diff options
Diffstat (limited to 'library')
96 files changed, 0 insertions, 15213 deletions
diff --git a/library/epub-meta/LICENSE b/library/epub-meta/LICENSE deleted file mode 100644 index 128bf1f66..000000000 --- a/library/epub-meta/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2012 Andreas Gohr <andi@splitbrain.org> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/library/epub-meta/README b/library/epub-meta/README deleted file mode 100644 index 21927dafe..000000000 --- a/library/epub-meta/README +++ /dev/null @@ -1,28 +0,0 @@ -====== PHP EPub Meta ====== - -This project aims to create a PHP class for reading and writing metadata -included in the EPub ebook format. - -It also includes a very basic web interface to edit book metadata. - -Please see the issue tracker for what's missing. - -Forks and pull requests welcome. - -===== About the EPub Manager Web Interface ===== - -The manager expects your ebooks in a single flat directory (no subfolders). The -location of that directory has to be configured at the top of the index.php file. - -All the epubs need to be read- and writable by the webserver. - -The manager also makes some assumption on how the files should be named. The -format is: "<Author file-as>-<Title>.epub". Commas will be replaced by __ and -spaces are replaced by _. - -Note that the manager will RENAME your files to that form when saving. - -Using the "Lookup Book Data" link will open a dialog that searches the book at -Google Books you can use the found data using the "fill in" and "replace" -buttons. The former will only fill empty fields, while the latter will replace -all data. Author filling is missing currently. diff --git a/library/epub-meta/assets/css/cleditor/images/buttons.gif b/library/epub-meta/assets/css/cleditor/images/buttons.gif Binary files differdeleted file mode 100644 index 2e464d0c8..000000000 --- a/library/epub-meta/assets/css/cleditor/images/buttons.gif +++ /dev/null diff --git a/library/epub-meta/assets/css/cleditor/images/toolbar.gif b/library/epub-meta/assets/css/cleditor/images/toolbar.gif Binary files differdeleted file mode 100644 index e6eb2da55..000000000 --- a/library/epub-meta/assets/css/cleditor/images/toolbar.gif +++ /dev/null diff --git a/library/epub-meta/assets/css/cleditor/jquery.cleditor.css b/library/epub-meta/assets/css/cleditor/jquery.cleditor.css deleted file mode 100644 index 6ac490bcf..000000000 --- a/library/epub-meta/assets/css/cleditor/jquery.cleditor.css +++ /dev/null @@ -1,24 +0,0 @@ -.cleditorMain {border:1px solid #999; padding:0 1px 1px; background-color:white}
-.cleditorMain iframe {border:none; margin:0; padding:0}
-.cleditorMain textarea {border:none; margin:0; padding:0; overflow-y:scroll; font:10pt Arial,Verdana; resize:none; outline:none /* webkit grip focus */}
-.cleditorToolbar {background: url('images/toolbar.gif') repeat}
-.cleditorGroup {float:left; height:26px}
-.cleditorButton {float:left; width:24px; height:24px; margin:1px 0 1px 0; background: url('images/buttons.gif')}
-.cleditorDisabled {opacity:0.3; filter:alpha(opacity=30)}
-.cleditorDivider {float:left; width:1px; height:23px; margin:1px 0 1px 0; background:#CCC}
-.cleditorPopup {border:solid 1px #999; background-color:white; position:absolute; font:10pt Arial,Verdana; cursor:default; z-index:10000}
-.cleditorList div {padding:2px 4px 2px 4px}
-.cleditorList p,
-.cleditorList h1,
-.cleditorList h2,
-.cleditorList h3,
-.cleditorList h4,
-.cleditorList h5,
-.cleditorList h6,
-.cleditorList font {padding:0; margin:0; background-color:Transparent}
-.cleditorColor {width:150px; padding:1px 0 0 1px}
-.cleditorColor div {float:left; width:14px; height:14px; margin:0 1px 1px 0}
-.cleditorPrompt {background-color:#F6F7F9; padding:4px; font-size:8.5pt}
-.cleditorPrompt input,
-.cleditorPrompt textarea {font:8.5pt Arial,Verdana;}
-.cleditorMsg {background-color:#FDFCEE; width:150px; padding:4px; font-size:8.5pt}
diff --git a/library/epub-meta/assets/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/library/epub-meta/assets/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png Binary files differdeleted file mode 100644 index 5b5dab2ab..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/library/epub-meta/assets/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png Binary files differdeleted file mode 100644 index ac8b229af..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png Binary files differdeleted file mode 100644 index ad3d6346e..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png Binary files differdeleted file mode 100644 index 42ccba269..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png Binary files differdeleted file mode 100644 index 5a46b47cb..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png Binary files differdeleted file mode 100644 index 86c2baa65..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png Binary files differdeleted file mode 100644 index 4443fdc1a..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/library/epub-meta/assets/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png Binary files differdeleted file mode 100644 index 7c9fa6c6e..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-icons_222222_256x240.png b/library/epub-meta/assets/css/smoothness/images/ui-icons_222222_256x240.png Binary files differdeleted file mode 100644 index b273ff111..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-icons_222222_256x240.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-icons_2e83ff_256x240.png b/library/epub-meta/assets/css/smoothness/images/ui-icons_2e83ff_256x240.png Binary files differdeleted file mode 100644 index 09d1cdc85..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-icons_2e83ff_256x240.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-icons_454545_256x240.png b/library/epub-meta/assets/css/smoothness/images/ui-icons_454545_256x240.png Binary files differdeleted file mode 100644 index 59bd45b90..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-icons_454545_256x240.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-icons_888888_256x240.png b/library/epub-meta/assets/css/smoothness/images/ui-icons_888888_256x240.png Binary files differdeleted file mode 100644 index 6d02426c1..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-icons_888888_256x240.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/images/ui-icons_cd0a0a_256x240.png b/library/epub-meta/assets/css/smoothness/images/ui-icons_cd0a0a_256x240.png Binary files differdeleted file mode 100644 index 2ab019b73..000000000 --- a/library/epub-meta/assets/css/smoothness/images/ui-icons_cd0a0a_256x240.png +++ /dev/null diff --git a/library/epub-meta/assets/css/smoothness/jquery-ui-1.8.18.custom.css b/library/epub-meta/assets/css/smoothness/jquery-ui-1.8.18.custom.css deleted file mode 100644 index 4cfb50a4a..000000000 --- a/library/epub-meta/assets/css/smoothness/jquery-ui-1.8.18.custom.css +++ /dev/null @@ -1,565 +0,0 @@ -/* - * jQuery UI CSS Framework 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } -.ui-helper-clearfix:after { clear: both; } -.ui-helper-clearfix { zoom: 1; } -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/* - * jQuery UI CSS Framework 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px - */ - - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } -.ui-widget-content a { color: #222222; } -.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } -.ui-widget-header a { color: #222222; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } -.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-off { background-position: -96px -144px; } -.ui-icon-radio-on { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } -.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } - -/* Overlays */ -.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* - * jQuery UI Resizable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizable#theming - */ -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* - * jQuery UI Selectable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectable#theming - */ -.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } -/* - * jQuery UI Accordion 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion#theming - */ -/* IE/Win - Fix animation bug - #4615 */ -.ui-accordion { width: 100%; } -.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } -.ui-accordion .ui-accordion-li-fix { display: inline; } -.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } -.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } -.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } -.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } -.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } -.ui-accordion .ui-accordion-content-active { display: block; } -/* - * jQuery UI Autocomplete 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu 1.8.18 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/* - * jQuery UI Button 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: hidden; *overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/* - * jQuery UI Dialog 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog#theming - */ -.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } -/* - * jQuery UI Slider 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider#theming - */ -.ui-slider { position: relative; text-align: left; } -.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } -.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } - -.ui-slider-horizontal { height: .8em; } -.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: .8em; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; }/* - * jQuery UI Tabs 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs#theming - */ -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } -.ui-tabs .ui-tabs-hide { display: none !important; } -/* - * jQuery UI Datepicker 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ -}/* - * jQuery UI Progressbar 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar#theming - */ -.ui-progressbar { height:2em; text-align: left; overflow: hidden; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file diff --git a/library/epub-meta/assets/css/style.css b/library/epub-meta/assets/css/style.css deleted file mode 100644 index 0e46dd1b0..000000000 --- a/library/epub-meta/assets/css/style.css +++ /dev/null @@ -1,180 +0,0 @@ -body, td, th, input, textarea { - font-family: "Arial", sans-serif; - color: #333; - font-size: 15px; -} - -a { - color: #4183C4; - text-decoration: none; -} - -a:hover, -a:active { - background-color: #efefef; -} - -#wrapper { - height: 95%; - width: 920px; - margin: auto; - padding: 0; - border: 1px solid #ccc; -} - -#booklist { - float: left; - width: 300px; - height: 100%; - overflow: auto; - list-style-type: none; - padding: 0; - margin: 0 25px 0 0; - font-size: 13px; -} - -#booklist li { - padding: 5px; -} - -#booklist li:hover { - background-color: #efefef; -} - -#booklist li span { - display: block; -} -#booklist li span.author { - padding-left: 5px; - font-size: 11px; -} - -#booklist li.active { - background-color: #4183C4; -} -#booklist li.active a, -#booklist li.active a:hover, -#booklist li.active a:active { - color: #efefef; - background-color: #4183C4; -} - - -#bookpanel { - float: left; - width: 590px; - height: 100%; - overflow: auto; -} - -.center { - text-align: center; -} - -table { - margin-bottom: 20px; -} - -table th, -table td { - vertical-align: top; - padding: 0 0 5px 0; -} - -table th { - text-align: right; - font-weight: bold; - padding: 3px; - padding-right: 20px; -} - -table td textarea, -table td input { - width: 450px; - border: none; - padding: 3px; - margin: 0; - border-bottom: solid 1px #dfdfdf; -} - -table td .cleditormain { - border: solid 1px #dfdfdf; -} - -table td textarea { - height: 250px; -} - -table td p { - margin: 0; - padding: 0; -} - -table td p input { - width: 200px; -} - -table td textarea:focus, -table td input:focus { - border: 1px solid #4183C4; -} - -table th img { - margin-top: 20px; -} - -a.addauthor { - margin-top: -20px; - float: right; -} - -div.license { - font-size: 11px; - margin-top: 300px; -} - -#bookapi-s { - float: left; -} - -#bookapi-q { - width: 600px; -} - -#bookapi { - font-size: 12px; -} - -#bookapi div.head { - margin-bottom: 10px; -} - -#bookapi div.result { - clear: both; - margin-bottom: 10px; - border-bottom: 1px solid #ccc; - min-height: 130px; -} - -#bookapi div.result div { - margin-left: 70px; -} - -#bookapi div.result div.buttons { - float: right; - text-align: right; -} - -#bookapi img { - margin-top: 30px; - width: 60px; - float: left; -} - -#bookapi h1.title { - font-size: 14px; -} - -#bookapi span.subjects { - font-style: italic; -} diff --git a/library/epub-meta/assets/js/jquery-1.7.1.min.js b/library/epub-meta/assets/js/jquery-1.7.1.min.js deleted file mode 100644 index 198b3ff07..000000000 --- a/library/epub-meta/assets/js/jquery-1.7.1.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! 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"?"<!doctype html>":"")+"<html><body>"),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;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=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<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\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(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)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(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?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<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",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></: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="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",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="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",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="<div style='width:4px;'></div>",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<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-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<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),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<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=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<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=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;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?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;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){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<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\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;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=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 b<c[3]-0},gt:function(a,b,c){return b>c[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<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=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;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",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 href='#'></a>",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="<p class='TEST'></p>";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="<div class='test e'></div><div class='test'></div>";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;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=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<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-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:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_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<div>","</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></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?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></$2>");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]==="<table>"&&!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<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=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\b[^<]*(?:(?!<\/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("<div>").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<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=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<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-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/library/epub-meta/assets/js/jquery-ui-1.8.18.custom.min.js b/library/epub-meta/assets/js/jquery-ui-1.8.18.custom.min.js deleted file mode 100644 index f00a62f13..000000000 --- a/library/epub-meta/assets/js/jquery-ui-1.8.18.custom.min.js +++ /dev/null @@ -1,356 +0,0 @@ -/*! - * jQuery UI 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI - */(function(a,b){function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;if(!b.href||!g||f.nodeName.toLowerCase()!=="map")return!1;h=a("img[usemap=#"+g+"]")[0];return!!h&&d(h)}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}a.ui=a.ui||{};a.ui.version||(a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)});return c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){if(c===b)return g["inner"+d].call(this);return this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){if(typeof b!="number")return g["outer"+d].call(this,b);return this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight,a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!!d&&!!a.element[0].parentNode)for(var e=0;e<d.length;e++)a.options[d[e][0]]&&d[e][1].apply(a.element,c)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(b,c){if(a(b).css("overflow")==="hidden")return!1;var d=c&&c==="left"?"scrollLeft":"scrollTop",e=!1;if(b[d]>0)return!0;b[d]=1,e=b[d]>0,b[d]=0;return e},isOverAxis:function(a,b,c){return a>b&&a<b+c},isOver:function(b,c,d,e,f,g){return a.ui.isOverAxis(b,d,f)&&a.ui.isOverAxis(c,e,g)}}))})(jQuery);/*! - * jQuery UI Widget 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Widget - */(function(a,b){if(a.cleanData){var c=a.cleanData;a.cleanData=function(b){for(var d=0,e;(e=b[d])!=null;d++)try{a(e).triggerHandler("remove")}catch(f){}c(b)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(b){}});return d.call(a(this),b,c)})}}a.widget=function(b,c,d){var e=b.split(".")[0],f;b=b.split(".")[1],f=e+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][f]=function(c){return!!a.data(c,b)},a[e]=a[e]||{},a[e][b]=function(a,b){arguments.length&&this._createWidget(a,b)};var g=new c;g.options=a.extend(!0,{},g.options),a[e][b].prototype=a.extend(!0,g,{namespace:e,widgetName:b,widgetEventPrefix:a[e][b].prototype.widgetEventPrefix||b,widgetBaseClass:f},d),a.widget.bridge(b,a[e][b])},a.widget.bridge=function(c,d){a.fn[c]=function(e){var f=typeof e=="string",g=Array.prototype.slice.call(arguments,1),h=this;e=!f&&g.length?a.extend.apply(null,[!0,e].concat(g)):e;if(f&&e.charAt(0)==="_")return h;f?this.each(function(){var d=a.data(this,c),f=d&&a.isFunction(d[e])?d[e].apply(d,g):d;if(f!==d&&f!==b){h=f;return!1}}):this.each(function(){var b=a.data(this,c);b?b.option(e||{})._init():a.data(this,c,new d(e,this))});return h}},a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)},a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(b,c){a.data(c,this.widgetName,this),this.element=a(c),this.options=a.extend(!0,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(c,d){var e=c;if(arguments.length===0)return a.extend({},this.options);if(typeof c=="string"){if(d===b)return this.options[c];e={},e[c]=d}this._setOptions(e);return this},_setOptions:function(b){var c=this;a.each(b,function(a,b){c._setOption(a,b)});return this},_setOption:function(a,b){this.options[a]=b,a==="disabled"&&this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",b);return this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(b,c,d){var e,f,g=this.options[b];d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);this.element.trigger(c,d);return!(a.isFunction(g)&&g.call(this.element[0],c,d)===!1||c.isDefaultPrevented())}}})(jQuery);/*! - * jQuery UI Mouse 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Mouse - * - * Depends: - * jquery.ui.widget.js - */(function(a,b){var c=!1;a(document).mouseup(function(a){c=!1}),a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var b=this;this.element.bind("mousedown."+this.widgetName,function(a){return b._mouseDown(a)}).bind("click."+this.widgetName,function(c){if(!0===a.data(c.target,b.widgetName+".preventClickEvent")){a.removeData(c.target,b.widgetName+".preventClickEvent"),c.stopImmediatePropagation();return!1}}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(b){if(!c){this._mouseStarted&&this._mouseUp(b),this._mouseDownEvent=b;var d=this,e=b.which==1,f=typeof this.options.cancel=="string"&&b.target.nodeName?a(b.target).closest(this.options.cancel).length:!1;if(!e||f||!this._mouseCapture(b))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)){this._mouseStarted=this._mouseStart(b)!==!1;if(!this._mouseStarted){b.preventDefault();return!0}}!0===a.data(b.target,this.widgetName+".preventClickEvent")&&a.removeData(b.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(a){return d._mouseMove(a)},this._mouseUpDelegate=function(a){return d._mouseUp(a)},a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),b.preventDefault(),c=!0;return!0}},_mouseMove:function(b){if(a.browser.msie&&!(document.documentMode>=9)&&!b.button)return this._mouseUp(b);if(this._mouseStarted){this._mouseDrag(b);return b.preventDefault()}this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b));return!this._mouseStarted},_mouseUp:function(b){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b));return!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);/* - * jQuery UI Position 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Position - */(function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1];return this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]!==e){var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0}},top:function(b,c){if(c.at[1]!==e){var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];if(!c||!c.ownerDocument)return null;if(b)return this.each(function(){a.offset.setOffset(this,b)});return h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&a.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery);/* - * jQuery UI Draggable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Draggables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */(function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!!this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy();return this}},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle"))return!1;this.handle=this._getHandle(b);if(!this.handle)return!1;c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")});return!0},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment();if(this._trigger("start",b)===!1){this._clear();return!1}this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.helper.addClass("ui-draggable-dragging"),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b);return!0},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1){this._mouseUp({});return!1}this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,b);return!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",b)!==!1&&d._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b);return a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)});return c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute");return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.left<h[0]&&(f=h[0]+this.offset.click.left),b.pageY-this.offset.click.top<h[1]&&(g=h[1]+this.offset.click.top),b.pageX-this.offset.click.left>h[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.top<h[1]||j-this.offset.click.top>h[3]?j-this.offset.click.top<h[1]?j+c.grid[1]:j-c.grid[1]:j:j;var k=c.grid[0]?this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0]:this.originalPageX;f=h?k-this.offset.click.left<h[0]||k-this.offset.click.left>h[2]?k-this.offset.click.left<h[0]?k+c.grid[0]:k-c.grid[0]:k:k}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(b,c,d){d=d||this._uiHash(),a.ui.plugin.call(this,b,[c,d]),b=="drag"&&(this.positionAbs=this._convertPositionTo("absolute"));return a.Widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(a){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),a.extend(a.ui.draggable,{version:"1.8.18"}),a.ui.plugin.add("draggable","connectToSortable",{start:function(b,c){var d=a(this).data("draggable"),e=d.options,f=a.extend({},c,{item:d.element});d.sortables=[],a(e.connectToSortable).each(function(){var c=a.data(this,"sortable");c&&!c.options.disabled&&(d.sortables.push({instance:c,shouldRevert:c.options.revert}),c.refreshPositions(),c._trigger("activate",b,f))})},stop:function(b,c){var d=a(this).data("draggable"),e=a.extend({},c,{item:d.element});a.each(d.sortables,function(){this.instance.isOver?(this.instance.isOver=0,d.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(b),this.instance.options.helper=this.instance.options._helper,d.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",b,e))})},drag:function(b,c){var d=a(this).data("draggable"),e=this,f=function(b){var c=this.offset.click.top,d=this.offset.click.left,e=this.positionAbs.top,f=this.positionAbs.left,g=b.height,h=b.width,i=b.top,j=b.left;return a.ui.isOver(e+c,f+d,i,j,g,h)};a.each(d.sortables,function(f){this.instance.positionAbs=d.positionAbs,this.instance.helperProportions=d.helperProportions,this.instance.offset.click=d.offset.click,this.instance._intersectsWith(this.instance.containerCache)?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=a(e).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return c.helper[0]},b.target=this.instance.currentItem[0],this.instance._mouseCapture(b,!0),this.instance._mouseStart(b,!0,!0),this.instance.offset.click.top=d.offset.click.top,this.instance.offset.click.left=d.offset.click.left,this.instance.offset.parent.left-=d.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=d.offset.parent.top-this.instance.offset.parent.top,d._trigger("toSortable",b),d.dropped=this.instance.element,d.currentItem=d.element,this.instance.fromOutside=d),this.instance.currentItem&&this.instance._mouseDrag(b)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",b,this.instance._uiHash(this.instance)),this.instance._mouseStop(b,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),d._trigger("fromSortable",b),d.dropped=!1)})}}),a.ui.plugin.add("draggable","cursor",{start:function(b,c){var d=a("body"),e=a(this).data("draggable").options;d.css("cursor")&&(e._cursor=d.css("cursor")),d.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;d._cursor&&a("body").css("cursor",d._cursor)}}),a.ui.plugin.add("draggable","opacity",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("opacity")&&(e._opacity=d.css("opacity")),d.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;d._opacity&&a(c.helper).css("opacity",d._opacity)}}),a.ui.plugin.add("draggable","scroll",{start:function(b,c){var d=a(this).data("draggable");d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"&&(d.overflowOffset=d.scrollParent.offset())},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=!1;if(d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"){if(!e.axis||e.axis!="x")d.overflowOffset.top+d.scrollParent[0].offsetHeight-b.pageY<e.scrollSensitivity?d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop+e.scrollSpeed:b.pageY-d.overflowOffset.top<e.scrollSensitivity&&(d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop-e.scrollSpeed);if(!e.axis||e.axis!="y")d.overflowOffset.left+d.scrollParent[0].offsetWidth-b.pageX<e.scrollSensitivity?d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft+e.scrollSpeed:b.pageX-d.overflowOffset.left<e.scrollSensitivity&&(d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft-e.scrollSpeed)}else{if(!e.axis||e.axis!="x")b.pageY-a(document).scrollTop()<e.scrollSensitivity?f=a(document).scrollTop(a(document).scrollTop()-e.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<e.scrollSensitivity&&(f=a(document).scrollTop(a(document).scrollTop()+e.scrollSpeed));if(!e.axis||e.axis!="y")b.pageX-a(document).scrollLeft()<e.scrollSensitivity?f=a(document).scrollLeft(a(document).scrollLeft()-e.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<e.scrollSensitivity&&(f=a(document).scrollLeft(a(document).scrollLeft()+e.scrollSpeed))}f!==!1&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(d,b)}}),a.ui.plugin.add("draggable","snap",{start:function(b,c){var d=a(this).data("draggable"),e=d.options;d.snapElements=[],a(e.snap.constructor!=String?e.snap.items||":data(draggable)":e.snap).each(function(){var b=a(this),c=b.offset();this!=d.element[0]&&d.snapElements.push({item:this,width:b.outerWidth(),height:b.outerHeight(),top:c.top,left:c.left})})},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=e.snapTolerance,g=c.offset.left,h=g+d.helperProportions.width,i=c.offset.top,j=i+d.helperProportions.height;for(var k=d.snapElements.length-1;k>=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f<g&&g<m+f&&n-f<i&&i<o+f||l-f<g&&g<m+f&&n-f<j&&j<o+f||l-f<h&&h<m+f&&n-f<i&&i<o+f||l-f<h&&h<m+f&&n-f<j&&j<o+f)){d.snapElements[k].snapping&&d.options.snap.release&&d.options.snap.release.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=!1;continue}if(e.snapMode!="inner"){var p=Math.abs(n-j)<=f,q=Math.abs(o-i)<=f,r=Math.abs(l-h)<=f,s=Math.abs(m-g)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n-d.helperProportions.height,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l-d.helperProportions.width}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m}).left-d.margins.left)}var t=p||q||r||s;if(e.snapMode!="outer"){var p=Math.abs(n-i)<=f,q=Math.abs(o-j)<=f,r=Math.abs(l-g)<=f,s=Math.abs(m-h)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o-d.helperProportions.height,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m-d.helperProportions.width}).left-d.margins.left)}!d.snapElements[k].snapping&&(p||q||r||s||t)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=p||q||r||s||t}}}),a.ui.plugin.add("draggable","stack",{start:function(b,c){var d=a(this).data("draggable").options,e=a.makeArray(a(d.stack)).sort(function(b,c){return(parseInt(a(b).css("zIndex"),10)||0)-(parseInt(a(c).css("zIndex"),10)||0)});if(!!e.length){var f=parseInt(e[0].style.zIndex)||0;a(e).each(function(a){this.style.zIndex=f+a}),this[0].style.zIndex=f+e.length}}}),a.ui.plugin.add("draggable","zIndex",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("zIndex")&&(e._zIndex=d.css("zIndex")),d.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;d._zIndex&&a(c.helper).css("zIndex",d._zIndex)}})})(jQuery);/* - * jQuery UI Droppable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Droppables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.mouse.js - * jquery.ui.draggable.js - */(function(a,b){a.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var b=this.options,c=b.accept;this.isover=0,this.isout=1,this.accept=a.isFunction(c)?c:function(a){return a.is(c)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},a.ui.ddmanager.droppables[b.scope]=a.ui.ddmanager.droppables[b.scope]||[],a.ui.ddmanager.droppables[b.scope].push(this),b.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++)b[c]==this&&b.splice(c,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(b,c){b=="accept"&&(this.accept=a.isFunction(c)?c:function(a){return a.is(c)}),a.Widget.prototype._setOption.apply(this,arguments)},_activate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),c&&this._trigger("activate",b,this.ui(c))},_deactivate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),c&&this._trigger("deactivate",b,this.ui(c))},_over:function(b){var c=a.ui.ddmanager.current;!!c&&(c.currentItem||c.element)[0]!=this.element[0]&&this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",b,this.ui(c)))},_out:function(b){var c=a.ui.ddmanager.current;!!c&&(c.currentItem||c.element)[0]!=this.element[0]&&this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",b,this.ui(c)))},_drop:function(b,c){var d=c||a.ui.ddmanager.current;if(!d||(d.currentItem||d.element)[0]==this.element[0])return!1;var e=!1;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var b=a.data(this,"droppable");if(b.options.greedy&&!b.options.disabled&&b.options.scope==d.options.scope&&b.accept.call(b.element[0],d.currentItem||d.element)&&a.ui.intersect(d,a.extend(b,{offset:b.element.offset()}),b.options.tolerance)){e=!0;return!1}});if(e)return!1;if(this.accept.call(this.element[0],d.currentItem||d.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",b,this.ui(d));return this.element}return!1},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}}),a.extend(a.ui.droppable,{version:"1.8.18"}),a.ui.intersect=function(b,c,d){if(!c.offset)return!1;var e=(b.positionAbs||b.position.absolute).left,f=e+b.helperProportions.width,g=(b.positionAbs||b.position.absolute).top,h=g+b.helperProportions.height,i=c.offset.left,j=i+c.proportions.width,k=c.offset.top,l=k+c.proportions.height;switch(d){case"fit":return i<=e&&f<=j&&k<=g&&h<=l;case"intersect":return i<e+b.helperProportions.width/2&&f-b.helperProportions.width/2<j&&k<g+b.helperProportions.height/2&&h-b.helperProportions.height/2<l;case"pointer":var m=(b.positionAbs||b.position.absolute).left+(b.clickOffset||b.offset.click).left,n=(b.positionAbs||b.position.absolute).top+(b.clickOffset||b.offset.click).top,o=a.ui.isOver(n,m,k,i,c.proportions.height,c.proportions.width);return o;case"touch":return(g>=k&&g<=l||h>=k&&h<=l||g<k&&h>l)&&(e>=i&&e<=j||f>=i&&f<=j||e<i&&f>j);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();droppablesLoop:for(var g=0;g<d.length;g++){if(d[g].options.disabled||b&&!d[g].accept.call(d[g].element[0],b.currentItem||b.element))continue;for(var h=0;h<f.length;h++)if(f[h]==d[g].element[0]){d[g].proportions.height=0;continue droppablesLoop}d[g].visible=d[g].element.css("display")!="none";if(!d[g].visible)continue;e=="mousedown"&&d[g]._activate.call(d[g],c),d[g].offset=d[g].element.offset(),d[g].proportions={width:d[g].element[0].offsetWidth,height:d[g].element[0].offsetHeight}}},drop:function(b,c){var d=!1;a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){!this.options||(!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)&&(d=this._drop.call(this,c)||d),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],b.currentItem||b.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,c)))});return d},dragStart:function(b,c){b.element.parents(":not(body,html)").bind("scroll.droppable",function(){b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)})},drag:function(b,c){b.options.refreshPositions&&a.ui.ddmanager.prepareOffsets(b,c),a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var d=a.ui.intersect(b,this,this.options.tolerance),e=!d&&this.isover==1?"isout":d&&this.isover==0?"isover":null;if(!e)return;var f;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");g.length&&(f=a.data(g[0],"droppable"),f.greedyChild=e=="isover"?1:0)}f&&e=="isover"&&(f.isover=0,f.isout=1,f._out.call(f,c)),this[e]=1,this[e=="isout"?"isover":"isout"]=0,this[e=="isover"?"_over":"_out"].call(this,c),f&&e=="isout"&&(f.isout=0,f.isover=1,f._over.call(f,c))}})},dragStop:function(b,c){b.element.parents(":not(body,html)").unbind("scroll.droppable"),b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)}}})(jQuery);/* - * jQuery UI Resizable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */(function(a,b){a.widget("ui.resizable",a.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var b=this,c=this.options;this.element.addClass("ui-resizable"),a.extend(this,{_aspectRatio:!!c.aspectRatio,aspectRatio:c.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:c.helper||c.ghost||c.animate?c.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(a('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e<d.length;e++){var f=a.trim(d[e]),g="ui-resizable-"+f,h=a('<div class="ui-resizable-handle '+g+'"></div>');/sw|se|ne|nw/.test(f)&&h.css({zIndex:++c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){c.disabled||(a(this).removeClass("ui-resizable-autohide"),b._handles.show())},function(){c.disabled||b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement);return this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b);return!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui());return!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),e<h.maxWidth&&(h.maxWidth=e),g<h.maxHeight&&(h.maxHeight=g);this._vBoundaries=h},_updateCache:function(a){var b=this.options;this.offset=this.helper.offset(),d(a.left)&&(this.position.left=a.left),d(a.top)&&(this.position.top=a.top),d(a.height)&&(this.size.height=a.height),d(a.width)&&(this.size.width=a.width)},_updateRatio:function(a,b){var c=this.options,e=this.position,f=this.size,g=this.axis;d(a.height)?a.width=a.height*this.aspectRatio:d(a.width)&&(a.height=a.width/this.aspectRatio),g=="sw"&&(a.left=e.left+(f.width-a.width),a.top=null),g=="nw"&&(a.top=e.top+(f.height-a.height),a.left=e.left+(f.width-a.width));return a},_respectSize:function(a,b){var c=this.helper,e=this._vBoundaries,f=this._aspectRatio||b.shiftKey,g=this.axis,h=d(a.width)&&e.maxWidth&&e.maxWidth<a.width,i=d(a.height)&&e.maxHeight&&e.maxHeight<a.height,j=d(a.width)&&e.minWidth&&e.minWidth>a.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null);return a},_proportionallyResize:function(){var b=this.options;if(!!this._proportionallyResizeElements.length){var c=this.helper||this.element;for(var d=0;d<this._proportionallyResizeElements.length;d++){var e=this._proportionallyResizeElements[d];if(!this.borderDif){var f=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],g=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];this.borderDif=a.map(f,function(a,b){var c=parseInt(a,10)||0,d=parseInt(g[b],10)||0;return c+d})}if(a.browser.msie&&(!!a(c).is(":hidden")||!!a(c).parents(":hidden").length))continue;e.css({height:c.height()-this.borderDif[0]-this.borderDif[2]||0,width:c.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var b=this.element,c=this.options;this.elementOffset=b.offset();if(this._helper){this.helper=this.helper||a('<div style="overflow:hidden;"></div>');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.18"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,d){a(b).each(function(){var b=a(this),e=a(this).data("resizable-alsoresize"),f={},g=d&&d.length?d:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(e[b]||0)+(h[b]||0);c&&c>=0&&(f[b]=c||null)}),b.css(f)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!!i){e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/e.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*e.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);/* - * jQuery UI Selectable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy();return this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(!this.options.disabled){var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element});return!1}})}},_mouseDrag:function(b){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!!i&&i.element!=c.element[0]){var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.right<e||i.top>h||i.bottom<f):d.tolerance=="fit"&&(j=i.left>e&&i.right<g&&i.top>f&&i.bottom<h),j?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,c._trigger("selecting",b,{selecting:i.element}))):(i.selecting&&((b.metaKey||b.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),c._trigger("unselecting",b,{unselecting:i.element}))),i.selected&&!b.metaKey&&!b.ctrlKey&&!i.startselected&&(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,c._trigger("unselecting",b,{unselecting:i.element})))}});return!1}},_mouseStop:function(b){var c=this;this.dragged=!1;var d=this.options;a(".ui-unselecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-unselecting"),d.unselecting=!1,d.startselected=!1,c._trigger("unselected",b,{unselected:d.element})}),a(".ui-selecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected"),d.selecting=!1,d.selected=!0,d.startselected=!0,c._trigger("selected",b,{selected:d.element})}),this._trigger("stop",b),this.helper.remove();return!1}}),a.extend(a.ui.selectable,{version:"1.8.18"})})(jQuery);/* - * jQuery UI Sortable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Sortables - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */(function(a,b){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},destroy:function(){a.Widget.prototype.destroy.call(this),this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f){e=a(this);return!1}});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}this.currentItem=e,this._removeCurrentsFromItems();return!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b);return!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY<c.scrollSensitivity?this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop+c.scrollSpeed:b.pageY-this.overflowOffset.top<c.scrollSensitivity&&(this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop-c.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-b.pageX<c.scrollSensitivity?this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft+c.scrollSpeed:b.pageX-this.overflowOffset.left<c.scrollSensitivity&&(this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft-c.scrollSpeed)):(b.pageY-a(document).scrollTop()<c.scrollSensitivity?d=a(document).scrollTop(a(document).scrollTop()-c.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<c.scrollSensitivity&&(d=a(document).scrollTop(a(document).scrollTop()+c.scrollSpeed)),b.pageX-a(document).scrollLeft()<c.scrollSensitivity?d=a(document).scrollLeft(a(document).scrollLeft()-c.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<c.scrollSensitivity&&(d=a(document).scrollLeft(a(document).scrollLeft()+c.scrollSpeed))),d!==!1&&a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var e=this.items.length-1;e>=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs;return!1},_mouseStop:function(b,c){if(!!b){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem));return this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"=");return d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")});return d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+j<i&&b+k>f&&b+k<g;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?l:f<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<g&&h<d+this.helperProportions.height/2&&e-this.helperProportions.height/2<i},_intersectsWithPointer:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left,b.width),e=c&&d,f=this._getDragVerticalDirection(),g=this._getDragHorizontalDirection();if(!e)return!1;return this.floating?g&&g=="right"||f=="down"?2:1:f&&(f=="down"?2:1)},_intersectsWithSides:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top+b.height/2,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left+b.width/2,b.width),e=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();return this.floating&&f?f=="right"&&d||f=="left"&&!d:e&&(e=="down"&&c||e=="up"&&!c)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a),this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(b){this.items=[],this.containers=[this];var c=this.items,d=this,e=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]],f=this._connectWith();if(f&&this.ready)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i<m;i++){var n=a(l[i]);n.data(this.widgetName+"-item",k),c.push({item:n,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var c=this.items.length-1;c>=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];e||(b.style.visibility="hidden");return b},update:function(a,b){if(!e||!!d.forcePlaceholderSize)b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!!c)if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.items[i][this.containers[d].floating?"left":"top"];Math.abs(j-h)<f&&(f=Math.abs(j-h),g=this.items[i])}if(!g&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[d],g?this._rearrange(b,g,null,!0):this._rearrange(b,null,this.containers[d].element,!0),this._trigger("change",b,this._uiHash()),this.containers[d]._trigger("change",b,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]),d[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(d[0].style.width==""||c.forceHelperSize)&&d.width(this.currentItem.width()),(d[0].style.height==""||c.forceHelperSize)&&d.height(this.currentItem.height());return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)){var c=a(b.containment)[0],d=a(b.containment).offset(),e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var f=b.pageX,g=b.pageY;if(this.originalPosition){this.containment&&(b.pageX-this.offset.click.left<this.containment[0]&&(f=this.containment[0]+this.offset.click.left),b.pageY-this.offset.click.top<this.containment[1]&&(g=this.containment[1]+this.offset.click.top),b.pageX-this.offset.click.left>this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.top<this.containment[1]||h-this.offset.click.top>this.containment[3]?h-this.offset.click.top<this.containment[1]?h+c.grid[1]:h-c.grid[1]:h:h;var i=this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0];f=this.containment?i-this.offset.click.left<this.containment[0]||i-this.offset.click.left>this.containment[2]?i-this.offset.click.left<this.containment[0]?i+c.grid[0]:i-c.grid[0]:i:i}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_rearrange:function(a,b,c,d){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var e=this,f=this.counter;window.setTimeout(function(){f==e.counter&&e.refreshPositions(!d)},0)},_clear:function(b,c){this.reverting=!1;var d=[],e=this;!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var f in this._storedCSS)if(this._storedCSS[f]=="auto"||this._storedCSS[f]=="static")this._storedCSS[f]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&d.push(function(a){this._trigger("receive",a,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c&&d.push(function(a){this._trigger("update",a,this._uiHash())});if(!a.ui.contains(this.element[0],this.currentItem[0])){c||d.push(function(a){this._trigger("remove",a,this._uiHash())});for(var f=this.containers.length-1;f>=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}return!1}c||this._trigger("beforeStop",b,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!c){for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}this.fromOutside=!1;return!0},_trigger:function(){a.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(b){var c=b||this;return{helper:c.helper,placeholder:c.placeholder||a([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:b?b.element:null}}}),a.extend(a.ui.sortable,{version:"1.8.18"})})(jQuery);/* - * jQuery UI Accordion 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */(function(a,b){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:!0,clearStyle:!1,collapsible:!1,event:"click",fillSpace:!1,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("<span></span>").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");(b.autoHeight||b.fillHeight)&&c.css("height","");return a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(!(this.options.disabled||b.altKey||b.ctrlKey)){var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}if(f){a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus();return!1}return!0}},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];this._clickHandler({target:b},b);return this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(!d.disabled){if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return}},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!!g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;this.running||(this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data))}}),a.extend(a.ui.accordion,{version:"1.8.18",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size())b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);else{if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})}},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})})(jQuery);/* - * jQuery UI Autocomplete 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.position.js - */(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!b.options.disabled&&!b.element.propAttr("readOnly")){d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._move("previous",c),c.preventDefault();break;case e.DOWN:b._move("next",c),c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){b.options.disabled||(b.selectedItem=null,b.previous=b.element.val())}).bind("blur.autocomplete",function(a){b.options.disabled||(clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150))}),this._initSource(),this.response=function(){return b._response.apply(b,arguments)},this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,d,e;a.isArray(this.options.source)?(d=this.options.source,this.source=function(b,c){c(a.ui.autocomplete.filter(d,b.term))}):typeof this.options.source=="string"?(e=this.options.source,this.source=function(d,f){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:e,data:d,dataType:"json",context:{autocompleteRequest:++c},success:function(a,b){this.autocompleteRequest===c&&f(a)},error:function(){this.autocompleteRequest===c&&f([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==!1)return this._search(a)},_search:function(a){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.source({term:a},this.response)},_response:function(a){!this.options.disabled&&a&&a.length?(a=this._normalize(a),this._suggest(a),this._trigger("open")):this.close(),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.deactivate(),this._trigger("close",a))},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(b){if(b.length&&b[0].label&&b[0].value)return b;return a.map(b,function(b){if(typeof b=="string")return{label:b,value:b};return a.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(b){var c=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(c,b),this.menu.deactivate(),this.menu.refresh(),c.show(),this._resizeMenu(),c.position(a.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(b,c){var d=this;a.each(c,function(a,c){d._renderItem(b,c)})},_renderItem:function(b,c){return a("<li></li>").data("item.autocomplete",c).append(a("<a></a>").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible"))this.search(null,b);else{if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)}},widget:function(){return this.menu.element}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){!a(c.target).closest(".ui-menu-item a").length||(c.preventDefault(),b.select(c))}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){!this.active||(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active)this.activate(c,this.element.children(b));else{var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))}},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10}),result.length||(result=this.element.children(".ui-menu-item:first")),this.activate(b,result)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})}(jQuery);/* - * jQuery UI Button 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */(function(a,b){var c,d,e,f,g="ui-button ui-widget ui-state-default ui-corner-all",h="ui-state-hover ui-state-active ",i="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",j=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},k=function(b){var c=b.name,d=b.form,e=a([]);c&&(d?e=a(d).find("[name='"+c+"']"):e=a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form}));return e};a.widget("ui.button",{options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",j),typeof this.options.disabled!="boolean"?this.options.disabled=!!this.element.propAttr("disabled"):this.element.propAttr("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var b=this,h=this.options,i=this.type==="checkbox"||this.type==="radio",l="ui-state-hover"+(i?"":" ui-state-active"),m="ui-state-focus";h.label===null&&(h.label=this.buttonElement.html()),this.buttonElement.addClass(g).attr("role","button").bind("mouseenter.button",function(){h.disabled||(a(this).addClass("ui-state-hover"),this===c&&a(this).addClass("ui-state-active"))}).bind("mouseleave.button",function(){h.disabled||a(this).removeClass(l)}).bind("click.button",function(a){h.disabled&&(a.preventDefault(),a.stopImmediatePropagation())}),this.element.bind("focus.button",function(){b.buttonElement.addClass(m)}).bind("blur.button",function(){b.buttonElement.removeClass(m)}),i&&(this.element.bind("change.button",function(){f||b.refresh()}),this.buttonElement.bind("mousedown.button",function(a){h.disabled||(f=!1,d=a.pageX,e=a.pageY)}).bind("mouseup.button",function(a){!h.disabled&&(d!==a.pageX||e!==a.pageY)&&(f=!0)})),this.type==="checkbox"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).toggleClass("ui-state-active"),b.buttonElement.attr("aria-pressed",b.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).addClass("ui-state-active"),b.buttonElement.attr("aria-pressed","true");var c=b.element[0];k(c).not(c).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown.button",function(){if(h.disabled)return!1;a(this).addClass("ui-state-active"),c=this,a(document).one("mouseup",function(){c=null})}).bind("mouseup.button",function(){if(h.disabled)return!1;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(b){if(h.disabled)return!1;(b.keyCode==a.ui.keyCode.SPACE||b.keyCode==a.ui.keyCode.ENTER)&&a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(b){b.keyCode===a.ui.keyCode.SPACE&&a(this).click()})),this._setOption("disabled",h.disabled),this._resetButton()},_determineButtonType:function(){this.element.is(":checkbox")?this.type="checkbox":this.element.is(":radio")?this.type="radio":this.element.is("input")?this.type="input":this.type="button";if(this.type==="checkbox"||this.type==="radio"){var a=this.element.parents().filter(":last"),b="label[for='"+this.element.attr("id")+"']";this.buttonElement=a.find(b),this.buttonElement.length||(a=a.length?a.siblings():this.element.siblings(),this.buttonElement=a.filter(b),this.buttonElement.length||(this.buttonElement=a.find(b))),this.element.addClass("ui-helper-hidden-accessible");var c=this.element.is(":checked");c&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.attr("aria-pressed",c)}else this.buttonElement=this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(g+" "+h+" "+i).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title"),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);b==="disabled"?c?this.element.propAttr("disabled",!0):this.element.propAttr("disabled",!1):this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b),this.type==="radio"?k(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass(i),c=a("<span></span>",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>"),d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>"),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})})(jQuery);/* - * jQuery UI Dialog 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - * jquery.ui.button.js - * jquery.ui.draggable.js - * jquery.ui.mouse.js - * jquery.ui.position.js - * jquery.ui.resizable.js - */(function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},f=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||" ",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("<div></div>")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){b.close(a);return!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("<span></span>")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("<span></span>").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1!==c._trigger("beforeClose",b)){c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d);return c}},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;if(e.modal&&!b||!e.stack&&!e.modal)return d._trigger("focus",c);e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c);return d},open:function(){if(!this._isOpen){var b=this,c=b.options,d=b.uiDialog;b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode===a.ui.keyCode.TAB){var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey){d.focus(1);return!1}if(b.target===d[0]&&b.shiftKey){e.focus(1);return!1}}}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open");return b}},_createButtons:function(b){var c=this,d=!1,e=a("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=a("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('<button type="button"></button>').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(g);a.each(d,function(a,b){a!=="click"&&(a in f?e[a](b):e.attr(a,b))}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||" "))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.18",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");b||(this.uuid+=1,b=this.uuid);return"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()<a.ui.dialog.overlay.maxZ)return!1})},1),a(document).bind("keydown.dialog-overlay",function(c){b.options.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}),a(window).bind("resize.dialog-overlay",a.ui.dialog.overlay.resize));var c=(this.oldInstances.pop()||a("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&c.bgiframe(),this.instances.push(c);return c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;if(a.browser.msie&&a.browser.version<7){b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return b<c?a(window).height()+"px":b+"px"}return a(document).height()+"px"},width:function(){var b,c;if(a.browser.msie){b=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),c=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return b<c?a(window).width()+"px":b+"px"}return a(document).width()+"px"},resize:function(){var b=a([]);a.each(a.ui.dialog.overlay.instances,function(){b=b.add(this)}),b.css({width:0,height:0}).css({width:a.ui.dialog.overlay.width(),height:a.ui.dialog.overlay.height()})}}),a.extend(a.ui.dialog.overlay.prototype,{destroy:function(){a.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);/* - * jQuery UI Slider 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider - * - * Depends: - * jquery.ui.core.js - * jquery.ui.mouse.js - * jquery.ui.widget.js - */(function(a,b){var c=5;a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var b=this,d=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",g=d.values&&d.values.length||1,h=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(d.disabled?" ui-slider-disabled ui-disabled":"")),this.range=a([]),d.range&&(d.range===!0&&(d.values||(d.values=[this._valueMin(),this._valueMin()]),d.values.length&&d.values.length!==2&&(d.values=[d.values[0],d.values[0]])),this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;i<g;i+=1)h.push(f);this.handles=e.add(a(h.join("")).appendTo(b.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(a){a.preventDefault()}).hover(function(){d.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){d.disabled?a(this).blur():(a(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),a(this).addClass("ui-state-focus"))}).blur(function(){a(this).removeClass("ui-state-focus")}),this.handles.each(function(b){a(this).data("index.ui-slider-handle",b)}),this.handles.keydown(function(d){var e=a(this).data("index.ui-slider-handle"),f,g,h,i;if(!b.options.disabled){switch(d.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:d.preventDefault();if(!b._keySliding){b._keySliding=!0,a(this).addClass("ui-state-active"),f=b._start(d,e);if(f===!1)return}}i=b.options.step,b.options.values&&b.options.values.length?g=h=b.values(e):g=h=b.value();switch(d.keyCode){case a.ui.keyCode.HOME:h=b._valueMin();break;case a.ui.keyCode.END:h=b._valueMax();break;case a.ui.keyCode.PAGE_UP:h=b._trimAlignValue(g+(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.PAGE_DOWN:h=b._trimAlignValue(g-(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(g===b._valueMax())return;h=b._trimAlignValue(g+i);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(g===b._valueMin())return;h=b._trimAlignValue(g-i)}b._slide(d,e,h)}}).keyup(function(c){var d=a(this).data("index.ui-slider-handle");b._keySliding&&(b._keySliding=!1,b._stop(c,d),b._change(c,d),a(this).removeClass("ui-state-active"))}),this._refreshValue(),this._animateOff=!1},destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"),this._mouseDestroy();return this},_mouseCapture:function(b){var c=this.options,d,e,f,g,h,i,j,k,l;if(c.disabled)return!1;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),d={x:b.pageX,y:b.pageY},e=this._normValueFromMouse(d),f=this._valueMax()-this._valueMin()+1,h=this,this.handles.each(function(b){var c=Math.abs(e-h.values(b));f>c&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i);if(j===!1)return!1;this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0;return!0},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);this._slide(a,this._handleIndex,c);return!1},_mouseStop:function(a){this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1;return!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e;return this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values());return this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c<d)&&(c=d),c!==this.values(b)&&(e=this.values(),e[b]=c,f=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e}),d=this.values(b?0:1),f!==!1&&this.values(b,c,!0))):c!==this.value()&&(f=this._trigger("slide",a,{handle:this.handles[b],value:c}),f!==!1&&this.value(c))},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("change",a,c)}},value:function(a){if(arguments.length)this.options.value=this._trimAlignValue(a),this._refreshValue(),this._change(null,0);else return this._value()},values:function(b,c){var d,e,f;if(arguments.length>1)this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);else{if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f<d.length;f+=1)d[f]=this._trimAlignValue(e[f]),this._change(null,f);this._refreshValue()}},_setOption:function(b,c){var d,e=0;a.isArray(this.options.values)&&(e=this.options.values.length),a.Widget.prototype._setOption.apply(this,arguments);switch(b){case"disabled":c?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.propAttr("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.propAttr("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(d=0;d<e;d+=1)this._change(null,d);this._animateOff=!1}},_value:function(){var a=this.options.value;a=this._trimAlignValue(a);return a},_values:function(a){var b,c,d;if(arguments.length){b=this.options.values[a],b=this._trimAlignValue(b);return b}c=this.options.values.slice();for(d=0;d<c.length;d+=1)c[d]=this._trimAlignValue(c[d]);return c},_trimAlignValue:function(a){if(a<=this._valueMin())return this._valueMin();if(a>=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;Math.abs(c)*2>=b&&(d+=c>0?b:-b);return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.18"})})(jQuery);/* - * jQuery UI Tabs 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */(function(a,b){function f(){return++d}function e(){return++c}var c=0,d=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading…</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash){e.selected=a;return!1}}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1){this.blur();return!1}e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected")){e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur();return!1}if(!f.length){e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur();return!1}}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$="+a+"]")));return a},destroy:function(){var b=this.options;this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie);return this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e]));return this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1<this.anchors.length?1:-1)),c.disabled=a.map(a.grep(c.disabled,function(a,c){return a!=b}),function(a,c){return a>=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0]));return this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a])));return this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;this.anchors.eq(a).trigger(this.options.event+".tabs");return this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup();return this},url:function(a,b){this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.18"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a<c.anchors.length?a:0)},a),b&&b.stopPropagation()}),f=c._unrotate||(c._unrotate=b?function(a){t=d.selected,e()}:function(a){a.clientX&&c.rotate(null)});a?(this.element.bind("tabsshow",e),this.anchors.bind(d.event+".tabs",f),e()):(clearTimeout(c.rotation),this.element.unbind("tabsshow",e),this.anchors.unbind(d.event+".tabs",f),delete this._rotate,delete this._unrotate);return this}})})(jQuery);/* - * jQuery UI Datepicker 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker - * - * Depends: - * jquery.ui.core.js - */(function($,undefined){function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);!c.length||c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);!$.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])&&!!d.length&&(d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover"))})}function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}$.extend($.ui,{datepicker:{version:"1.8.18"}});var PROP_NAME="datepicker",dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){extendRemove(this._defaults,a||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);c.hasClass(this.markerClassName)||(this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a))},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$('<span class="'+this._appendClass+'">'+c+"</span>"),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('<button type="button"></button>').addClass(this._triggerClass).html(g==""?f:$("<img/>").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){$.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._datepickerShowing&&$.datepicker._lastInput!=a[0]?($.datepicker._hideDatepicker(),$.datepicker._showDatepicker(a[0])):$.datepicker._showDatepicker(a[0]);return!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;d<a.length;d++)a[d].length>b&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);c.hasClass(this.markerClassName)||(c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block"))},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+g+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f);return this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return!0;return!1},_getInst:function(a){try{return $.data(a,PROP_NAME)}catch(b){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(a,b,c){var d=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?$.extend({},$.datepicker._defaults):d?b=="all"?$.extend({},d.settings):this._get(d,b):null;var e=b||{};typeof b=="string"&&(e={},e[b]=c);if(d){this._curInst==d&&this._hideDatepicker();var f=this._getDateDatepicker(a,!0),g=this._getMinMaxDate(d,"min"),h=this._getMinMaxDate(d,"max");extendRemove(d.settings,e),g!==null&&e.dateFormat!==undefined&&e.minDate===undefined&&(d.settings.minDate=this._formatDate(d,g)),h!==null&&e.dateFormat!==undefined&&e.maxDate===undefined&&(d.settings.maxDate=this._formatDate(d,h)),this._attachments($(a),d),this._autoSize(d),this._setDate(d,f),this._updateAlternate(d),this._updateDatepicker(d)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){var b=this._getInst(a);b&&this._updateDatepicker(b)},_setDateDatepicker:function(a,b){var c=this._getInst(a);c&&(this._setDate(c,b),this._updateDatepicker(c),this._updateAlternate(c))},_getDateDatepicker:function(a,b){var c=this._getInst(a);c&&!c.inline&&this._setDateFromField(c,b);return c?this._getDate(c):null},_doKeyDown:function(a){var b=$.datepicker._getInst(a.target),c=!0,d=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=!0;if($.datepicker._datepickerShowing)switch(a.keyCode){case 9:$.datepicker._hideDatepicker(),c=!1;break;case 13:var e=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",b.dpDiv);e[0]&&$.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,e[0]);var f=$.datepicker._get(b,"onSelect");if(f){var g=$.datepicker._formatDate(b);f.apply(b.input?b.input[0]:null,[g,b])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 35:(a.ctrlKey||a.metaKey)&&$.datepicker._clearDate(a.target),c=a.ctrlKey||a.metaKey;break;case 36:(a.ctrlKey||a.metaKey)&&$.datepicker._gotoToday(a.target),c=a.ctrlKey||a.metaKey;break;case 37:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?1:-1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 38:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,-7,"D"),c=a.ctrlKey||a.metaKey;break;case 39:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?-1:1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 40:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,7,"D"),c=a.ctrlKey||a.metaKey;break;default:c=!1}else a.keyCode==36&&a.ctrlKey?$.datepicker._showDatepicker(this):c=!1;c&&(a.preventDefault(),a.stopPropagation())},_doKeyPress:function(a){var b=$.datepicker._getInst(a.target);if($.datepicker._get(b,"constrainInput")){var c=$.datepicker._possibleChars($.datepicker._get(b,"dateFormat")),d=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||d<" "||!c||c.indexOf(d)>-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(a){$.datepicker.log(a)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if(!$.datepicker._isDisabledDatepicker(a)&&$.datepicker._lastInput!=a){var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){e|=$(this).css("position")=="fixed";return!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+$(document).scrollLeft(),i=document.documentElement.clientHeight+$(document).scrollTop();b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0);return b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=$.data(a,PROP_NAME))&&this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=this,f=function(){$.datepicker._tidyDialog(b),e._curInst=null};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,f):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,f),c||f(),this._datepickerShowing=!1;var g=this._get(b,"onClose");g&&g.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!!$.datepicker._curInst){var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.closest("."+$.datepicker._triggerClass).length&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);this._isDisabledDatepicker(d[0])||(this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e))},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if(!$(d).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(e[0])){var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();b.setMonth(0),b.setDate(1);return Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1<a.length&&a.charAt(s+1)==b;c&&s++;return c},o=function(a){var c=n(a),d=a=="@"?14:a=="!"?20:a=="y"&&c?4:a=="o"?3:2,e=new RegExp("^\\d{1,"+d+"}"),f=b.substring(r).match(e);if(!f)throw"Missing number at position "+r;r+=f[0].length;return parseInt(f[0],10)},p=function(a,c,d){var e=$.map(n(a)?d:c,function(a,b){return[[b,a]]}).sort(function(a,b){return-(a[1].length-b[1].length)}),f=-1;$.each(e,function(a,c){var d=c[1];if(b.substr(r,d.length).toLowerCase()==d.toLowerCase()){f=c[0],r+=d.length;return!1}});if(f!=-1)return f+1;throw"Unknown name at position "+r},q=function(){if(b.charAt(r)!=a.charAt(s))throw"Unexpected literal at position "+r;r++},r=0;for(var s=0;s<a.length;s++)if(m)a.charAt(s)=="'"&&!n("'")?m=!1:q();else switch(a.charAt(s)){case"d":k=o("d");break;case"D":p("D",e,f);break;case"o":l=o("o");break;case"m":j=o("m");break;case"M":j=p("M",g,h);break;case"y":i=o("y");break;case"@":var t=new Date(o("@"));i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"!":var t=new Date((o("!")-this._ticksTo1970)/1e4);i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"'":n("'")?q():m=!0;break;default:q()}if(r<b.length)throw"Extra/unparsed characters found in date: "+b.substring(r);i==-1?i=(new Date).getFullYear():i<100&&(i+=(new Date).getFullYear()-(new Date).getFullYear()%100+(i<=d?0:-100));if(l>-1){j=1,k=l;for(;;){var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+1<a.length&&a.charAt(m+1)==b;c&&m++;return c},i=function(a,b,c){var d=""+b;if(h(a))while(d.length<c)d="0"+d;return d},j=function(a,b,c,d){return h(a)?d[b]:c[b]},k="",l=!1;if(b)for(var m=0;m<a.length;m++)if(l)a.charAt(m)=="'"&&!h("'")?l=!1:k+=a.charAt(m);else switch(a.charAt(m)){case"d":k+=i("d",b.getDate(),2);break;case"D":k+=j("D",b.getDay(),d,e);break;case"o":k+=i("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":k+=i("m",b.getMonth()+1,2);break;case"M":k+=j("M",b.getMonth(),f,g);break;case"y":k+=h("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case"@":k+=b.getTime();break;case"!":k+=b.getTime()*1e4+this._ticksTo1970;break;case"'":h("'")?k+="'":l=!0;break;default:k+=a.charAt(m)}return k},_possibleChars:function(a){var b="",c=!1,d=function(b){var c=e+1<a.length&&a.charAt(e+1)==b;c&&e++;return c};for(var e=0;e<a.length;e++)if(c)a.charAt(e)=="'"&&!d("'")?c=!1:b+=a.charAt(e);else switch(a.charAt(e)){case"d":case"m":case"y":case"@":b+="0123456789";break;case"D":case"M":return null;case"'":d("'")?b+="'":c=!0;break;default:b+=a.charAt(e)}return b},_get:function(a,b){return a.settings[b]!==undefined?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),d=a.lastVal=a.input?a.input.val():null,e,f;e=f=this._getDefaultDate(a);var g=this._getFormatConfig(a);try{e=this.parseDate(c,d,g)||f}catch(h){this.log(h),d=b?"":d}a.selectedDay=e.getDate(),a.drawMonth=a.selectedMonth=e.getMonth(),a.drawYear=a.selectedYear=e.getFullYear(),a.currentDay=d?e.getDate():0,a.currentMonth=d?e.getMonth():0,a.currentYear=d?e.getFullYear():0,this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var d=function(a){var b=new Date;b.setDate(b.getDate()+a);return b},e=function(b){try{return $.datepicker.parseDate($.datepicker._get(a,"dateFormat"),b,$.datepicker._getFormatConfig(a))}catch(c){}var d=(b.toLowerCase().match(/^c/)?$.datepicker._getDate(a):null)||new Date,e=d.getFullYear(),f=d.getMonth(),g=d.getDate(),h=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,i=h.exec(b);while(i){switch(i[2]||"d"){case"d":case"D":g+=parseInt(i[1],10);break;case"w":case"W":g+=parseInt(i[1],10)*7;break;case"m":case"M":f+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f));break;case"y":case"Y":e+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f))}i=h.exec(b)}return new Date(e,f,g)},f=b==null||b===""?c:typeof b=="string"?e(b):typeof b=="number"?isNaN(b)?c:d(b):new Date(b.getTime());f=f&&f.toString()=="Invalid Date"?c:f,f&&(f.setHours(0),f.setMinutes(0),f.setSeconds(0),f.setMilliseconds(0));return this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&p<l?l:p;while(this._daylightSavingAdjust(new Date(o,n,1))>p)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', -"+i+", 'M');\""+' title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>":e?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', +"+i+", 'M');\""+' title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":e?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+dpuuid+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>",x=d?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?w:"")+(this._isInRange(a,v)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._gotoToday('#"+a.id+"');\""+">"+u+"</button>":"")+(c?"":w)+"</div>":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L<g[0];L++){var M="";this.maxRows=4;for(var N=0;N<g[1];N++){var O=this._daylightSavingAdjust(new Date(o,n,a.selectedDay)),P=" ui-corner-all",Q="";if(j){Q+='<div class="ui-datepicker-group';if(g[1]>1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+P+'">'+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var R=z?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="<th"+((S+y+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+A[T]+'">'+C[T]+"</span></th>"}Q+=R+"</tr></thead><tbody>";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z<X;Z++){Q+="<tr>";var _=z?'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(Y)+"</td>":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Y<l||m&&Y>m;_+='<td class="'+((S+y+6)%7>=5?" ui-datepicker-week-end":"")+(bb?" ui-datepicker-other-month":"")+(Y.getTime()==O.getTime()&&n==a.selectedMonth&&a._keyEvent||J.getTime()==Y.getTime()&&J.getTime()==O.getTime()?" "+this._dayOverClass:"")+(bc?" "+this._unselectableClass+" ui-state-disabled":"")+(bb&&!G?"":" "+ba[1]+(Y.getTime()==k.getTime()?" "+this._currentClass:"")+(Y.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!bb||G)&&ba[2]?' title="'+ba[2]+'"':"")+(bc?"":' onclick="DP_jQuery_'+dpuuid+".datepicker._selectDay('#"+a.id+"',"+Y.getMonth()+","+Y.getFullYear()+', this);return false;"')+">"+(bb&&!G?" ":bc?'<span class="ui-state-default">'+Y.getDate()+"</span>":'<a class="ui-state-default'+(Y.getTime()==b.getTime()?" ui-state-highlight":"")+(Y.getTime()==k.getTime()?" ui-state-active":"")+(bb?" ui-priority-secondary":"")+'" href="#">'+Y.getDate()+"</a>")+"</td>",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+"</tr>"}n++,n>11&&(n=0,o++),Q+="</tbody></table>"+(j?"</div>"+(g[0]>0&&N==g[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),M+=Q}K+=M}K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""), -a._keyEvent=!1;return K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this._get(a,"showMonthAfterYear"),l='<div class="ui-datepicker-title">',m="";if(f||!i)m+='<span class="ui-datepicker-month">'+g[b]+"</span>";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" "+">";for(var p=0;p<12;p++)(!n||p>=d.getMonth())&&(!o||p<=e.getMonth())&&(m+='<option value="'+p+'"'+(p==b?' selected="selected"':"")+">"+h[p]+"</option>");m+="</select>"}k||(l+=m+(f||!i||!j?" ":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+='<span class="ui-datepicker-year">'+c+"</span>";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" "+">";for(;t<=u;t++)a.yearshtml+='<option value="'+t+'"'+(t==c?' selected="selected"':"")+">"+t+"</option>";a.yearshtml+="</select>",l+=a.yearshtml,a.yearshtml=null}}l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?" ":"")+m),l+="</div>";return l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&b<c?c:b;e=d&&e>d?d:e;return e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth()));return this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));return this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)})},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.18",window["DP_jQuery_"+dpuuid]=$})(jQuery);/* - * jQuery UI Progressbar 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */(function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===b)return this._value();this._setOption("value",a);return this},_setOption:function(b,c){b==="value"&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;typeof a!="number"&&(a=0);return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.18"})})(jQuery);/* - * jQuery UI Effects 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/ - */jQuery.effects||function(a,b){function l(b){if(!b||typeof b=="number"||a.fx.speeds[b])return!0;if(typeof b=="string"&&!a.effects[b])return!0;return!1}function k(b,c,d,e){typeof b=="object"&&(e=c,d=null,c=b,b=c.effect),a.isFunction(c)&&(e=c,d=null,c={});if(typeof c=="number"||a.fx.speeds[c])e=d,d=c,c={};a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:typeof d=="number"?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete;return[b,c,d,e]}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function i(b){var c,d;for(c in b)d=b[c],(d==null||a.isFunction(d)||c in g||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function h(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]]){var e=a.length;while(e--)c=a[e],typeof a[c]=="string"&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c])}else for(c in a)typeof a[c]=="string"&&(b[c]=a[c]);return b}function d(b,d){var e;do{e=a.curCSS(b,d);if(e!=""&&e!="transparent"||a.nodeName(b,"body"))break;d="backgroundColor"}while(b=b.parentNode);return c(e)}function c(b){var c;if(b&&b.constructor==Array&&b.length==3)return b;if(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))return[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)];if(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))return[parseFloat(c[1])*2.55,parseFloat(c[2])*2.55,parseFloat(c[3])*2.55];if(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)];if(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)];if(c=/rgba\(0, 0, 0, 0\)/.exec(b))return e.transparent;return e[a.trim(b).toLowerCase()]}a.effects={},a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,e){a.fx.step[e]=function(a){a.colorInit||(a.start=d(a.elem,e),a.end=c(a.end),a.colorInit=!0),a.elem.style[e]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var e={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(b,c,d,e){a.isFunction(d)&&(e=d,d=null);return this.queue(function(){var g=a(this),k=g.attr("style")||" ",l=i(h.call(this)),m,n=g.attr("class");a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),m=i(h.call(this)),g.attr("class",n),g.animate(j(l,m),{queue:!1,duration:c,easing:d,complete:function(){a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),typeof g.attr("style")=="object"?(g.attr("style").cssText="",g.attr("style").cssText=k):g.attr("style",k),e&&e.apply(this,arguments),a.dequeue(this)}})})},a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(c,d,e,f,g){return typeof d=="boolean"||d===b?e?a.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):a.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this,[{add:c,remove:b},d,e,f])}}),a.extend(a.effects,{version:"1.8.18",save:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.data("ec.storage."+b[c],a[0].style[b[c]])},restore:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.css(b[c],a.data("ec.storage."+b[c]))},setMode:function(a,b){b=="toggle"&&(b=a.is(":hidden")?"show":"hide");return b},getBaseline:function(a,b){var c,d;switch(a[0]){case"top":c=0;break;case"middle":c=.5;break;case"bottom":c=1;break;default:c=a[0]/b.height}switch(a[1]){case"left":d=0;break;case"center":d=.5;break;case"right":d=1;break;default:d=a[1]/b.width}return{x:d,y:c}},createWrapper:function(b){if(b.parent().is(".ui-effects-wrapper"))return b.parent();var c={width:b.outerWidth(!0),height:b.outerHeight(!0),"float":b.css("float")},d=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(),d=b.parent(),b.css("position")=="static"?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"}));return d.css(c).show()},removeWrapper:function(b){var c,d=document.activeElement;if(b.parent().is(".ui-effects-wrapper")){c=b.parent().replaceWith(b),(b[0]===d||a.contains(b[0],d))&&a(d).focus();return c}return b},setTransition:function(b,c,d,e){e=e||{},a.each(c,function(a,c){unit=b.cssUnit(c),unit[0]>0&&(e[c]=unit[0]*d+unit[1])});return e}}),a.fn.extend({effect:function(b,c,d,e){var f=k.apply(this,arguments),g={options:f[1],duration:f[2],callback:f[3]},h=g.options.mode,i=a.effects[b];if(a.fx.off||!i)return h?this[h](g.duration,g.callback):this.each(function(){g.callback&&g.callback.call(this)});return i.call(this,g)},_show:a.fn.show,show:function(a){if(l(a))return this._show.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="show";return this.effect.apply(this,b)},_hide:a.fn.hide,hide:function(a){if(l(a))return this._hide.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="hide";return this.effect.apply(this,b)},__toggle:a.fn.toggle,toggle:function(b){if(l(b)||typeof b=="boolean"||a.isFunction(b))return this.__toggle.apply(this,arguments);var c=k.apply(this,arguments);c[1].mode="toggle";return this.effect.apply(this,c)},cssUnit:function(b){var c=this.css(b),d=[];a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])});return d}}),a.easing.jswing=a.easing.swing,a.extend(a.easing,{def:"easeOutQuad",swing:function(b,c,d,e,f){return a.easing[a.easing.def](b,c,d,e,f)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b+c;return-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b+c;return d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b+c;return-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b*b+c;return d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return b==0?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){if(b==0)return c;if(b==e)return c+d;if((b/=e/2)<1)return d/2*Math.pow(2,10*(b-1))+c;return d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){if((b/=e/2)<1)return-d/2*(Math.sqrt(1-b*b)-1)+c;return d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin((b*e-f)*2*Math.PI/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e/2)==2)return c+d;g||(g=e*.3*1.5);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);if(b<1)return-0.5*h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)+c;return h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)*.5+d+c},easeInBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);return e*(c/=f)*c*((g+1)*c-g)+d},easeOutBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);return e*((c=c/f-1)*c*((g+1)*c+g)+1)+d},easeInOutBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);if((c/=f/2)<1)return e/2*c*c*(((g*=1.525)+1)*c-g)+d;return e/2*((c-=2)*c*(((g*=1.525)+1)*c+g)+2)+d},easeInBounce:function(b,c,d,e,f){return e-a.easing.easeOutBounce(b,f-c,0,e,f)+d},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*7.5625*b*b+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(b,c,d,e,f){if(c<f/2)return a.easing.easeInBounce(b,c*2,0,e,f)*.5+d;return a.easing.easeOutBounce(b,c*2-f,0,e,f)*.5+e*.5+d}})}(jQuery);/* - * jQuery UI Effects Blind 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Blind - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.blind=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=f=="vertical"?"height":"width",i=f=="vertical"?g.height():g.width();e=="show"&&g.css(h,0);var j={};j[h]=e=="show"?i:0,g.animate(j,b.duration,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);/* - * jQuery UI Effects Bounce 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Bounce - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.bounce=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"up",g=b.options.distance||20,h=b.options.times||5,i=b.duration||250;/show|hide/.test(e)&&d.push("opacity"),a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",g=b.options.distance||(j=="top"?c.outerHeight({margin:!0})/3:c.outerWidth({margin:!0})/3);e=="show"&&c.css("opacity",0).css(j,k=="pos"?-g:g),e=="hide"&&(g=g/(h*2)),e!="hide"&&h--;if(e=="show"){var l={opacity:1};l[j]=(k=="pos"?"+=":"-=")+g,c.animate(l,i/2,b.options.easing),g=g/2,h--}for(var m=0;m<h;m++){var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing),g=e=="hide"?g*2:g/2}if(e=="hide"){var l={opacity:0};l[j]=(k=="pos"?"-=":"+=")+g,c.animate(l,i/2,b.options.easing,function(){c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}else{var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}c.queue("fx",function(){c.dequeue()}),c.dequeue()})}})(jQuery);/* - * jQuery UI Effects Clip 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Clip - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.clip=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","height","width"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=c[0].tagName=="IMG"?g:c,i={size:f=="vertical"?"height":"width",position:f=="vertical"?"top":"left"},j=f=="vertical"?h.height():h.width();e=="show"&&(h.css(i.size,0),h.css(i.position,j/2));var k={};k[i.size]=e=="show"?j:0,k[i.position]=e=="show"?0:j/2,h.animate(k,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()}})})}})(jQuery);/* - * jQuery UI Effects Drop 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Drop - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.drop=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","opacity"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0})/2:c.outerWidth({margin:!0})/2);e=="show"&&c.css("opacity",0).css(g,h=="pos"?-i:i);var j={opacity:e=="show"?1:0};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/* - * jQuery UI Effects Explode 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Explode - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.explode=function(b){return this.queue(function(){var c=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3,d=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?a(this).is(":visible")?"hide":"show":b.options.mode;var e=a(this).show().css("visibility","hidden"),f=e.offset();f.top-=parseInt(e.css("marginTop"),10)||0,f.left-=parseInt(e.css("marginLeft"),10)||0;var g=e.outerWidth(!0),h=e.outerHeight(!0);for(var i=0;i<c;i++)for(var j=0;j<d;j++)e.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(g/d),top:-i*(h/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/d,height:h/c,left:f.left+j*(g/d)+(b.options.mode=="show"?(j-Math.floor(d/2))*(g/d):0),top:f.top+i*(h/c)+(b.options.mode=="show"?(i-Math.floor(c/2))*(h/c):0),opacity:b.options.mode=="show"?0:1}).animate({left:f.left+j*(g/d)+(b.options.mode=="show"?0:(j-Math.floor(d/2))*(g/d)),top:f.top+i*(h/c)+(b.options.mode=="show"?0:(i-Math.floor(c/2))*(h/c)),opacity:b.options.mode=="show"?1:0},b.duration||500);setTimeout(function(){b.options.mode=="show"?e.css({visibility:"visible"}):e.css({visibility:"visible"}).hide(),b.callback&&b.callback.apply(e[0]),e.dequeue(),a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);/* - * jQuery UI Effects Fade 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fade - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.fade=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/* - * jQuery UI Effects Fold 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fold - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.fold=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.size||15,g=!!b.options.horizFirst,h=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(c,d),c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),j=e=="show"!=g,k=j?["width","height"]:["height","width"],l=j?[i.width(),i.height()]:[i.height(),i.width()],m=/([0-9]+)%/.exec(f);m&&(f=parseInt(m[1],10)/100*l[e=="hide"?0:1]),e=="show"&&i.css(g?{height:0,width:f}:{height:f,width:0});var n={},p={};n[k[0]]=e=="show"?l[0]:f,p[k[1]]=e=="show"?l[1]:0,i.animate(n,h,b.options.easing).animate(p,h,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);/* - * jQuery UI Effects Highlight 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Highlight - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.highlight=function(b){return this.queue(function(){var c=a(this),d=["backgroundImage","backgroundColor","opacity"],e=a.effects.setMode(c,b.options.mode||"show"),f={backgroundColor:c.css("backgroundColor")};e=="hide"&&(f.opacity=0),a.effects.save(c,d),c.show().css({backgroundImage:"none",backgroundColor:b.options.color||"#ffff99"}).animate(f,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),e=="show"&&!a.support.opacity&&this.style.removeAttribute("filter"),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/* - * jQuery UI Effects Pulsate 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Pulsate - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.pulsate=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"show");times=(b.options.times||5)*2-1,duration=b.duration?b.duration/2:a.fx.speeds._default/2,isVisible=c.is(":visible"),animateTo=0,isVisible||(c.css("opacity",0).show(),animateTo=1),(d=="hide"&&isVisible||d=="show"&&!isVisible)&×--;for(var e=0;e<times;e++)c.animate({opacity:animateTo},duration,b.options.easing),animateTo=(animateTo+1)%2;c.animate({opacity:animateTo},duration,b.options.easing,function(){animateTo==0&&c.hide(),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}).dequeue()})}})(jQuery);/* - * jQuery UI Effects Scale 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Scale - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.puff=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide"),e=parseInt(b.options.percent,10)||150,f=e/100,g={height:c.height(),width:c.width()};a.extend(b.options,{fade:!0,mode:d,percent:d=="hide"?e:100,from:d=="hide"?g:{height:g.height*f,width:g.width*f}}),c.effect("scale",b.options,b.duration,b.callback),c.dequeue()})},a.effects.scale=function(b){return this.queue(function(){var c=a(this),d=a.extend(!0,{},b.options),e=a.effects.setMode(c,b.options.mode||"effect"),f=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:e=="hide"?0:100),g=b.options.direction||"both",h=b.options.origin;e!="effect"&&(d.origin=h||["middle","center"],d.restore=!0);var i={height:c.height(),width:c.width()};c.from=b.options.from||(e=="show"?{height:0,width:0}:i);var j={y:g!="horizontal"?f/100:1,x:g!="vertical"?f/100:1};c.to={height:i.height*j.y,width:i.width*j.x},b.options.fade&&(e=="show"&&(c.from.opacity=0,c.to.opacity=1),e=="hide"&&(c.from.opacity=1,c.to.opacity=0)),d.from=c.from,d.to=c.to,d.mode=e,c.effect("size",d,b.duration,b.callback),c.dequeue()})},a.effects.size=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","width","height","overflow","opacity"],e=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],g=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],i=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],j=a.effects.setMode(c,b.options.mode||"effect"),k=b.options.restore||!1,l=b.options.scale||"both",m=b.options.origin,n={height:c.height(),width:c.width()};c.from=b.options.from||n,c.to=b.options.to||n;if(m){var p=a.effects.getBaseline(m,n);c.from.top=(n.height-c.from.height)*p.y,c.from.left=(n.width-c.from.width)*p.x,c.to.top=(n.height-c.to.height)*p.y,c.to.left=(n.width-c.to.width)*p.x}var q={from:{y:c.from.height/n.height,x:c.from.width/n.width},to:{y:c.to.height/n.height,x:c.to.width/n.width}};if(l=="box"||l=="both")q.from.y!=q.to.y&&(d=d.concat(h),c.from=a.effects.setTransition(c,h,q.from.y,c.from),c.to=a.effects.setTransition(c,h,q.to.y,c.to)),q.from.x!=q.to.x&&(d=d.concat(i),c.from=a.effects.setTransition(c,i,q.from.x,c.from),c.to=a.effects.setTransition(c,i,q.to.x,c.to));(l=="content"||l=="both")&&q.from.y!=q.to.y&&(d=d.concat(g),c.from=a.effects.setTransition(c,g,q.from.y,c.from),c.to=a.effects.setTransition(c,g,q.to.y,c.to)),a.effects.save(c,k?d:e),c.show(),a.effects.createWrapper(c),c.css("overflow","hidden").css(c.from);if(l=="content"||l=="both")h=h.concat(["marginTop","marginBottom"]).concat(g),i=i.concat(["marginLeft","marginRight"]),f=d.concat(h).concat(i),c.find("*[width]").each(function(){child=a(this),k&&a.effects.save(child,f);var c={height:child.height(),width:child.width()};child.from={height:c.height*q.from.y,width:c.width*q.from.x},child.to={height:c.height*q.to.y,width:c.width*q.to.x},q.from.y!=q.to.y&&(child.from=a.effects.setTransition(child,h,q.from.y,child.from),child.to=a.effects.setTransition(child,h,q.to.y,child.to)),q.from.x!=q.to.x&&(child.from=a.effects.setTransition(child,i,q.from.x,child.from),child.to=a.effects.setTransition(child,i,q.to.x,child.to)),child.css(child.from),child.animate(child.to,b.duration,b.options.easing,function(){k&&a.effects.restore(child,f)})});c.animate(c.to,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity),j=="hide"&&c.hide(),a.effects.restore(c,k?d:e),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/* - * jQuery UI Effects Shake 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Shake - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.shake=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"left",g=b.options.distance||20,h=b.options.times||3,i=b.duration||b.options.duration||140;a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",l={},m={},n={};l[j]=(k=="pos"?"-=":"+=")+g,m[j]=(k=="pos"?"+=":"-=")+g*2,n[j]=(k=="pos"?"-=":"+=")+g*2,c.animate(l,i,b.options.easing);for(var p=1;p<h;p++)c.animate(m,i,b.options.easing).animate(n,i,b.options.easing);c.animate(m,i,b.options.easing).animate(l,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}),c.dequeue()})}})(jQuery);/* - * jQuery UI Effects Slide 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Slide - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.slide=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"show"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c).css({overflow:"hidden"});var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0}):c.outerWidth({margin:!0}));e=="show"&&c.css(g,h=="pos"?isNaN(i)?"-"+i:-i:i);var j={};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}})(jQuery);/* - * jQuery UI Effects Transfer 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Transfer - * - * Depends: - * jquery.effects.core.js - */(function(a,b){a.effects.transfer=function(b){return this.queue(function(){var c=a(this),d=a(b.options.to),e=d.offset(),f={top:e.top,left:e.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}})(jQuery);
\ No newline at end of file diff --git a/library/epub-meta/assets/js/jquery.cleditor.min.js b/library/epub-meta/assets/js/jquery.cleditor.min.js deleted file mode 100644 index 5afec0488..000000000 --- a/library/epub-meta/assets/js/jquery.cleditor.min.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - CLEditor WYSIWYG HTML Editor v1.3.0 - http://premiumsoftware.net/cleditor - requires jQuery v1.4.2 or later - - Copyright 2010, Chris Landowski, Premium Software, LLC - Dual licensed under the MIT or GPL Version 2 licenses. -*/ -(function(e){function aa(a){var b=this,c=a.target,d=e.data(c,x),h=s[d],f=h.popupName,i=p[f];if(!(b.disabled||e(c).attr(n)==n)){var g={editor:b,button:c,buttonName:d,popup:i,popupName:f,command:h.command,useCSS:b.options.useCSS};if(h.buttonClick&&h.buttonClick(a,g)===false)return false;if(d=="source"){if(t(b)){delete b.range;b.$area.hide();b.$frame.show();c.title=h.title}else{b.$frame.hide();b.$area.show();c.title="Show Rich Text"}setTimeout(function(){u(b)},100)}else if(!t(b))if(f){var j=e(i);if(f== -"url"){if(d=="link"&&M(b)===""){z(b,"A selection is required when inserting a link.",c);return false}j.children(":button").unbind(q).bind(q,function(){var k=j.find(":text"),o=e.trim(k.val());o!==""&&v(b,g.command,o,null,g.button);k.val("http://");r();w(b)})}else f=="pastetext"&&j.children(":button").unbind(q).bind(q,function(){var k=j.find("textarea"),o=k.val().replace(/\n/g,"<br />");o!==""&&v(b,g.command,o,null,g.button);k.val("");r();w(b)});if(c!==e.data(i,A)){N(b,i,c);return false}return}else if(d== -"print")b.$frame[0].contentWindow.print();else if(!v(b,g.command,g.value,g.useCSS,c))return false;w(b)}}function O(a){a=e(a.target).closest("div");a.css(H,a.data(x)?"#FFF":"#FFC")}function P(a){e(a.target).closest("div").css(H,"transparent")}function ba(a){var b=a.data.popup,c=a.target;if(!(b===p.msg||e(b).hasClass(B))){var d=e.data(b,A),h=e.data(d,x),f=s[h],i=f.command,g,j=this.options.useCSS;if(h=="font")g=c.style.fontFamily.replace(/"/g,"");else if(h=="size"){if(c.tagName=="DIV")c=c.children[0]; -g=c.innerHTML}else if(h=="style")g="<"+c.tagName+">";else if(h=="color")g=Q(c.style.backgroundColor);else if(h=="highlight"){g=Q(c.style.backgroundColor);if(l)i="backcolor";else j=true}b={editor:this,button:d,buttonName:h,popup:b,popupName:f.popupName,command:i,value:g,useCSS:j};if(!(f.popupClick&&f.popupClick(a,b)===false)){if(b.command&&!v(this,b.command,b.value,b.useCSS,d))return false;r();w(this)}}}function C(a){for(var b=1,c=0,d=0;d<a.length;++d){b=(b+a.charCodeAt(d))%65521;c=(c+b)%65521}return c<< -16|b}function R(a,b,c,d,h){if(p[a])return p[a];var f=e(m).hide().addClass(ca).appendTo("body");if(d)f.html(d);else if(a=="color"){b=b.colors.split(" ");b.length<10&&f.width("auto");e.each(b,function(i,g){e(m).appendTo(f).css(H,"#"+g)});c=da}else if(a=="font")e.each(b.fonts.split(","),function(i,g){e(m).appendTo(f).css("fontFamily",g).html(g)});else if(a=="size")e.each(b.sizes.split(","),function(i,g){e(m).appendTo(f).html("<font size="+g+">"+g+"</font>")});else if(a=="style")e.each(b.styles,function(i, -g){e(m).appendTo(f).html(g[1]+g[0]+g[1].replace("<","</"))});else if(a=="url"){f.html('Enter URL:<br><input type=text value="http://" size=35><br><input type=button value="Submit">');c=B}else if(a=="pastetext"){f.html("Paste your content here and click submit.<br /><textarea cols=40 rows=3></textarea><br /><input type=button value=Submit>");c=B}if(!c&&!d)c=S;f.addClass(c);l&&f.attr(I,"on").find("div,font,p,h1,h2,h3,h4,h5,h6").attr(I,"on");if(f.hasClass(S)||h===true)f.children().hover(O,P);p[a]=f[0]; -return f[0]}function T(a,b){if(b){a.$area.attr(n,n);a.disabled=true}else{a.$area.removeAttr(n);delete a.disabled}try{if(l)a.doc.body.contentEditable=!b;else a.doc.designMode=!b?"on":"off"}catch(c){}u(a)}function v(a,b,c,d,h){D(a);if(!l){if(d===undefined||d===null)d=a.options.useCSS;a.doc.execCommand("styleWithCSS",0,d.toString())}d=true;var f;if(l&&b.toLowerCase()=="inserthtml")y(a).pasteHTML(c);else{try{d=a.doc.execCommand(b,0,c||null)}catch(i){f=i.description;d=false}d||("cutcopypaste".indexOf(b)> --1?z(a,"For security reasons, your browser does not support the "+b+" command. Try using the keyboard shortcut or context menu instead.",h):z(a,f?f:"Error executing the "+b+" command.",h))}u(a);return d}function w(a){setTimeout(function(){t(a)?a.$area.focus():a.$frame[0].contentWindow.focus();u(a)},0)}function y(a){if(l)return J(a).createRange();return J(a).getRangeAt(0)}function J(a){if(l)return a.doc.selection;return a.$frame[0].contentWindow.getSelection()}function Q(a){var b=/rgba?\((\d+), (\d+), (\d+)/.exec(a), -c=a.split("");if(b)for(a=(b[1]<<16|b[2]<<8|b[3]).toString(16);a.length<6;)a="0"+a;return"#"+(a.length==6?a:c[1]+c[1]+c[2]+c[2]+c[3]+c[3])}function r(){e.each(p,function(a,b){e(b).hide().unbind(q).removeData(A)})}function U(){var a=e("link[href$='jquery.cleditor.css']").attr("href");return a.substr(0,a.length-19)+"images/"}function K(a){var b=a.$main,c=a.options;a.$frame&&a.$frame.remove();var d=a.$frame=e('<iframe frameborder="0" src="javascript:true;">').hide().appendTo(b),h=d[0].contentWindow,f= -a.doc=h.document,i=e(f);f.open();f.write(c.docType+"<html>"+(c.docCSSFile===""?"":'<head><link rel="stylesheet" type="text/css" href="'+c.docCSSFile+'" /></head>')+'<body style="'+c.bodyStyle+'"></body></html>');f.close();l&&i.click(function(){w(a)});E(a);if(l){i.bind("beforedeactivate beforeactivate selectionchange keypress",function(g){if(g.type=="beforedeactivate")a.inactive=true;else if(g.type=="beforeactivate"){!a.inactive&&a.range&&a.range.length>1&&a.range.shift();delete a.inactive}else if(!a.inactive){if(!a.range)a.range= -[];for(a.range.unshift(y(a));a.range.length>2;)a.range.pop()}});d.focus(function(){D(a)})}(e.browser.mozilla?i:e(h)).blur(function(){V(a,true)});i.click(r).bind("keyup mouseup",function(){u(a)});L?a.$area.show():d.show();e(function(){var g=a.$toolbar,j=g.children("div:last"),k=b.width();j=j.offset().top+j.outerHeight()-g.offset().top+1;g.height(j);j=(/%/.test(""+c.height)?b.height():parseInt(c.height))-j;d.width(k).height(j);a.$area.width(k).height(ea?j-2:j);T(a,a.disabled);u(a)})}function u(a){if(!L&& -e.browser.webkit&&!a.focused){a.$frame[0].contentWindow.focus();window.focus();a.focused=true}var b=a.doc;if(l)b=y(a);var c=t(a);e.each(a.$toolbar.find("."+W),function(d,h){var f=e(h),i=e.cleditor.buttons[e.data(h,x)],g=i.command,j=true;if(a.disabled)j=false;else if(i.getEnabled){j=i.getEnabled({editor:a,button:h,buttonName:i.name,popup:p[i.popupName],popupName:i.popupName,command:i.command,useCSS:a.options.useCSS});if(j===undefined)j=true}else if((c||L)&&i.name!="source"||l&&(g=="undo"||g=="redo"))j= -false;else if(g&&g!="print"){if(l&&g=="hilitecolor")g="backcolor";if(!l||g!="inserthtml")try{j=b.queryCommandEnabled(g)}catch(k){j=false}}if(j){f.removeClass(X);f.removeAttr(n)}else{f.addClass(X);f.attr(n,n)}})}function D(a){l&&a.range&&a.range[0].select()}function M(a){D(a);if(l)return y(a).text;return J(a).toString()}function z(a,b,c){var d=R("msg",a.options,fa);d.innerHTML=b;N(a,d,c)}function N(a,b,c){var d,h,f=e(b);if(c){var i=e(c);d=i.offset();h=--d.left;d=d.top+i.height()}else{i=a.$toolbar; -d=i.offset();h=Math.floor((i.width()-f.width())/2)+d.left;d=d.top+i.height()-2}r();f.css({left:h,top:d}).show();if(c){e.data(b,A,c);f.bind(q,{popup:b},e.proxy(ba,a))}setTimeout(function(){f.find(":text,textarea").eq(0).focus().select()},100)}function t(a){return a.$area.is(":visible")}function E(a,b){var c=a.$area.val(),d=a.options,h=d.updateFrame,f=e(a.doc.body);if(h){var i=C(c);if(b&&a.areaChecksum==i)return;a.areaChecksum=i}c=h?h(c):c;c=c.replace(/<(?=\/?script)/ig,"<");if(d.updateTextArea)a.frameChecksum= -C(c);if(c!=f.html()){f.html(c);e(a).triggerHandler(F)}}function V(a,b){var c=e(a.doc.body).html(),d=a.options,h=d.updateTextArea,f=a.$area;if(h){var i=C(c);if(b&&a.frameChecksum==i)return;a.frameChecksum=i}c=h?h(c):c;if(d.updateFrame)a.areaChecksum=C(c);if(c!=f.val()){f.val(c);e(a).triggerHandler(F)}}e.cleditor={defaultOptions:{width:500,height:250,controls:"bold italic underline strikethrough subscript superscript | font size style | color highlight removeformat | bullets numbering | outdent indent | alignleft center alignright justify | undo redo | rule image link unlink | cut copy paste pastetext | print source", -colors:"FFF FCC FC9 FF9 FFC 9F9 9FF CFF CCF FCF CCC F66 F96 FF6 FF3 6F9 3FF 6FF 99F F9F BBB F00 F90 FC6 FF0 3F3 6CC 3CF 66C C6C 999 C00 F60 FC3 FC0 3C0 0CC 36F 63F C3C 666 900 C60 C93 990 090 399 33F 60C 939 333 600 930 963 660 060 366 009 339 636 000 300 630 633 330 030 033 006 309 303",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond,Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",sizes:"1,2,3,4,5,6,7",styles:[["Paragraph","<p>"],["Header 1","<h1>"],["Header 2","<h2>"], -["Header 3","<h3>"],["Header 4","<h4>"],["Header 5","<h5>"],["Header 6","<h6>"]],useCSS:false,docType:'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',docCSSFile:"",bodyStyle:"margin:4px; font:10pt Arial,Verdana; cursor:text"},buttons:{init:"bold,,|italic,,|underline,,|strikethrough,,|subscript,,|superscript,,|font,,fontname,|size,Font Size,fontsize,|style,,formatblock,|color,Font Color,forecolor,|highlight,Text Highlight Color,hilitecolor,color|removeformat,Remove Formatting,|bullets,,insertunorderedlist|numbering,,insertorderedlist|outdent,,|indent,,|alignleft,Align Text Left,justifyleft|center,,justifycenter|alignright,Align Text Right,justifyright|justify,,justifyfull|undo,,|redo,,|rule,Insert Horizontal Rule,inserthorizontalrule|image,Insert Image,insertimage,url|link,Insert Hyperlink,createlink,url|unlink,Remove Hyperlink,|cut,,|copy,,|paste,,|pastetext,Paste as Text,inserthtml,|print,,|source,Show Source"}, -imagesPath:function(){return U()}};e.fn.cleditor=function(a){var b=e([]);this.each(function(c,d){if(d.tagName=="TEXTAREA"){var h=e.data(d,Y);h||(h=new cleditor(d,a));b=b.add(h)}});return b};var H="backgroundColor",A="button",x="buttonName",F="change",Y="cleditor",q="click",n="disabled",m="<div>",I="unselectable",W="cleditorButton",X="cleditorDisabled",ca="cleditorPopup",S="cleditorList",da="cleditorColor",B="cleditorPrompt",fa="cleditorMsg",l=e.browser.msie,ea=/msie\s6/i.test(navigator.userAgent), -L=/iphone|ipad|ipod/i.test(navigator.userAgent),p={},Z,s=e.cleditor.buttons;e.each(s.init.split("|"),function(a,b){var c=b.split(","),d=c[0];s[d]={stripIndex:a,name:d,title:c[1]===""?d.charAt(0).toUpperCase()+d.substr(1):c[1],command:c[2]===""?d:c[2],popupName:c[3]===""?d:c[3]}});delete s.init;cleditor=function(a,b){var c=this;c.options=b=e.extend({},e.cleditor.defaultOptions,b);var d=c.$area=e(a).hide().data(Y,c).blur(function(){E(c,true)}),h=c.$main=e(m).addClass("cleditorMain").width(b.width).height(b.height), -f=c.$toolbar=e(m).addClass("cleditorToolbar").appendTo(h),i=e(m).addClass("cleditorGroup").appendTo(f);e.each(b.controls.split(" "),function(g,j){if(j==="")return true;if(j=="|"){e(m).addClass("cleditorDivider").appendTo(i);i=e(m).addClass("cleditorGroup").appendTo(f)}else{var k=s[j],o=e(m).data(x,k.name).addClass(W).attr("title",k.title).bind(q,e.proxy(aa,c)).appendTo(i).hover(O,P),G={};if(k.css)G=k.css;else if(k.image)G.backgroundImage="url("+U()+k.image+")";if(k.stripIndex)G.backgroundPosition= -k.stripIndex*-24;o.css(G);l&&o.attr(I,"on");k.popupName&&R(k.popupName,b,k.popupClass,k.popupContent,k.popupHover)}});h.insertBefore(d).append(d);if(!Z){e(document).click(function(g){g=e(g.target);g.add(g.parents()).is("."+B)||r()});Z=true}/auto|%/.test(""+b.width+b.height)&&e(window).resize(function(){K(c)});K(c)};var $=cleditor.prototype;e.each([["clear",function(a){a.$area.val("");E(a)}],["disable",T],["execCommand",v],["focus",w],["hidePopups",r],["sourceMode",t,true],["refresh",K],["select", -function(a){setTimeout(function(){t(a)?a.$area.select():v(a,"selectall")},0)}],["selectedHTML",function(a){D(a);a=y(a);if(l)return a.htmlText;var b=e("<layer>")[0];b.appendChild(a.cloneContents());return b.innerHTML},true],["selectedText",M,true],["showMessage",z],["updateFrame",E],["updateTextArea",V]],function(a,b){$[b[0]]=function(){for(var c=[this],d=0;d<arguments.length;d++)c.push(arguments[d]);c=b[1].apply(this,c);if(b[2])return c;return this}});$.change=function(a){var b=e(this);return a?b.bind(F, -a):b.trigger(F)}})(jQuery);
\ No newline at end of file diff --git a/library/epub-meta/assets/js/script.js b/library/epub-meta/assets/js/script.js deleted file mode 100644 index cf8b3f2a1..000000000 --- a/library/epub-meta/assets/js/script.js +++ /dev/null @@ -1,194 +0,0 @@ - -var bookapi = { - $dialog: null, - - resulttpl: - '<div class="result">' + - ' <img src="" />'+ - ' <div>' + - ' <div class="buttons">' + - ' <button class="btn-repl">replace</button><br />' + - ' <button class="btn-fill">fill in</button>' + - ' </div>' + - ' <h1 class="title"></h1>' + - ' <p class="authors"></p>' + - ' <p class="description"></p>' + - ' <p class="more">' + - ' <span class="lang"></span>' + - ' <span class="publisher"></span>' + - ' <span class="subjects"></span>' + - ' </p>' + - ' </div>' + - '</div>', - - init: function(){ - $('body').append('<div id="bookapi"></div>'); - bookapi.$dialog = $('#bookapi'); - bookapi.$dialog.dialog( - { - autoOpen: false, - title: 'Lookup Book Data', - width: 800, - height: 500 - } - ); - bookapi.$dialog.append('<div class="head">Lookup: <input type="text" id="bookapi-q" /></div>') - .append('<div id="bookapi-out"></div>'); - bookapi.$out = $('#bookapi-out'); - - $('#bookpanel').append('<a href="#" id="bookapi-s">Lookup Book Data</a>'); - $('#bookapi-s').attr('title','Search this book at Google Books'); - $('#bookapi-s').click(bookapi.open); - - $('#bookapi-q').keypress( - function(event){ - if(event.which == 13){ - event.preventDefault(); - bookapi.search(); - } - }); - - }, - - open: function(){ - bookapi.$dialog.dialog('open'); - - var query = $('#bookpanel input[name=title]').val(); - $('#bookapi-q').val(query); - - bookapi.search(); - }, - - search: function(){ - bookapi.$out.html('please wait...'); - $.ajax({ - type: 'GET', - data: {'api':$('#bookapi-q').val()}, - success: bookapi.searchdone, - dataType: 'json' - }); - }, - - searchdone: function(data){ - if(data.totalItems == 0){ - bookapi.$out.html('Found no results.<br />Try adjusting the query and retry.'); - return; - } - - bookapi.$out.html(''); - for(i=0; i<data.items.length; i++){ - $res = $(bookapi.resulttpl); - if(data.items[i].volumeInfo.title) - $res.find('.title').html(data.items[i].volumeInfo.title); - if(data.items[i].volumeInfo.authors) - $res.find('.authors').html(data.items[i].volumeInfo.authors.join(', ')); - if(data.items[i].volumeInfo.description) - $res.find('.description').html(data.items[i].volumeInfo.description); - if(data.items[i].volumeInfo.language) - $res.find('.lang').html('['+data.items[i].volumeInfo.language+']'); - if(data.items[i].volumeInfo.publisher) - $res.find('.publisher').html(data.items[i].volumeInfo.publisher); - if(data.items[i].volumeInfo.categories) - $res.find('.subjects').html(data.items[i].volumeInfo.categories.join(', ')); - if(data.items[i].volumeInfo.imageLinks) - if(data.items[i].volumeInfo.imageLinks.thumbnail) - $res.find('img').attr('src',data.items[i].volumeInfo.imageLinks.thumbnail); - - $res.find('.btn-repl').click(data.items[i].volumeInfo,bookapi.replace); - $res.find('.btn-fill').click(data.items[i].volumeInfo,bookapi.fillin); - - bookapi.$out.append($res); - } - }, - - replace: function(event){ - item = event.data; - if(item.title) - $('#bookpanel input[name=title]').val(item.title); - if(item.description) - $('#bookpanel textarea[name=description]').val(item.description); - $wysiwyg[0].updateFrame(); - if(item.language) - $('#bookpanel input[name=language]').val(item.language); - if(item.publisher) - $('#bookpanel input[name=publisher]').val(item.publisher); - if(item.categories) - $('#bookpanel input[name=subjects]').val(item.categories.join(', ')); - if(item.imageLinks){ - $('#bookpanel input[name=coverurl]').val(item.imageLinks.thumbnail); - $('#cover').attr('src',item.imageLinks.thumbnail); - } - bookapi.$dialog.dialog('close'); - }, - - fillin: function(event){ - item = event.data; - - if(item.title && $('#bookpanel input[name=title]').val() == '') - $('#bookpanel input[name=title]').val(item.title); - if(item.description && $('#bookpanel textarea[name=description]').val() == '') - $('#bookpanel textarea[name=description]').val(item.description); - $wysiwyg[0].updateFrame(); - if(item.language && $('#bookpanel input[name=language]').val() == '') - $('#bookpanel input[name=language]').val(item.language); - if(item.publisher && $('#bookpanel input[name=publisher]').val() == '') - $('#bookpanel input[name=publisher]').val(item.publisher); - if(item.categories && $('#bookpanel input[name=subjects]').val() == '') - $('#bookpanel input[name=subjects]').val(item.categories.join(', ')); - if(item.imageLinks && $('#cover').hasClass('noimg')){ - $('#bookpanel input[name=coverurl]').val(item.imageLinks.thumbnail); - $('#cover').attr('src',item.imageLinks.thumbnail); - } - bookapi.$dialog.dialog('close'); - } - -}; - -var author = { - init: function(){ - $button = $(document.createElement('a')); - $button.text('+').attr('href','#'); - $button.attr('title','add another author line'); - $button.click(author.add); - $button.addClass('addauthor'); - - $td = $('#authors'); - $td.append($button); - }, - - add: function(){ - $td = $('#authors'); - - $ps = $td.find('p'); - $new = $ps.first().clone(); - $new.find('input').first().attr('name','authorname['+$ps.length+']').val(''); - $new.find('input').last().attr('name','authoras['+$ps.length+']').val(''); - - $ps.last().after($new); - } -}; - -var $wysiwg = null; -$(function(){ - bookapi.init(); - author.init(); - - // scroll to currently selected book - $current = $('#booklist li.active'); - if($current.length){ - $current[0].scrollIntoView(); - } - - // initialize the WYSIWYG editor - $wysiwyg = $('textarea').cleditor({ - width: 450, - controls: // controls to add to the toolbar - "bold italic underline strikethrough | " + - "style removeformat | bullets numbering | " + - "alignleft center alignright justify | undo redo | " + - "link unlink | source", - styles: // styles in the style popup - [["Paragraph", "<p>"], ["Header 1", "<h1>"], ["Header 2", "<h2>"], - ["Header 3", "<h3>"], ["Header 4","<h4>"], ["Header 5","<h5>"]] - }); -}); diff --git a/library/epub-meta/epub.php b/library/epub-meta/epub.php deleted file mode 100644 index 6895a6797..000000000 --- a/library/epub-meta/epub.php +++ /dev/null @@ -1,536 +0,0 @@ -<?php -/** - * PHP EPub Meta library - * - * @author Andreas Gohr <andi@splitbrain.org> - */ -class EPub { - public $xml; //FIXME change to protected, later - protected $xpath; - protected $file; - protected $meta; - protected $namespaces; - protected $imagetoadd=''; - - /** - * Constructor - * - * @param string $file path to epub file to work on - * @throws Exception if metadata could not be loaded - */ - public function __construct($file){ - // open file - $this->file = $file; - $zip = new ZipArchive(); - if(!@$zip->open($this->file)){ - throw new Exception('Failed to read epub file'); - } - - // read container data - $data = $zip->getFromName('META-INF/container.xml'); - if($data == false){ - throw new Exception('Failed to access epub container data'); - } - $xml = new DOMDocument(); - $xml->registerNodeClass('DOMElement','EPubDOMElement'); - $xml->loadXML($data); - $xpath = new EPubDOMXPath($xml); - $nodes = $xpath->query('//n:rootfiles/n:rootfile[@media-type="application/oebps-package+xml"]'); - $this->meta = $nodes->item(0)->attr('full-path'); - - // load metadata - $data = $zip->getFromName($this->meta); - if(!$data){ - throw new Exception('Failed to access epub metadata'); - } - $this->xml = new DOMDocument(); - $this->xml->registerNodeClass('DOMElement','EPubDOMElement'); - $this->xml->loadXML($data); - $this->xml->formatOutput = true; - $this->xpath = new EPubDOMXPath($this->xml); - - $zip->close(); - } - - /** - * file name getter - */ - public function file(){ - return $this->file; - } - - /** - * Writes back all meta data changes - */ - public function save(){ - $zip = new ZipArchive(); - $res = @$zip->open($this->file, ZipArchive::CREATE); - if($res === false){ - throw new Exception('Failed to write back metadata'); - } - $zip->addFromString($this->meta,$this->xml->saveXML()); - // add the cover image - if($this->imagetoadd){ - $path = dirname('/'.$this->meta).'/php-epub-meta-cover.img'; // image path is relative to meta file - $path = ltrim($path,'/'); - - $zip->addFromString($path,file_get_contents($this->imagetoadd)); - $this->imagetoadd=''; - } - $zip->close(); - } - - /** - * Get or set the book author(s) - * - * Authors should be given with a "file-as" and a real name. The file as - * is used for sorting in e-readers. - * - * Example: - * - * array( - * 'Pratchett, Terry' => 'Terry Pratchett', - * 'Simpson, Jacqeline' => 'Jacqueline Simpson', - * ) - * - * @params array $authors - */ - public function Authors($authors=false){ - // set new data - if($authors !== false){ - // Author where given as a comma separated list - if(is_string($authors)){ - if($authors == ''){ - $authors = array(); - }else{ - $authors = explode(',',$authors); - $authors = array_map('trim',$authors); - } - } - - // delete existing nodes - $nodes = $this->xpath->query('//opf:metadata/dc:creator[@opf:role="aut"]'); - foreach($nodes as $node) $node->delete(); - - // add new nodes - $parent = $this->xpath->query('//opf:metadata')->item(0); - foreach($authors as $as => $name){ - if(is_int($as)) $as = $name; //numeric array given - $node = $parent->newChild('dc:creator',$name); - $node->attr('opf:role', 'aut'); - $node->attr('opf:file-as', $as); - } - - $this->reparse(); - } - - // read current data - $rolefix = false; - $authors = array(); - $nodes = $this->xpath->query('//opf:metadata/dc:creator[@opf:role="aut"]'); - if($nodes->length == 0){ - // no nodes where found, let's try again without role - $nodes = $this->xpath->query('//opf:metadata/dc:creator'); - $rolefix = true; - } - foreach($nodes as $node){ - $name = $node->nodeValue; - $as = $node->attr('opf:file-as'); - if(!$as){ - $as = $name; - $node->attr('opf:file-as',$as); - } - if($rolefix){ - $node->attr('opf:role','aut'); - } - $authors[$as] = $name; - } - return $authors; - } - - /** - * Set or get the book title - * - * @param string $title - */ - public function Title($title=false){ - return $this->getset('dc:title',$title); - } - - /** - * Set or get the book's language - * - * @param string $lang - */ - public function Language($lang=false){ - return $this->getset('dc:language',$lang); - } - - /** - * Set or get the book' publisher info - * - * @param string $publisher - */ - public function Publisher($publisher=false){ - return $this->getset('dc:publisher',$publisher); - } - - /** - * Set or get the book's copyright info - * - * @param string $rights - */ - public function Copyright($rights=false){ - return $this->getset('dc:rights',$rights); - } - - /** - * Set or get the book's description - * - * @param string $description - */ - public function Description($description=false){ - return $this->getset('dc:description',$description); - } - - /** - * Set or get the book's ISBN number - * - * @param string $isbn - */ - public function ISBN($isbn=false){ - return $this->getset('dc:identifier',$isbn,'opf:scheme','ISBN'); - } - - /** - * Set or get the Google Books ID - * - * @param string $google - */ - public function Google($google=false){ - return $this->getset('dc:identifier',$google,'opf:scheme','GOOGLE'); - } - - /** - * Set or get the Amazon ID of the book - * - * @param string $amazon - */ - public function Amazon($amazon=false){ - return $this->getset('dc:identifier',$amazon,'opf:scheme','AMAZON'); - } - - /** - * Set or get the book's subjects (aka. tags) - * - * Subject should be given as array, but a comma separated string will also - * be accepted. - * - * @param array $subjects - */ - public function Subjects($subjects=false){ - // setter - if($subjects !== false){ - if(is_string($subjects)){ - if($subjects === ''){ - $subjects = array(); - }else{ - $subjects = explode(',',$subjects); - $subjects = array_map('trim',$subjects); - } - } - - // delete previous - $nodes = $this->xpath->query('//opf:metadata/dc:subject'); - foreach($nodes as $node){ - $node->delete(); - } - // add new ones - $parent = $this->xpath->query('//opf:metadata')->item(0); - foreach($subjects as $subj){ - $node = $this->xml->createElement('dc:subject',htmlspecialchars($subj)); - $node = $parent->appendChild($node); - } - - $this->reparse(); - } - - //getter - $subjects = array(); - $nodes = $this->xpath->query('//opf:metadata/dc:subject'); - foreach($nodes as $node){ - $subjects[] = $node->nodeValue; - } - return $subjects; - } - - /** - * Read the cover data - * - * Returns an associative array with the following keys: - * - * mime - filetype (usually image/jpeg) - * data - the binary image data - * found - the internal path, or false if no image is set in epub - * - * When no image is set in the epub file, the binary data for a transparent - * GIF pixel is returned. - * - * When adding a new image this function return no or old data because the - * image contents are not in the epub file, yet. The image will be added when - * the save() method is called. - * - * @param string $path local filesystem path to a new cover image - * @param string $mime mime type of the given file - * @return array - */ - public function Cover($path=false, $mime=false){ - // set cover - if($path !== false){ - // remove current pointer - $nodes = $this->xpath->query('//opf:metadata/opf:meta[@name="cover"]'); - foreach($nodes as $node) $node->delete(); - // remove previous manifest entries if they where made by us - $nodes = $this->xpath->query('//opf:manifest/opf:item[@id="php-epub-meta-cover"]'); - foreach($nodes as $node) $node->delete(); - - if($path){ - // add pointer - $parent = $this->xpath->query('//opf:metadata')->item(0); - $node = $parent->newChild('opf:meta'); - $node->attr('opf:name','cover'); - $node->attr('opf:content','php-epub-meta-cover'); - - // add manifest - $parent = $this->xpath->query('//opf:manifest')->item(0); - $node = $parent->newChild('opf:item'); - $node->attr('id','php-epub-meta-cover'); - $node->attr('opf:href','php-epub-meta-cover.img'); - $node->attr('opf:media-type',$mime); - - // remember path for save action - $this->imagetoadd = $path; - } - - $this->reparse(); - } - - // load cover - $nodes = $this->xpath->query('//opf:metadata/opf:meta[@name="cover"]'); - if(!$nodes->length) return $this->no_cover(); - $coverid = (String) $nodes->item(0)->attr('opf:content'); - if(!$coverid) return $this->no_cover(); - - $nodes = $this->xpath->query('//opf:manifest/opf:item[@id="'.$coverid.'"]'); - if(!$nodes->length) return $this->no_cover(); - $mime = $nodes->item(0)->attr('opf:media-type'); - $path = $nodes->item(0)->attr('opf:href'); - $path = dirname('/'.$this->meta).'/'.$path; // image path is relative to meta file - $path = ltrim($path,'/'); - - $zip = new ZipArchive(); - if(!@$zip->open($this->file)){ - throw new Exception('Failed to read epub file'); - } - $data = $zip->getFromName($path); - - return array( - 'mime' => $mime, - 'data' => $data, - 'found' => $path - ); - } - - /** - * A simple getter/setter for simple meta attributes - * - * It should only be used for attributes that are expected to be unique - * - * @param string $item XML node to set/get - * @param string $value New node value - * @param string $att Attribute name - * @param string $aval Attribute value - */ - protected function getset($item,$value=false,$att=false,$aval=false){ - // construct xpath - $xpath = '//opf:metadata/'.$item; - if($att){ - $xpath .= "[@$att=\"$aval\"]"; - } - - // set value - if($value !== false){ - $value = htmlspecialchars($value); - $nodes = $this->xpath->query($xpath); - if($nodes->length == 1 ){ - if($value === ''){ - // the user want's to empty this value -> delete the node - $nodes->item(0)->delete(); - }else{ - // replace value - $nodes->item(0)->nodeValue = $value; - } - }else{ - // if there are multiple matching nodes for some reason delete - // them. we'll replace them all with our own single one - foreach($nodes as $n) $n->delete(); - // readd them - if($value){ - $parent = $this->xpath->query('//opf:metadata')->item(0); - $node = $this->xml->createElement($item,$value); - $node = $parent->appendChild($node); - if($att) $node->attr($att,$aval); - } - } - - $this->reparse(); - } - - // get value - $nodes = $this->xpath->query($xpath); - if($nodes->length){ - return $nodes->item(0)->nodeValue; - }else{ - return ''; - } - } - - /** - * Return a not found response for Cover() - */ - protected function no_cover(){ - return array( - 'data' => base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7'), - 'mime' => 'image/gif', - 'found' => false - ); - } - - /** - * Reparse the DOM tree - * - * I had to rely on this because otherwise xpath failed to find the newly - * added nodes - */ - protected function reparse() { - $this->xml->loadXML($this->xml->saveXML()); - $this->xpath = new EPubDOMXPath($this->xml); - } -} - -class EPubDOMXPath extends DOMXPath { - public function __construct(DOMDocument $doc){ - parent::__construct($doc); - - if(is_a($doc->documentElement, 'EPubDOMElement')){ - foreach($doc->documentElement->namespaces as $ns => $url){ - $this->registerNamespace($ns,$url); - } - } - } -} - -class EPubDOMElement extends DOMElement { - public $namespaces = array( - 'n' => 'urn:oasis:names:tc:opendocument:xmlns:container', - 'opf' => 'http://www.idpf.org/2007/opf', - 'dc' => 'http://purl.org/dc/elements/1.1/' - ); - - - public function __construct($name, $value='', $namespaceURI=''){ - list($ns,$name) = $this->splitns($name); - $value = htmlspecialchars($value); - if(!$namespaceURI && $ns){ - $namespaceURI = $this->namespaces[$ns]; - } - parent::__construct($name, $value, $namespaceURI); - } - - - /** - * Create and append a new child - * - * Works with our epub namespaces and omits default namespaces - */ - public function newChild($name, $value=''){ - list($ns,$local) = $this->splitns($name); - if($ns){ - $nsuri = $this->namespaces[$ns]; - if($this->isDefaultNamespace($nsuri)){ - $name = $local; - $nsuri = ''; - } - } - - // this doesn't call the construcor: $node = $this->ownerDocument->createElement($name,$value); - $node = new EPubDOMElement($name,$value,$nsuri); - return $this->appendChild($node); - } - - /** - * Split given name in namespace prefix and local part - * - * @param string $name - * @return array (namespace, name) - */ - public function splitns($name){ - $list = explode(':',$name,2); - if(count($list) < 2) array_unshift($list,''); - return $list; - } - - /** - * Simple EPub namespace aware attribute accessor - */ - public function attr($attr,$value=null){ - list($ns,$attr) = $this->splitns($attr); - - $nsuri = ''; - if($ns){ - $nsuri = $this->namespaces[$ns]; - if(!$this->namespaceURI){ - if($this->isDefaultNamespace($nsuri)){ - $nsuri = ''; - } - }elseif($this->namespaceURI == $nsuri){ - $nsuri = ''; - } - } - - if(!is_null($value)){ - if($value === false){ - // delete if false was given - if($nsuri){ - $this->removeAttributeNS($nsuri,$attr); - }else{ - $this->removeAttribute($attr); - } - }else{ - // modify if value was given - if($nsuri){ - $this->setAttributeNS($nsuri,$attr,$value); - }else{ - $this->setAttribute($attr,$value); - } - } - }else{ - // return value if none was given - if($nsuri){ - return $this->getAttributeNS($nsuri,$attr); - }else{ - return $this->getAttribute($attr); - } - } - } - - /** - * Remove this node from the DOM - */ - public function delete(){ - $this->parentNode->removeChild($this); - } - -} - - diff --git a/library/epub-meta/index.php b/library/epub-meta/index.php deleted file mode 100644 index 57bb31b5c..000000000 --- a/library/epub-meta/index.php +++ /dev/null @@ -1,214 +0,0 @@ -<?php - // modify this to point to your book directory - $bookdir = '/home/andi/Dropbox/ebooks/'; - - - error_reporting(E_ALL ^ E_NOTICE); - - // proxy google requests - if(isset($_GET['api'])){ - header('application/json; charset=UTF-8'); - echo file_get_contents('https://www.googleapis.com/books/v1/volumes?q='.rawurlencode($_GET['api']).'&maxResults=25&printType=books&projection=full'); - exit; - } - - require('util.php'); - - // load epub data - require('epub.php'); - if(isset($_REQUEST['book'])){ - try{ - $book = $_REQUEST['book']; - $book = str_replace('..','',$book); // no upper dirs, lowers might be supported later - $epub = new EPub($bookdir.$book.'.epub'); - }catch (Exception $e){ - $error = $e->getMessage(); - } - } - - // return image data - if(isset($_REQUEST['img']) && isset($epub)){ - $img = $epub->Cover(); - header('Content-Type: '.$img['mime']); - echo $img['data']; - exit; - } - - // save epub data - if($_REQUEST['save'] && isset($epub)){ - $epub->Title($_POST['title']); - $epub->Description($_POST['description']); - $epub->Language($_POST['language']); - $epub->Publisher($_POST['publisher']); - $epub->Copyright($_POST['copyright']); - $epub->ISBN($_POST['isbn']); - $epub->Subjects($_POST['subjects']); - - $authors = array(); - foreach((array) $_POST['authorname'] as $num => $name){ - if($name){ - $as = $_POST['authoras'][$num]; - if(!$as) $as = $name; - $authors[$as] = $name; - } - } - $epub->Authors($authors); - - // handle image - $cover = ''; - if(preg_match('/^https?:\/\//i',$_POST['coverurl'])){ - $data = @file_get_contents($_POST['coverurl']); - if($data){ - $cover = tempnam(sys_get_temp_dir(), 'epubcover'); - file_put_contents($cover,$data); - unset($data); - } - }elseif(is_uploaded_file($_FILES['coverfile']['tmp_name'])){ - $cover = $_FILES['coverfile']['tmp_name']; - } - if($cover){ - $info = @getimagesize($cover); - if(preg_match('/^image\/(gif|jpe?g|png)$/',$info['mime'])){ - $epub->Cover($cover,$info['meta']); - }else{ - $error = "Not a valid image file".$cover; - } - } - - // save the ebook - try{ - $epub->save(); - }catch(Exception $e){ - $error = $e->getMessage(); - } - - // clean up temporary cover file - if($cover) @unlink($cover); - - // rename - $author = array_shift(array_keys($epub->Authors())); - $title = $epub->Title(); - $new = to_file($author.'-'.$title); - $new = $bookdir.$new.'.epub'; - $old = $epub->file(); - if(realpath($new) != realpath($old)){ - if(!@rename($old,$new)) $new = $old; //rename failed, stay here - } - $go = basename($new,'.epub'); - header('Location: ?book='.rawurlencode($go)); - exit; - } - - header('Content-Type: text/html; charset=utf-8'); -?> -<html> -<head> - <title>EPub Manager</title> - - <link rel="stylesheet" type="text/css" href="assets/css/smoothness/jquery-ui-1.8.18.custom.css" /> - <link rel="stylesheet" type="text/css" href="assets/css/cleditor/jquery.cleditor.css" /> - <link rel="stylesheet" type="text/css" href="assets/css/style.css" /> - - <script type="text/javascript"> - <?php if($error) echo "alert('".htmlspecialchars($error)."');";?> - </script> -</head> -<body> - -<div id="wrapper"> - <ul id="booklist"> - <?php - $list = glob($bookdir.'/*.epub'); - foreach($list as $book){ - $base = basename($book,'.epub'); - $name = book_output($base); - echo '<li '.($base == $_REQUEST['book'] ? 'class="active"' : '' ).'>'; - echo '<a href="?book='.htmlspecialchars($base).'">'.$name.'</a>'; - echo '</li>'; - } - ?> - </ul> - - <?php if($epub): ?> - <form action="" method="post" id="bookpanel" enctype="multipart/form-data"> - <input type="hidden" name="book" value="<?php echo htmlspecialchars($_REQUEST['book'])?>" /> - - <table> - <tr> - <th>Title</th> - <td><input type="text" name="title" value="<?php echo htmlspecialchars($epub->Title())?>" /></td> - </tr> - <tr> - <th>Authors</th> - <td id="authors"> - <?php - $count = 0; - foreach($epub->Authors() as $as => $name){ - ?> - <p> - <input type="text" name="authorname[<?php echo $count?>]" value="<?php echo htmlspecialchars($name)?>" /> - (<input type="text" name="authoras[<?php echo $count?>]" value="<?php echo htmlspecialchars($as)?>" />) - </p> - <?php - $count++; - } - ?> - </td> - </tr> - <tr> - <th>Description<br /> - <img src="?book=<?php echo htmlspecialchars($_REQUEST['book'])?>&img=1" id="cover" width="90" - class="<?php $c = $epub->Cover(); echo ($c['found']?'hasimg':'noimg')?>" /> - </th> - <td><textarea name="description"><?php echo htmlspecialchars($epub->Description())?></textarea></td> - </tr> - <tr> - <th>Subjects</th> - <td><input type="text" name="subjects" value="<?php echo htmlspecialchars(join(', ',$epub->Subjects()))?>" /></td> - </tr> - <tr> - <th>Publisher</th> - <td><input type="text" name="publisher" value="<?php echo htmlspecialchars($epub->Publisher())?>" /></td> - </tr> - <tr> - <th>Copyright</th> - <td><input type="text" name="copyright" value="<?php echo htmlspecialchars($epub->Copyright())?>" /></td> - </tr> - <tr> - <th>Language</th> - <td><p><input type="text" name="language" value="<?php echo htmlspecialchars($epub->Language())?>" /></p></td> - </tr> - <tr> - <th>ISBN</th> - <td><p><input type="text" name="isbn" value="<?php echo htmlspecialchars($epub->ISBN())?>" /></p></td> - </tr> - <tr> - <th>Cover Image</th> - <td><p> - <input type="file" name="coverfile" /> - URL: <input type="text" name="coverurl" value="" /> - </p></td> - </table> - <div class="center"> - <input name="save" type="submit" /> - </div> - </form> - <?php else: ?> - <h1>EPub Manager</h1> - - <p>View and edit epub books stored in <code><?php echo htmlspecialchars($bookdir)?></code>.</p> - <div class="license"> - <p><?php echo str_replace("\n\n",'</p><p>',htmlspecialchars(file_get_contents('LICENSE'))) ?></p> - </div> - - <?php endif; ?> - - <!-- load at the end, for faster site load --> - <script type="text/javascript" src="assets/js/jquery-1.7.1.min.js"></script> - <script type="text/javascript" src="assets/js/jquery-ui-1.8.18.custom.min.js"></script> - <script type="text/javascript" src="assets/js/jquery.cleditor.min.js"></script> - <script type="text/javascript" src="assets/js/script.js"></script> - -</div> -</body> -</html> diff --git a/library/epub-meta/test/test.epub b/library/epub-meta/test/test.epub Binary files differdeleted file mode 100644 index 85d60aece..000000000 --- a/library/epub-meta/test/test.epub +++ /dev/null diff --git a/library/epub-meta/test/test.jpg b/library/epub-meta/test/test.jpg Binary files differdeleted file mode 100644 index 4ca4a685c..000000000 --- a/library/epub-meta/test/test.jpg +++ /dev/null diff --git a/library/epub-meta/test/test.phpunit.php b/library/epub-meta/test/test.phpunit.php deleted file mode 100644 index 88a9aa914..000000000 --- a/library/epub-meta/test/test.phpunit.php +++ /dev/null @@ -1,190 +0,0 @@ -<?php - -require '../epub.php'; - - -class EPubTest extends PHPUnit_Framework_TestCase { - - protected $epub; - - protected function setUp(){ - // sometime I might have accidentally broken the test file - if(filesize('test.epub') != 768780){ - die('test.epub has wrong size, make sure it\'s unmodified'); - } - - // we work on a copy to test saving - if(!copy('test.epub','test.copy.epub')){ - die('failed to create copy of the test book'); - } - - $this->epub = new EPub('test.copy.epub'); - } - - protected function tearDown(){ - unlink('test.copy.epub'); - } - - public function testAuthors(){ - // read curent value - $this->assertEquals( - $this->epub->Authors(), - array('Shakespeare, William' => 'William Shakespeare') - ); - - // remove value with string - $this->assertEquals( - $this->epub->Authors(''), - array() - ); - - // set single value by String - - $this->assertEquals( - $this->epub->Authors('John Doe'), - array('John Doe' => 'John Doe') - ); - - // set single value by indexed array - $this->assertEquals( - $this->epub->Authors(array('John Doe')), - array('John Doe' => 'John Doe') - ); - - // remove value with array - $this->assertEquals( - $this->epub->Authors(array()), - array() - ); - - // set single value by associative array - $this->assertEquals( - $this->epub->Authors(array('Doe, John' => 'John Doe')), - array('Doe, John' => 'John Doe') - ); - - // set multi value by string - $this->assertEquals( - $this->epub->Authors('John Doe, Jane Smith'), - array('John Doe' => 'John Doe', 'Jane Smith' => 'Jane Smith') - ); - - // set multi value by indexed array - $this->assertEquals( - $this->epub->Authors(array('John Doe', 'Jane Smith')), - array('John Doe' => 'John Doe', 'Jane Smith' => 'Jane Smith') - ); - - // set multi value by associative array - $this->assertEquals( - $this->epub->Authors(array('Doe, John' => 'John Doe', 'Smith, Jane' => 'Jane Smith')), - array('Doe, John' => 'John Doe', 'Smith, Jane' => 'Jane Smith') - ); - - // check escaping - $this->assertEquals( - $this->epub->Authors(array('Doe, John ' => 'John Doe ')), - array('Doe, John ' => 'John Doe ') - ); - } - - public function testTitle(){ - // get current value - $this->assertEquals( - $this->epub->Title(), - 'Romeo and Juliet' - ); - - // delete current value - $this->assertEquals( - $this->epub->Title(''), - '' - ); - - // get current value - $this->assertEquals( - $this->epub->Title(), - '' - ); - - // set new value - $this->assertEquals( - $this->epub->Title('Foo Bar'), - 'Foo Bar' - ); - - // check escaping - $this->assertEquals( - $this->epub->Title('Foo Bar'), - 'Foo Bar' - ); - } - - public function testSubject(){ - // get current values - $this->assertEquals( - $this->epub->Subjects(), - array('Fiction','Drama','Romance') - ); - - // delete current values with String - $this->assertEquals( - $this->epub->Subjects(''), - array() - ); - - // set new values with String - $this->assertEquals( - $this->epub->Subjects('Fiction, Drama, Romance'), - array('Fiction','Drama','Romance') - ); - - // delete current values with Array - $this->assertEquals( - $this->epub->Subjects(array()), - array() - ); - - // set new values with array - $this->assertEquals( - $this->epub->Subjects(array('Fiction','Drama','Romance')), - array('Fiction','Drama','Romance') - ); - - // check escaping - $this->assertEquals( - $this->epub->Subjects(array('Fiction','Drama ','Romance')), - array('Fiction','Drama ','Romance') - ); - } - - - public function testCover(){ - // read current cover - $cover = $this->epub->Cover(); - $this->assertEquals($cover['mime'],'image/png'); - $this->assertEquals($cover['found'],'OPS/images/cover.png'); - $this->assertEquals(strlen($cover['data']), 657911); - - // delete cover - $cover = $this->epub->Cover(''); - $this->assertEquals($cover['mime'],'image/gif'); - $this->assertEquals($cover['found'],false); - $this->assertEquals(strlen($cover['data']), 42); - - // set new cover (will return a not-found as it's not yet saved) - $cover = $this->epub->Cover('test.jpg','image/jpeg'); - $this->assertEquals($cover['mime'],'image/jpeg'); - $this->assertEquals($cover['found'],'OPS/php-epub-meta-cover.img'); - $this->assertEquals(strlen($cover['data']), 0); - - // save - $this->epub->save(); - - // read now changed cover - $cover = $this->epub->Cover(); - $this->assertEquals($cover['mime'],'image/jpeg'); - $this->assertEquals($cover['found'],'OPS/php-epub-meta-cover.img'); - $this->assertEquals(strlen($cover['data']), filesize('test.jpg')); - } -} diff --git a/library/epub-meta/util.php b/library/epub-meta/util.php deleted file mode 100644 index 75cb8a829..000000000 --- a/library/epub-meta/util.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -function to_file($input){ - $input = str_replace(' ','_',$input); - $input = str_replace('__','_',$input); - $input = str_replace(',_',',',$input); - $input = str_replace('_,',',',$input); - $input = str_replace('-_','-',$input); - $input = str_replace('_-','-',$input); - $input = str_replace(',','__',$input); - return $input; -} - -function book_output($input){ - $input = str_replace('__',',',$input); - $input = str_replace('_',' ',$input); - $input = str_replace(',',', ',$input); - $input = str_replace('-',' - ',$input); - list($author,$title) = explode('-',$input,2); - $author = trim($author); - $title = trim($title); - - if(!$title){ - $title = $author; - $author = ''; - } - - return '<span class="title">'.htmlspecialchars($title).'</span>'. - '<span class="author">'.htmlspecialchars($author).'</author>'; -} diff --git a/library/openid/README b/library/openid/README deleted file mode 100644 index 799b452ac..000000000 --- a/library/openid/README +++ /dev/null @@ -1,49 +0,0 @@ -This class provides a simple interface for OpenID (1.1 and 2.0) authentication. -Supports Yadis discovery. - -The authentication process is stateless/dumb. - -Usage: -Sign-on with OpenID is a two step process: -Step one is authentication with the provider: -<code> -$openid = new LightOpenID('my-host.example.org'); -$openid->identity = 'ID supplied by user'; -header('Location: ' . $openid->authUrl()); -</code> - -The provider then sends various parameters via GET, one of them is openid_mode. -Step two is verification: -<code> -if ($this->data['openid_mode']) { - $openid = new LightOpenID('my-host.example.org'); - echo $openid->validate() ? 'Logged in.' : 'Failed'; -} -</code> - * -Change the 'my-host.example.org' to your domain name. Do NOT use $_SERVER['HTTP_HOST'] -for that, unless you know what you are doing. - * -Optionally, you can set $returnUrl and $realm (or $trustRoot, which is an alias). -The default values for those are: -$openid->realm = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; -$openid->returnUrl = $openid->realm . $_SERVER['REQUEST_URI']; -If you don't know their meaning, refer to any openid tutorial, or specification. Or just guess. - * -AX and SREG extensions are supported. -To use them, specify $openid->required and/or $openid->optional before calling $openid->authUrl(). -These are arrays, with values being AX schema paths (the 'path' part of the URL). -For example: - $openid->required = array('namePerson/friendly', 'contact/email'); - $openid->optional = array('namePerson/first'); -If the server supports only SREG or OpenID 1.1, these are automaticaly -mapped to SREG names, so that user doesn't have to know anything about the server. - * -To get the values, use $openid->getAttributes(). - * -The library requires PHP >= 5.1.2 with curl or http/https stream wrappers enabled. -@author Mewp -@contributors Brice http://github.com/brice/ -@copyright Copyright (c) 2010, Mewp -@copyright Copyright (c) 2010, Brice -@license http://www.opensource.org/licenses/mit-license.php MIT
\ No newline at end of file diff --git a/library/openid/example-google.php b/library/openid/example-google.php deleted file mode 100644 index f23f2cc48..000000000 --- a/library/openid/example-google.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php -# Logging in with Google accounts requires setting special identity, so this example shows how to do it. -require 'openid.php'; -try { - # Change 'localhost' to your domain name. - $openid = new LightOpenID('localhost'); - if(!$openid->mode) { - if(isset($_GET['login'])) { - $openid->identity = 'https://www.google.com/accounts/o8/id'; - header('Location: ' . $openid->authUrl()); - } -?> -<form action="?login" method="post"> - <button>Login with Google</button> -</form> -<?php - } elseif($openid->mode == 'cancel') { - echo 'User has canceled authentication!'; - } else { - echo 'User ' . ($openid->validate() ? $openid->identity . ' has ' : 'has not ') . 'logged in.'; - } -} catch(ErrorException $e) { - echo $e->getMessage(); -} diff --git a/library/openid/example.php b/library/openid/example.php deleted file mode 100644 index e4ab107fe..000000000 --- a/library/openid/example.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -require 'openid.php'; -try { - # Change 'localhost' to your domain name. - $openid = new LightOpenID('localhost'); - if(!$openid->mode) { - if(isset($_POST['openid_identifier'])) { - $openid->identity = $_POST['openid_identifier']; - header('Location: ' . $openid->authUrl()); - } -?> -<form action="" method="post"> - OpenID: <input type="text" name="openid_identifier" /> <button>Submit</button> -</form> -<?php - } elseif($openid->mode == 'cancel') { - echo 'User has canceled authentication!'; - } else { - echo 'User ' . ($openid->validate() ? $openid->identity . ' has ' : 'has not ') . 'logged in.'; - } -} catch(ErrorException $e) { - echo $e->getMessage(); -} diff --git a/library/openid/openid.php b/library/openid/openid.php deleted file mode 100644 index 00250c59d..000000000 --- a/library/openid/openid.php +++ /dev/null @@ -1,781 +0,0 @@ -<?php -/** - * This class provides a simple interface for OpenID (1.1 and 2.0) authentication. - * Supports Yadis discovery. - * The authentication process is stateless/dumb. - * - * Usage: - * Sign-on with OpenID is a two step process: - * Step one is authentication with the provider: - * <code> - * $openid = new LightOpenID('my-host.example.org'); - * $openid->identity = 'ID supplied by user'; - * header('Location: ' . $openid->authUrl()); - * </code> - * The provider then sends various parameters via GET, one of them is openid_mode. - * Step two is verification: - * <code> - * if ($this->data['openid_mode']) { - * $openid = new LightOpenID('my-host.example.org'); - * echo $openid->validate() ? 'Logged in.' : 'Failed'; - * } - * </code> - * - * Change the 'my-host.example.org' to your domain name. Do NOT use $_SERVER['HTTP_HOST'] - * for that, unless you know what you are doing. - * - * Optionally, you can set $returnUrl and $realm (or $trustRoot, which is an alias). - * The default values for those are: - * $openid->realm = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; - * $openid->returnUrl = $openid->realm . $_SERVER['REQUEST_URI']; - * If you don't know their meaning, refer to any openid tutorial, or specification. Or just guess. - * - * AX and SREG extensions are supported. - * To use them, specify $openid->required and/or $openid->optional before calling $openid->authUrl(). - * These are arrays, with values being AX schema paths (the 'path' part of the URL). - * For example: - * $openid->required = array('namePerson/friendly', 'contact/email'); - * $openid->optional = array('namePerson/first'); - * If the server supports only SREG or OpenID 1.1, these are automaticaly - * mapped to SREG names, so that user doesn't have to know anything about the server. - * - * To get the values, use $openid->getAttributes(). - * - * - * The library requires PHP >= 5.1.2 with curl or http/https stream wrappers enabled. - * @author Mewp - * @copyright Copyright (c) 2010, Mewp - * @license http://www.opensource.org/licenses/mit-license.php MIT - */ -class LightOpenID -{ - public $returnUrl - , $required = array() - , $optional = array() - , $verify_peer = null - , $capath = null - , $cainfo = null - , $data; - private $identity, $claimed_id; - protected $server, $version, $trustRoot, $aliases, $identifier_select = false - , $ax = false, $sreg = false, $setup_url = null; - static protected $ax_to_sreg = array( - 'namePerson/friendly' => 'nickname', - 'contact/email' => 'email', - 'namePerson' => 'fullname', - 'birthDate' => 'dob', - 'person/gender' => 'gender', - 'contact/postalCode/home' => 'postcode', - 'contact/country/home' => 'country', - 'pref/language' => 'language', - 'pref/timezone' => 'timezone', - ); - - function __construct($host) - { - $this->trustRoot = (strpos($host, '://') ? $host : 'http://' . $host); - if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') - || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) - && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') - ) { - $this->trustRoot = (strpos($host, '://') ? $host : 'https://' . $host); - } - - if(($host_end = strpos($this->trustRoot, '/', 8)) !== false) { - $this->trustRoot = substr($this->trustRoot, 0, $host_end); - } - - $uri = rtrim(preg_replace('#((?<=\?)|&)openid\.[^&]+#', '', $_SERVER['REQUEST_URI']), '?'); - $this->returnUrl = $this->trustRoot . $uri; - - $this->data = ($_SERVER['REQUEST_METHOD'] === 'POST') ? $_POST : $_GET; - - if(!function_exists('curl_init') && !in_array('https', stream_get_wrappers())) { - throw new ErrorException('You must have either https wrappers or curl enabled.'); - } - } - - function __set($name, $value) - { - switch ($name) { - case 'identity': - if (strlen($value = trim((String) $value))) { - if (preg_match('#^xri:/*#i', $value, $m)) { - $value = substr($value, strlen($m[0])); - } elseif (!preg_match('/^(?:[=@+\$!\(]|https?:)/i', $value)) { - $value = "http://$value"; - } - if (preg_match('#^https?://[^/]+$#i', $value, $m)) { - $value .= '/'; - } - } - $this->$name = $this->claimed_id = $value; - break; - case 'trustRoot': - case 'realm': - $this->trustRoot = trim($value); - } - } - - function __get($name) - { - switch ($name) { - case 'identity': - # We return claimed_id instead of identity, - # because the developer should see the claimed identifier, - # i.e. what he set as identity, not the op-local identifier (which is what we verify) - return $this->claimed_id; - case 'trustRoot': - case 'realm': - return $this->trustRoot; - case 'mode': - return empty($this->data['openid_mode']) ? null : $this->data['openid_mode']; - } - } - - /** - * Checks if the server specified in the url exists. - * - * @param $url url to check - * @return true, if the server exists; false otherwise - */ - function hostExists($url) - { - if (strpos($url, '/') === false) { - $server = $url; - } else { - $server = @parse_url($url, PHP_URL_HOST); - } - - if (!$server) { - return false; - } - - return !!gethostbynamel($server); - } - - protected function request_curl($url, $method='GET', $params=array()) - { - $params = http_build_query($params, '', '&'); - $curl = curl_init($url . ($method == 'GET' && $params ? '?' . $params : '')); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($curl, CURLOPT_HEADER, false); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/xrds+xml, */*')); - - if($this->verify_peer !== null) { - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->verify_peer); - if($this->capath) { - curl_setopt($curl, CURLOPT_CAPATH, $this->capath); - } - - if($this->cainfo) { - curl_setopt($curl, CURLOPT_CAINFO, $this->cainfo); - } - } - - if ($method == 'POST') { - curl_setopt($curl, CURLOPT_POST, true); - curl_setopt($curl, CURLOPT_POSTFIELDS, $params); - } elseif ($method == 'HEAD') { - curl_setopt($curl, CURLOPT_HEADER, true); - curl_setopt($curl, CURLOPT_NOBODY, true); - } else { - curl_setopt($curl, CURLOPT_HTTPGET, true); - } - $response = curl_exec($curl); - - if($method == 'HEAD') { - $headers = array(); - foreach(explode("\n", $response) as $header) { - $pos = strpos($header,':'); - $name = strtolower(trim(substr($header, 0, $pos))); - $headers[$name] = trim(substr($header, $pos+1)); - } - - # Updating claimed_id in case of redirections. - $effective_url = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL); - if($effective_url != $url) { - $this->identity = $this->claimed_id = $effective_url; - } - - return $headers; - } - - if (curl_errno($curl)) { - throw new ErrorException(curl_error($curl), curl_errno($curl)); - } - - return $response; - } - - protected function request_streams($url, $method='GET', $params=array()) - { - if(!$this->hostExists($url)) { - throw new ErrorException("Could not connect to $url.", 404); - } - - $params = http_build_query($params, '', '&'); - switch($method) { - case 'GET': - $opts = array( - 'http' => array( - 'method' => 'GET', - 'header' => 'Accept: application/xrds+xml, */*', - 'ignore_errors' => true, - ), 'ssl' => array( - 'CN_match' => parse_url($url, PHP_URL_HOST), - ), - ); - $url = $url . ($params ? '?' . $params : ''); - break; - case 'POST': - $opts = array( - 'http' => array( - 'method' => 'POST', - 'header' => 'Content-type: application/x-www-form-urlencoded', - 'content' => $params, - 'ignore_errors' => true, - ), 'ssl' => array( - 'CN_match' => parse_url($url, PHP_URL_HOST), - ), - ); - break; - case 'HEAD': - # We want to send a HEAD request, - # but since get_headers doesn't accept $context parameter, - # we have to change the defaults. - $default = stream_context_get_options(stream_context_get_default()); - stream_context_get_default( - array( - 'http' => array( - 'method' => 'HEAD', - 'header' => 'Accept: application/xrds+xml, */*', - 'ignore_errors' => true, - ), 'ssl' => array( - 'CN_match' => parse_url($url, PHP_URL_HOST), - ), - ) - ); - - $url = $url . ($params ? '?' . $params : ''); - $headers_tmp = get_headers ($url); - if(!$headers_tmp) { - return array(); - } - - # Parsing headers. - $headers = array(); - foreach($headers_tmp as $header) { - $pos = strpos($header,':'); - $name = strtolower(trim(substr($header, 0, $pos))); - $headers[$name] = trim(substr($header, $pos+1)); - - # Following possible redirections. The point is just to have - # claimed_id change with them, because get_headers() will - # follow redirections automatically. - # We ignore redirections with relative paths. - # If any known provider uses them, file a bug report. - if($name == 'location') { - if(strpos($headers[$name], 'http') === 0) { - $this->identity = $this->claimed_id = $headers[$name]; - } elseif($headers[$name][0] == '/') { - $parsed_url = parse_url($this->claimed_id); - $this->identity = - $this->claimed_id = $parsed_url['scheme'] . '://' - . $parsed_url['host'] - . $headers[$name]; - } - } - } - - # And restore them. - stream_context_get_default($default); - return $headers; - } - - if($this->verify_peer) { - $opts['ssl'] += array( - 'verify_peer' => true, - 'capath' => $this->capath, - 'cafile' => $this->cainfo, - ); - } - - $context = stream_context_create ($opts); - - return file_get_contents($url, false, $context); - } - - protected function request($url, $method='GET', $params=array()) - { - if (function_exists('curl_init') - && (!in_array('https', stream_get_wrappers()) || !ini_get('safe_mode') && !ini_get('open_basedir')) - ) { - return $this->request_curl($url, $method, $params); - } - return $this->request_streams($url, $method, $params); - } - - protected function build_url($url, $parts) - { - if (isset($url['query'], $parts['query'])) { - $parts['query'] = $url['query'] . '&' . $parts['query']; - } - - $url = $parts + $url; - $url = $url['scheme'] . '://' - . (empty($url['username'])?'' - :(empty($url['password'])? "{$url['username']}@" - :"{$url['username']}:{$url['password']}@")) - . $url['host'] - . (empty($url['port'])?'':":{$url['port']}") - . (empty($url['path'])?'':$url['path']) - . (empty($url['query'])?'':"?{$url['query']}") - . (empty($url['fragment'])?'':"#{$url['fragment']}"); - return $url; - } - - /** - * Helper function used to scan for <meta>/<link> tags and extract information - * from them - */ - protected function htmlTag($content, $tag, $attrName, $attrValue, $valueName) - { - preg_match_all("#<{$tag}[^>]*$attrName=['\"].*?$attrValue.*?['\"][^>]*$valueName=['\"](.+?)['\"][^>]*/?>#i", $content, $matches1); - preg_match_all("#<{$tag}[^>]*$valueName=['\"](.+?)['\"][^>]*$attrName=['\"].*?$attrValue.*?['\"][^>]*/?>#i", $content, $matches2); - - $result = array_merge($matches1[1], $matches2[1]); - return empty($result)?false:$result[0]; - } - - /** - * Performs Yadis and HTML discovery. Normally not used. - * @param $url Identity URL. - * @return String OP Endpoint (i.e. OpenID provider address). - * @throws ErrorException - */ - function discover($url) - { - if (!$url) throw new ErrorException('No identity supplied.'); - # Use xri.net proxy to resolve i-name identities - if (!preg_match('#^https?:#', $url)) { - $url = "https://xri.net/$url"; - } - - # We save the original url in case of Yadis discovery failure. - # It can happen when we'll be lead to an XRDS document - # which does not have any OpenID2 services. - $originalUrl = $url; - - # A flag to disable yadis discovery in case of failure in headers. - $yadis = true; - - # We'll jump a maximum of 5 times, to avoid endless redirections. - for ($i = 0; $i < 5; $i ++) { - if ($yadis) { - $headers = $this->request($url, 'HEAD'); - - $next = false; - if (isset($headers['x-xrds-location'])) { - $url = $this->build_url(parse_url($url), parse_url(trim($headers['x-xrds-location']))); - $next = true; - } - - if (isset($headers['content-type']) - && (strpos($headers['content-type'], 'application/xrds+xml') !== false - || strpos($headers['content-type'], 'text/xml') !== false) - ) { - # Apparently, some providers return XRDS documents as text/html. - # While it is against the spec, allowing this here shouldn't break - # compatibility with anything. - # --- - # Found an XRDS document, now let's find the server, and optionally delegate. - $content = $this->request($url, 'GET'); - - preg_match_all('#<Service.*?>(.*?)</Service>#s', $content, $m); - foreach($m[1] as $content) { - $content = ' ' . $content; # The space is added, so that strpos doesn't return 0. - - # OpenID 2 - $ns = preg_quote('http://specs.openid.net/auth/2.0/'); - if(preg_match('#<Type>\s*'.$ns.'(server|signon)\s*</Type>#s', $content, $type)) { - if ($type[1] == 'server') $this->identifier_select = true; - - preg_match('#<URI.*?>(.*)</URI>#', $content, $server); - preg_match('#<(Local|Canonical)ID>(.*)</\1ID>#', $content, $delegate); - if (empty($server)) { - return false; - } - # Does the server advertise support for either AX or SREG? - $this->ax = (bool) strpos($content, '<Type>http://openid.net/srv/ax/1.0</Type>'); - $this->sreg = strpos($content, '<Type>http://openid.net/sreg/1.0</Type>') - || strpos($content, '<Type>http://openid.net/extensions/sreg/1.1</Type>'); - - $server = $server[1]; - if (isset($delegate[2])) $this->identity = trim($delegate[2]); - $this->version = 2; - - $this->server = $server; - return $server; - } - - # OpenID 1.1 - $ns = preg_quote('http://openid.net/signon/1.1'); - if (preg_match('#<Type>\s*'.$ns.'\s*</Type>#s', $content)) { - - preg_match('#<URI.*?>(.*)</URI>#', $content, $server); - preg_match('#<.*?Delegate>(.*)</.*?Delegate>#', $content, $delegate); - if (empty($server)) { - return false; - } - # AX can be used only with OpenID 2.0, so checking only SREG - $this->sreg = strpos($content, '<Type>http://openid.net/sreg/1.0</Type>') - || strpos($content, '<Type>http://openid.net/extensions/sreg/1.1</Type>'); - - $server = $server[1]; - if (isset($delegate[1])) $this->identity = $delegate[1]; - $this->version = 1; - - $this->server = $server; - return $server; - } - } - - $next = true; - $yadis = false; - $url = $originalUrl; - $content = null; - break; - } - if ($next) continue; - - # There are no relevant information in headers, so we search the body. - $content = $this->request($url, 'GET'); - $location = $this->htmlTag($content, 'meta', 'http-equiv', 'X-XRDS-Location', 'content'); - if ($location) { - $url = $this->build_url(parse_url($url), parse_url($location)); - continue; - } - } - - if (!$content) $content = $this->request($url, 'GET'); - - # At this point, the YADIS Discovery has failed, so we'll switch - # to openid2 HTML discovery, then fallback to openid 1.1 discovery. - $server = $this->htmlTag($content, 'link', 'rel', 'openid2.provider', 'href'); - $delegate = $this->htmlTag($content, 'link', 'rel', 'openid2.local_id', 'href'); - $this->version = 2; - - if (!$server) { - # The same with openid 1.1 - $server = $this->htmlTag($content, 'link', 'rel', 'openid.server', 'href'); - $delegate = $this->htmlTag($content, 'link', 'rel', 'openid.delegate', 'href'); - $this->version = 1; - } - - if ($server) { - # We found an OpenID2 OP Endpoint - if ($delegate) { - # We have also found an OP-Local ID. - $this->identity = $delegate; - } - $this->server = $server; - return $server; - } - - throw new ErrorException("No OpenID Server found at $url", 404); - } - throw new ErrorException('Endless redirection!', 500); - } - - protected function sregParams() - { - $params = array(); - # We always use SREG 1.1, even if the server is advertising only support for 1.0. - # That's because it's fully backwards compatibile with 1.0, and some providers - # advertise 1.0 even if they accept only 1.1. One such provider is myopenid.com - $params['openid.ns.sreg'] = 'http://openid.net/extensions/sreg/1.1'; - if ($this->required) { - $params['openid.sreg.required'] = array(); - foreach ($this->required as $required) { - if (!isset(self::$ax_to_sreg[$required])) continue; - $params['openid.sreg.required'][] = self::$ax_to_sreg[$required]; - } - $params['openid.sreg.required'] = implode(',', $params['openid.sreg.required']); - } - - if ($this->optional) { - $params['openid.sreg.optional'] = array(); - foreach ($this->optional as $optional) { - if (!isset(self::$ax_to_sreg[$optional])) continue; - $params['openid.sreg.optional'][] = self::$ax_to_sreg[$optional]; - } - $params['openid.sreg.optional'] = implode(',', $params['openid.sreg.optional']); - } - return $params; - } - - protected function axParams() - { - $params = array(); - if ($this->required || $this->optional) { - $params['openid.ns.ax'] = 'http://openid.net/srv/ax/1.0'; - $params['openid.ax.mode'] = 'fetch_request'; - $this->aliases = array(); - $counts = array(); - $required = array(); - $optional = array(); - foreach (array('required','optional') as $type) { - foreach ($this->$type as $alias => $field) { - if (is_int($alias)) $alias = strtr($field, '/', '_'); - $this->aliases[$alias] = 'http://axschema.org/' . $field; - if (empty($counts[$alias])) $counts[$alias] = 0; - $counts[$alias] += 1; - ${$type}[] = $alias; - } - } - foreach ($this->aliases as $alias => $ns) { - $params['openid.ax.type.' . $alias] = $ns; - } - foreach ($counts as $alias => $count) { - if ($count == 1) continue; - $params['openid.ax.count.' . $alias] = $count; - } - - # Don't send empty ax.requied and ax.if_available. - # Google and possibly other providers refuse to support ax when one of these is empty. - if($required) { - $params['openid.ax.required'] = implode(',', $required); - } - if($optional) { - $params['openid.ax.if_available'] = implode(',', $optional); - } - } - return $params; - } - - protected function authUrl_v1($immediate) - { - $returnUrl = $this->returnUrl; - # If we have an openid.delegate that is different from our claimed id, - # we need to somehow preserve the claimed id between requests. - # The simplest way is to just send it along with the return_to url. - if($this->identity != $this->claimed_id) { - $returnUrl .= (strpos($returnUrl, '?') ? '&' : '?') . 'openid.claimed_id=' . $this->claimed_id; - } - - $params = array( - 'openid.return_to' => $returnUrl, - 'openid.mode' => $immediate ? 'checkid_immediate' : 'checkid_setup', - 'openid.identity' => $this->identity, - 'openid.trust_root' => $this->trustRoot, - ) + $this->sregParams(); - - return $this->build_url(parse_url($this->server) - , array('query' => http_build_query($params, '', '&'))); - } - - protected function authUrl_v2($immediate) - { - $params = array( - 'openid.ns' => 'http://specs.openid.net/auth/2.0', - 'openid.mode' => $immediate ? 'checkid_immediate' : 'checkid_setup', - 'openid.return_to' => $this->returnUrl, - 'openid.realm' => $this->trustRoot, - ); - if ($this->ax) { - $params += $this->axParams(); - } - if ($this->sreg) { - $params += $this->sregParams(); - } - if (!$this->ax && !$this->sreg) { - # If OP doesn't advertise either SREG, nor AX, let's send them both - # in worst case we don't get anything in return. - $params += $this->axParams() + $this->sregParams(); - } - - if ($this->identifier_select) { - $params['openid.identity'] = $params['openid.claimed_id'] - = 'http://specs.openid.net/auth/2.0/identifier_select'; - } else { - $params['openid.identity'] = $this->identity; - $params['openid.claimed_id'] = $this->claimed_id; - } - - return $this->build_url(parse_url($this->server) - , array('query' => http_build_query($params, '', '&'))); - } - - /** - * Returns authentication url. Usually, you want to redirect your user to it. - * @return String The authentication url. - * @param String $select_identifier Whether to request OP to select identity for an user in OpenID 2. Does not affect OpenID 1. - * @throws ErrorException - */ - function authUrl($immediate = false) - { - if ($this->setup_url && !$immediate) return $this->setup_url; - if (!$this->server) $this->discover($this->identity); - - if ($this->version == 2) { - return $this->authUrl_v2($immediate); - } - return $this->authUrl_v1($immediate); - } - - /** - * Performs OpenID verification with the OP. - * @return Bool Whether the verification was successful. - * @throws ErrorException - */ - function validate() - { - # If the request was using immediate mode, a failure may be reported - # by presenting user_setup_url (for 1.1) or reporting - # mode 'setup_needed' (for 2.0). Also catching all modes other than - # id_res, in order to avoid throwing errors. - if(isset($this->data['openid_user_setup_url'])) { - $this->setup_url = $this->data['openid_user_setup_url']; - return false; - } - if($this->mode != 'id_res') { - return false; - } - - $this->claimed_id = isset($this->data['openid_claimed_id'])?$this->data['openid_claimed_id']:$this->data['openid_identity']; - $params = array( - 'openid.assoc_handle' => $this->data['openid_assoc_handle'], - 'openid.signed' => $this->data['openid_signed'], - 'openid.sig' => $this->data['openid_sig'], - ); - - if (isset($this->data['openid_ns'])) { - # We're dealing with an OpenID 2.0 server, so let's set an ns - # Even though we should know location of the endpoint, - # we still need to verify it by discovery, so $server is not set here - $params['openid.ns'] = 'http://specs.openid.net/auth/2.0'; - } elseif (isset($this->data['openid_claimed_id']) - && $this->data['openid_claimed_id'] != $this->data['openid_identity'] - ) { - # If it's an OpenID 1 provider, and we've got claimed_id, - # we have to append it to the returnUrl, like authUrl_v1 does. - $this->returnUrl .= (strpos($this->returnUrl, '?') ? '&' : '?') - . 'openid.claimed_id=' . $this->claimed_id; - } - - if ($this->data['openid_return_to'] != $this->returnUrl) { - # The return_to url must match the url of current request. - # I'm assuing that noone will set the returnUrl to something that doesn't make sense. - return false; - } - - $server = $this->discover($this->claimed_id); - - foreach (explode(',', $this->data['openid_signed']) as $item) { - # Checking whether magic_quotes_gpc is turned on, because - # the function may fail if it is. For example, when fetching - # AX namePerson, it might containg an apostrophe, which will be escaped. - # In such case, validation would fail, since we'd send different data than OP - # wants to verify. stripslashes() should solve that problem, but we can't - # use it when magic_quotes is off. - $value = $this->data['openid_' . str_replace('.','_',$item)]; - $params['openid.' . $item] = get_magic_quotes_gpc() ? stripslashes($value) : $value; - - } - - $params['openid.mode'] = 'check_authentication'; - - $response = $this->request($server, 'POST', $params); - - return preg_match('/is_valid\s*:\s*true/i', $response); - } - - protected function getAxAttributes() - { - $alias = null; - if (isset($this->data['openid_ns_ax']) - && $this->data['openid_ns_ax'] != 'http://openid.net/srv/ax/1.0' - ) { # It's the most likely case, so we'll check it before - $alias = 'ax'; - } else { - # 'ax' prefix is either undefined, or points to another extension, - # so we search for another prefix - foreach ($this->data as $key => $val) { - if (substr($key, 0, strlen('openid_ns_')) == 'openid_ns_' - && $val == 'http://openid.net/srv/ax/1.0' - ) { - $alias = substr($key, strlen('openid_ns_')); - break; - } - } - } - if (!$alias) { - # An alias for AX schema has not been found, - # so there is no AX data in the OP's response - return array(); - } - - $attributes = array(); - foreach (explode(',', $this->data['openid_signed']) as $key) { - $keyMatch = $alias . '.value.'; - if (substr($key, 0, strlen($keyMatch)) != $keyMatch) { - continue; - } - $key = substr($key, strlen($keyMatch)); - if (!isset($this->data['openid_' . $alias . '_type_' . $key])) { - # OP is breaking the spec by returning a field without - # associated ns. This shouldn't happen, but it's better - # to check, than cause an E_NOTICE. - continue; - } - $value = $this->data['openid_' . $alias . '_value_' . $key]; - $key = substr($this->data['openid_' . $alias . '_type_' . $key], - strlen('http://axschema.org/')); - - $attributes[$key] = $value; - } - return $attributes; - } - - protected function getSregAttributes() - { - $attributes = array(); - $sreg_to_ax = array_flip(self::$ax_to_sreg); - foreach (explode(',', $this->data['openid_signed']) as $key) { - $keyMatch = 'sreg.'; - if (substr($key, 0, strlen($keyMatch)) != $keyMatch) { - continue; - } - $key = substr($key, strlen($keyMatch)); - if (!isset($sreg_to_ax[$key])) { - # The field name isn't part of the SREG spec, so we ignore it. - continue; - } - $attributes[$sreg_to_ax[$key]] = $this->data['openid_sreg_' . $key]; - } - return $attributes; - } - - /** - * Gets AX/SREG attributes provided by OP. should be used only after successful validaton. - * Note that it does not guarantee that any of the required/optional parameters will be present, - * or that there will be no other attributes besides those specified. - * In other words. OP may provide whatever information it wants to. - * * SREG names will be mapped to AX names. - * * @return Array Array of attributes with keys being the AX schema names, e.g. 'contact/email' - * @see http://www.axschema.org/types/ - */ - function getAttributes() - { - if (isset($this->data['openid_ns']) - && $this->data['openid_ns'] == 'http://specs.openid.net/auth/2.0' - ) { # OpenID 2.0 - # We search for both AX and SREG attributes, with AX taking precedence. - return $this->getAxAttributes() + $this->getSregAttributes(); - } - return $this->getSregAttributes(); - } -} diff --git a/library/openid/provider/example-mysql.php b/library/openid/provider/example-mysql.php deleted file mode 100644 index 574e3c811..000000000 --- a/library/openid/provider/example-mysql.php +++ /dev/null @@ -1,194 +0,0 @@ -<?php -/** - * This example shows several things: - * - How a setup interface should look like. - * - How to use a mysql table for authentication - * - How to store associations in mysql table, instead of php sessions. - * - How to store realm authorizations. - * - How to send AX/SREG parameters. - * For the example to work, you need to create the necessary tables: -CREATE TABLE Users ( - id INT NOT NULL auto_increment PRIMARY KEY, - login VARCHAR(32) NOT NULL, - password CHAR(40) NOT NULL, - firstName VARCHAR(32) NOT NULL, - lastName VARCHAR(32) NOT NULL -); - -CREATE TABLE AllowedSites ( - user INT NOT NULL, - realm TEXT NOT NULL, - attributes TEXT NOT NULL, - INDEX(user) -); - -CREATE TABLE Associations ( - id INT NOT NULL PRIMARY KEY, - data TEXT NOT NULL -); - * - * This is only an example. Don't use it in your code as-is. - * It has several security flaws, which you shouldn't copy (like storing plaintext login and password in forms). - * - * This setup could be very easily flooded with many associations, - * since non-private ones aren't automatically deleted. - * You could prevent this by storing a date of association and removing old ones, - * or by setting $this->dh = false; - * However, the latter one would disable stateful mode, unless connecting via HTTPS. - */ -require 'provider.php'; - -mysql_connect(); -mysql_select_db('test'); - -function getUserData($handle=null) -{ - if(isset($_POST['login'],$_POST['password'])) { - $login = mysql_real_escape_string($_POST['login']); - $password = sha1($_POST['password']); - $q = mysql_query("SELECT * FROM Users WHERE login = '$login' AND password = '$password'"); - if($data = mysql_fetch_assoc($q)) { - return $data; - } - if($handle) { - echo 'Wrong login/password.'; - } - } - if($handle) { - ?> - <form action="" method="post"> - <input type="hidden" name="openid.assoc_handle" value="<?php echo $handle?>"> - Login: <input type="text" name="login"><br> - Password: <input type="password" name="password"><br> - <button>Submit</button> - </form> - <?php - die(); - } -} - -class MysqlProvider extends LightOpenIDProvider -{ - private $attrMap = array( - 'namePerson/first' => 'First name', - 'namePerson/last' => 'Last name', - 'namePerson/friendly' => 'Nickname (login)' - ); - - private $attrFieldMap = array( - 'namePerson/first' => 'firstName', - 'namePerson/last' => 'lastName', - 'namePerson/friendly' => 'login' - ); - - function setup($identity, $realm, $assoc_handle, $attributes) - { - $data = getUserData($assoc_handle); - echo '<form action="" method="post">' - . '<input type="hidden" name="openid.assoc_handle" value="' . $assoc_handle . '">' - . '<input type="hidden" name="login" value="' . $_POST['login'] .'">' - . '<input type="hidden" name="password" value="' . $_POST['password'] .'">' - . "<b>$realm</b> wishes to authenticate you."; - if($attributes['required'] || $attributes['optional']) { - echo " It also requests following information (required fields marked with *):" - . '<ul>'; - - foreach($attributes['required'] as $attr) { - if(isset($this->attrMap[$attr])) { - echo '<li>' - . '<input type="checkbox" name="attributes[' . $attr . ']"> ' - . $this->attrMap[$attr] . '(*)</li>'; - } - } - - foreach($attributes['optional'] as $attr) { - if(isset($this->attrMap[$attr])) { - echo '<li>' - . '<input type="checkbox" name="attributes[' . $attr . ']"> ' - . $this->attrMap[$attr] . '</li>'; - } - } - echo '</ul>'; - } - echo '<br>' - . '<button name="once">Allow once</button> ' - . '<button name="always">Always allow</button> ' - . '<button name="cancel">cancel</button> ' - . '</form>'; - } - - function checkid($realm, &$attributes) - { - if(isset($_POST['cancel'])) { - $this->cancel(); - } - - $data = getUserData(); - if(!$data) { - return false; - } - $realm = mysql_real_escape_string($realm); - $q = mysql_query("SELECT attributes FROM AllowedSites WHERE user = '{$data['id']}' AND realm = '$realm'"); - - $attrs = array(); - if($attrs = mysql_fetch_row($q)) { - $attrs = explode(',', $attributes[0]); - } elseif(isset($_POST['attributes'])) { - $attrs = array_keys($_POST['attributes']); - } elseif(!isset($_POST['once']) && !isset($_POST['always'])) { - return false; - } - - $attributes = array(); - foreach($attrs as $attr) { - if(isset($this->attrFieldMap[$attr])) { - $attributes[$attr] = $data[$this->attrFieldMap[$attr]]; - } - } - - if(isset($_POST['always'])) { - $attrs = mysql_real_escape_string(implode(',', array_keys($attributes))); - mysql_query("REPLACE INTO AllowedSites VALUES('{$data['id']}', '$realm', '$attrs')"); - } - - return $this->serverLocation . '?' . $data['login']; - } - - function assoc_handle() - { - # We generate an integer assoc handle, because it's just faster to look up an integer later. - $q = mysql_query("SELECT MAX(id) FROM Associations"); - $result = mysql_fetch_row($q); - return $q[0]+1; - } - - function setAssoc($handle, $data) - { - $data = mysql_real_escape_string(serialize($data)); - mysql_query("REPLACE INTO Associations VALUES('$handle', '$data')"); - } - - function getAssoc($handle) - { - if(!is_numeric($handle)) { - return false; - } - $q = mysql_query("SELECT data FROM Associations WHERE id = '$handle'"); - $data = mysql_fetch_row($q); - if(!$data) { - return false; - } - return unserialize($data[0]); - } - - function delAssoc($handle) - { - if(!is_numeric($handle)) { - return false; - } - mysql_query("DELETE FROM Associations WHERE id = '$handle'"); - } - -} -$op = new MysqlProvider; -$op->server(); diff --git a/library/openid/provider/example.php b/library/openid/provider/example.php deleted file mode 100644 index b8a4c24a9..000000000 --- a/library/openid/provider/example.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php -/** - * This example shows how to create a basic provider usin HTTP Authentication. - * This is only an example. You shouldn't use it as-is in your code. - */ -require 'provider.php'; - -class BasicProvider extends LightOpenIDProvider -{ - public $select_id = true; - public $login = ''; - public $password = ''; - - function __construct() - { - parent::__construct(); - - # If we use select_id, we must disable it for identity pages, - # so that an RP can discover it and get proper data (i.e. without select_id) - if(isset($_GET['id'])) { - $this->select_id = false; - } - } - - function setup($identity, $realm, $assoc_handle, $attributes) - { - header('WWW-Authenticate: Basic realm="' . $this->data['openid_realm'] . '"'); - header('HTTP/1.0 401 Unauthorized'); - } - - function checkid($realm, &$attributes) - { - if(!isset($_SERVER['PHP_AUTH_USER'])) { - return false; - } - - if ($_SERVER['PHP_AUTH_USER'] == $this->login - && $_SERVER['PHP_AUTH_PW'] == $this->password - ) { - # Returning identity - # It can be any url that leads here, or to any other place that hosts - # an XRDS document pointing here. - return $this->serverLocation . '?id=' . $this->login; - } - - return false; - } - -} -$op = new BasicProvider; -$op->login = 'test'; -$op->password = 'test'; -$op->server(); diff --git a/library/openid/provider/provider.php b/library/openid/provider/provider.php deleted file mode 100644 index a1a98d70b..000000000 --- a/library/openid/provider/provider.php +++ /dev/null @@ -1,845 +0,0 @@ -<?php -/** - * Using this class, you can easily set up an OpenID Provider. - * It's independent of LightOpenID class. - * It requires either GMP or BCMath for session encryption, - * but will work without them (although either via SSL, or in stateless mode only). - * Also, it requires PHP >= 5.1.2 - * - * This is an alpha version, using it in production code is not recommended, - * until you are *sure* that it works and is secure. - * - * Please send me messages about your testing results - * (even if successful, so I know that it has been tested). - * Also, if you think there's a way to make it easier to use, tell me -- it's an alpha for a reason. - * Same thing applies to bugs in code, suggestions, - * and everything else you'd like to say about the library. - * - * There's no usage documentation here, see the examples. - * - * @author Mewp - * @copyright Copyright (c) 2010, Mewp - * @license http://www.opensource.org/licenses/mit-license.php MIT - */ -//ini_set('error_log','log'); -abstract class LightOpenIDProvider -{ - # URL-s to XRDS and server location. - public $xrdsLocation, $serverLocation; - - # Should we operate in server, or signon mode? - public $select_id = false; - - # Lifetime of an association. - protected $assoc_lifetime = 600; - - # Variables below are either set automatically, or are constant. - # ----- - # Can we support DH? - protected $dh = true; - protected $ns = 'http://specs.openid.net/auth/2.0'; - protected $data, $assoc; - - # Default DH parameters as defined in the specification. - protected $default_modulus; - protected $default_gen = 'Ag=='; - - # AX <-> SREG transform - protected $ax_to_sreg = array( - 'namePerson/friendly' => 'nickname', - 'contact/email' => 'email', - 'namePerson' => 'fullname', - 'birthDate' => 'dob', - 'person/gender' => 'gender', - 'contact/postalCode/home' => 'postcode', - 'contact/country/home' => 'country', - 'pref/language' => 'language', - 'pref/timezone' => 'timezone', - ); - - # Math - private $add, $mul, $pow, $mod, $div, $powmod; - # ----- - - # ------------------------------------------------------------------------ # - # Functions you probably want to implement when extending the class. - - /** - * Checks whether an user is authenticated. - * The function should determine what fields it wants to send to the RP, - * and put them in the $attributes array. - * @param Array $attributes - * @param String $realm Realm used for authentication. - * @return String OP-local identifier of an authenticated user, or an empty value. - */ - abstract function checkid($realm, &$attributes); - - /** - * Displays an user interface for inputting user's login and password. - * Attributes are always AX field namespaces, with stripped host part. - * For example, the $attributes array may be: - * array( 'required' => array('namePerson/friendly', 'contact/email'), - * 'optional' => array('pref/timezone', 'pref/language') - * @param String $identity Discovered identity string. May be used to extract login, unless using $this->select_id - * @param String $realm Realm used for authentication. - * @param String Association handle. must be sent as openid.assoc_handle in $_GET or $_POST in subsequent requests. - * @param Array User attributes requested by the RP. - */ - abstract function setup($identity, $realm, $assoc_handle, $attributes); - - /** - * Stores an association. - * If you want to use php sessions in your provider code, you have to replace it. - * @param String $handle Association handle -- should be used as a key. - * @param Array $assoc Association data. - */ - protected function setAssoc($handle, $assoc) - { - $oldSession = session_id(); - session_commit(); - session_id($assoc['handle']); - session_start(); - $_SESSION['assoc'] = $assoc; - session_commit(); - if($oldSession) { - session_id($oldSession); - session_start(); - } - } - - /** - * Retreives association data. - * If you want to use php sessions in your provider code, you have to replace it. - * @param String $handle Association handle. - * @return Array Association data. - */ - protected function getAssoc($handle) - { - $oldSession = session_id(); - session_commit(); - session_id($handle); - session_start(); - if(empty($_SESSION['assoc'])) { - return null; - } - return $_SESSION['assoc']; - session_commit(); - if($oldSession) { - session_id($oldSession); - session_start(); - } - } - - /** - * Deletes an association. - * If you want to use php sessions in your provider code, you have to replace it. - * @param String $handle Association handle. - */ - protected function delAssoc($handle) - { - $oldSession = session_id(); - session_commit(); - session_id($handle); - session_start(); - session_destroy(); - if($oldSession) { - session_id($oldSession); - session_start(); - } - } - - # ------------------------------------------------------------------------ # - # Functions that you might want to implement. - - /** - * Redirects the user to an url. - * @param String $location The url that the user will be redirected to. - */ - protected function redirect($location) - { - header('Location: ' . $location); - die(); - } - - /** - * Generates a new association handle. - * @return string - */ - protected function assoc_handle() - { - return sha1(microtime()); - } - - /** - * Generates a random shared secret. - * @return string - */ - protected function shared_secret($hash) - { - $length = 20; - if($hash == 'sha256') { - $length = 256; - } - - $secret = ''; - for($i = 0; $i < $length; $i++) { - $secret .= mt_rand(0,255); - } - - return $secret; - } - - /** - * Generates a private key. - * @param int $length Length of the key. - */ - protected function keygen($length) - { - $key = ''; - for($i = 1; $i < $length; $i++) { - $key .= mt_rand(0,9); - } - $key .= mt_rand(1,9); - - return $key; - } - - # ------------------------------------------------------------------------ # - # Functions that you probably shouldn't touch. - - function __construct() - { - $this->default_modulus = - 'ANz5OguIOXLsDhmYmsWizjEOHTdxfo2Vcbt2I3MYZuYe91ouJ4mLBX+YkcLiemOcPy' - . 'm2CBRYHNOyyjmG0mg3BVd9RcLn5S3IHHoXGHblzqdLFEi/368Ygo79JRnxTkXjgmY0' - . 'rxlJ5bU1zIKaSDuKdiI+XUkKJX8Fvf8W8vsixYOr'; - - $location = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' - . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; - $location = preg_replace('/\?.*/','',$location); - $this->serverLocation = $location; - $location .= (strpos($location, '?') ? '&' : '?') . 'xrds'; - $this->xrdsLocation = $location; - - $this->data = $_GET + $_POST; - - # We choose GMP if avaiable, and bcmath otherwise - if(function_exists('gmp_add')) { - $this->add = 'gmp_add'; - $this->mul = 'gmp_mul'; - $this->pow = 'gmp_pow'; - $this->mod = 'gmp_mod'; - $this->div = 'gmp_div'; - $this->powmod = 'gmp_powm'; - } elseif(function_exists('bcadd')) { - $this->add = 'bcadd'; - $this->mul = 'bcmul'; - $this->pow = 'bcpow'; - $this->mod = 'bcmod'; - $this->div = 'bcdiv'; - $this->powmod = 'bcpowmod'; - } else { - # If neither are avaiable, we can't use DH - $this->dh = false; - } - - # However, we do require the hash functions. - # They should be built-in anyway. - if(!function_exists('hash_algos')) { - $this->dh = false; - } - } - - /** - * Displays an XRDS document, or redirects to it. - * By default, it detects whether it should display or redirect automatically. - * @param bool|null $force When true, always display the document, when false always redirect. - */ - function xrds($force=null) - { - if($force) { - echo $this->xrdsContent(); - die(); - } elseif($force === false) { - header('X-XRDS-Location: '. $this->xrdsLocation); - return; - } - - if (isset($_GET['xrds']) - || (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'application/xrds+xml') !== false) - ) { - header('Content-Type: application/xrds+xml'); - echo $this->xrdsContent(); - die(); - } - - header('X-XRDS-Location: ' . $this->xrdsLocation); - } - - /** - * Returns the content of the XRDS document - * @return String The XRDS document. - */ - protected function xrdsContent() - { - $lines = array( - '<?xml version="1.0" encoding="UTF-8"?>', - '<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">', - '<XRD>', - ' <Service>', - ' <Type>' . $this->ns . '/' . ($this->select_id ? 'server' : 'signon') .'</Type>', - ' <URI>' . $this->serverLocation . '</URI>', - ' </Service>', - '</XRD>', - '</xrds:XRDS>' - ); - return implode("\n", $lines); - } - - /** - * Does everything that a provider has to -- in one function. - */ - function server() - { - if(isset($this->data['openid_assoc_handle'])) { - $this->assoc = $this->getAssoc($this->data['openid_assoc_handle']); - if(isset($this->assoc['data'])) { - # We have additional data stored for setup. - $this->data += $this->assoc['data']; - unset($this->assoc['data']); - } - } - - if (isset($this->data['openid_ns']) - && $this->data['openid_ns'] == $this->ns - ) { - if(!isset($this->data['openid_mode'])) $this->errorResponse(); - - switch($this->data['openid_mode']) - { - case 'checkid_immediate': - case 'checkid_setup': - $this->checkRealm(); - # We support AX xor SREG. - $attributes = $this->ax(); - if(!$attributes) { - $attributes = $this->sreg(); - } - - # Even if some user is authenticated, we need to know if it's - # the same one that want's to authenticate. - # Of course, if we use select_id, we accept any user. - if (($identity = $this->checkid($this->data['openid_realm'], $attrValues)) - && ($this->select_id || $identity == $this->data['openid_identity']) - ) { - $this->positiveResponse($identity, $attrValues); - } elseif($this->data['openid_mode'] == 'checkid_immediate') { - $this->redirect($this->response(array('openid.mode' => 'setup_needed'))); - } else { - if(!$this->assoc) { - $this->generateAssociation(); - $this->assoc['private'] = true; - } - $this->assoc['data'] = $this->data; - $this->setAssoc($this->assoc['handle'], $this->assoc); - $this->setup($this->data['openid_identity'], - $this->data['openid_realm'], - $this->assoc['handle'], - $attributes); - } - break; - case 'associate': - $this->associate(); - break; - case 'check_authentication': - $this->checkRealm(); - if($this->verify()) { - echo "ns:$this->ns\nis_valid:true"; - if(strpos($this->data['openid_signed'],'invalidate_handle') !== false) { - echo "\ninvalidate_handle:" . $this->data['openid_invalidate_handle']; - } - } else { - echo "ns:$this->ns\nis_valid:false"; - } - die(); - break; - default: - $this->errorResponse(); - } - } else { - $this->xrds(); - } - } - - protected function checkRealm() - { - if (!isset($this->data['openid_return_to'], $this->data['openid_realm'])) { - $this->errorResponse(); - } - - $realm = str_replace('\*', '[^/]', preg_quote($this->data['openid_realm'])); - if(!preg_match("#^$realm#", $this->data['openid_return_to'])) { - $this->errorResponse(); - } - } - - protected function ax() - { - # Namespace prefix that the fields must have. - $ns = 'http://axschema.org/'; - - # First, we must find out what alias is used for AX. - # Let's check the most likely one - $alias = null; - if (isset($this->data['openid_ns_ax']) - && $this->data['openid_ns_ax'] == 'http://openid.net/srv/ax/1.0' - ) { - $alias = 'ax'; - } else { - foreach($this->data as $name => $value) { - if ($value == 'http://openid.net/srv/ax/1.0' - && preg_match('/openid_ns_(.+)/', $name, $m) - ) { - $alias = $m[1]; - break; - } - } - } - - if(!$alias) { - return null; - } - - $fields = array(); - # Now, we must search again, this time for field aliases - foreach($this->data as $name => $value) { - if (strpos($name, 'openid_' . $alias . '_type') === false - || strpos($value, $ns) === false) { - continue; - } - - $name = substr($name, strlen('openid_' . $alias . '_type_')); - $value = substr($value, strlen($ns)); - - $fields[$name] = $value; - } - - # Then, we find out what fields are required and optional - $required = array(); - $if_available = array(); - foreach(array('required','if_available') as $type) { - if(empty($this->data["openid_{$alias}_{$type}"])) { - continue; - } - $attributes = explode(',', $this->data["openid_{$alias}_{$type}"]); - foreach($attributes as $attr) { - if(empty($fields[$attr])) { - # There is an undefined field here, so we ignore it. - continue; - } - - ${$type}[] = $fields[$attr]; - } - } - - $this->data['ax'] = true; - return array('required' => $required, 'optional' => $if_available); - } - - protected function sreg() - { - $sreg_to_ax = array_flip($this->ax_to_sreg); - - $attributes = array('required' => array(), 'optional' => array()); - - if (empty($this->data['openid_sreg_required']) - && empty($this->data['openid_sreg_optional']) - ) { - return $attributes; - } - - foreach(array('required', 'optional') as $type) { - foreach(explode(',',$this->data['openid_sreg_' . $type]) as $attr) { - if(empty($sreg_to_ax[$attr])) { - # Undefined attribute in SREG request. - # Shouldn't happen, but we check anyway. - continue; - } - - $attributes[$type][] = $sreg_to_ax[$attr]; - } - } - - return $attributes; - } - - /** - * Aids an RP in assertion verification. - * @return bool Information whether the verification suceeded. - */ - protected function verify() - { - # Firstly, we need to make sure that there's an association. - # Otherwise the verification will fail, - # because we've signed assoc_handle in the assertion - if(empty($this->assoc)) { - return false; - } - - # Next, we check that it's a private association, - # i.e. one made without RP input. - # Otherwise, the RP shouldn't ask us to verify. - if(empty($this->assoc['private'])) { - return false; - } - - # Now we have to check if the nonce is correct, to prevent replay attacks. - if($this->data['openid_response_nonce'] != $this->assoc['nonce']) { - return false; - } - - # Getting the signed fields for signature. - $sig = array(); - $signed = explode(',', $this->data['openid_signed']); - foreach($signed as $field) { - $name = strtr($field, '.', '_'); - if(!isset($this->data['openid_' . $name])) { - return false; - } - - $sig[$field] = $this->data['openid_' . $name]; - } - - # Computing the signature and checking if it matches. - $sig = $this->keyValueForm($sig); - if ($this->data['openid_sig'] != - base64_encode(hash_hmac($this->assoc['hash'], $sig, $this->assoc['mac'], true)) - ) { - return false; - } - - # Clearing the nonce, so that it won't be used again. - $this->assoc['nonce'] = null; - - if(empty($this->assoc['private'])) { - # Commiting changes to the association. - $this->setAssoc($this->assoc['handle'], $this->assoc); - } else { - # Private associations shouldn't be used again, se we can as well delete them. - $this->delAssoc($this->assoc['handle']); - } - - # Nothing has failed, so the verification was a success. - return true; - } - - /** - * Performs association with an RP. - */ - protected function associate() - { - # Rejecting no-encryption without TLS. - if(empty($_SERVER['HTTPS']) && $this->data['openid_session_type'] == 'no-encryption') { - $this->directErrorResponse(); - } - - # Checking whether we support DH at all. - if (!$this->dh && substr($this->data['openid_session_type'], 0, 2) == 'DH') { - $this->redirect($this->response(array( - 'openid.error' => 'DH not supported', - 'openid.error_code' => 'unsupported-type', - 'openid.session_type' => 'no-encryption' - ))); - } - - # Creating the association - $this->assoc = array(); - $this->assoc['hash'] = $this->data['openid_assoc_type'] == 'HMAC-SHA256' ? 'sha256' : 'sha1'; - $this->assoc['handle'] = $this->assoc_handle(); - - # Getting the shared secret - if($this->data['openid_session_type'] == 'no-encryption') { - $this->assoc['mac'] = base64_encode($this->shared_secret($this->assoc['hash'])); - } else { - $this->dh(); - } - - # Preparing the direct response... - $response = array( - 'ns' => $this->ns, - 'assoc_handle' => $this->assoc['handle'], - 'assoc_type' => $this->data['openid_assoc_type'], - 'session_type' => $this->data['openid_session_type'], - 'expires_in' => $this->assoc_lifetime - ); - - if(isset($this->assoc['dh_server_public'])) { - $response['dh_server_public'] = $this->assoc['dh_server_public']; - $response['enc_mac_key'] = $this->assoc['mac']; - } else { - $response['mac_key'] = $this->assoc['mac']; - } - - # ...and sending it. - echo $this->keyValueForm($response); - die(); - } - - /** - * Creates a private association. - */ - protected function generateAssociation() - { - $this->assoc = array(); - # We use sha1 by default. - $this->assoc['hash'] = 'sha1'; - $this->assoc['mac'] = $this->shared_secret('sha1'); - $this->assoc['handle'] = $this->assoc_handle(); - } - - /** - * Encrypts the MAC key using DH key exchange. - */ - protected function dh() - { - if(empty($this->data['openid_dh_modulus'])) { - $this->data['openid_dh_modulus'] = $this->default_modulus; - } - - if(empty($this->data['openid_dh_gen'])) { - $this->data['openid_dh_gen'] = $this->default_gen; - } - - if(empty($this->data['openid_dh_consumer_public'])) { - $this->directErrorResponse(); - } - - $modulus = $this->b64dec($this->data['openid_dh_modulus']); - $gen = $this->b64dec($this->data['openid_dh_gen']); - $consumerKey = $this->b64dec($this->data['openid_dh_consumer_public']); - - $privateKey = $this->keygen(strlen($modulus)); - $publicKey = $this->powmod($gen, $privateKey, $modulus); - $ss = $this->powmod($consumerKey, $privateKey, $modulus); - - $mac = $this->x_or(hash($this->assoc['hash'], $ss, true), $this->shared_secret($this->assoc['hash'])); - $this->assoc['dh_server_public'] = $this->decb64($publicKey); - $this->assoc['mac'] = base64_encode($mac); - } - - /** - * XORs two strings. - * @param String $a - * @param String $b - * @return String $a ^ $b - */ - protected function x_or($a, $b) - { - $length = strlen($a); - for($i = 0; $i < $length; $i++) { - $a[$i] = $a[$i] ^ $b[$i]; - } - - return $a; - } - - /** - * Prepares an indirect response url. - * @param array $params Parameters to be sent. - */ - protected function response($params) - { - $params += array('openid.ns' => $this->ns); - return $this->data['openid_return_to'] - . (strpos($this->data['openid_return_to'],'?') ? '&' : '?') - . http_build_query($params, '', '&'); - } - - /** - * Outputs a direct error. - */ - protected function errorResponse() - { - if(!empty($this->data['openid_return_to'])) { - $response = array( - 'openid.mode' => 'error', - 'openid.error' => 'Invalid request' - ); - $this->redirect($this->response($response)); - } else { - header('HTTP/1.1 400 Bad Request'); - $response = array( - 'ns' => $this->ns, - 'error' => 'Invalid request' - ); - echo $this->keyValueForm($response); - } - die(); - } - - /** - * Sends an positive assertion. - * @param String $identity the OP-Local Identifier that is being authenticated. - * @param Array $attributes User attributes to be sent. - */ - protected function positiveResponse($identity, $attributes) - { - # We generate a private association if there is none established. - if(!$this->assoc) { - $this->generateAssociation(); - $this->assoc['private'] = true; - } - - # We set openid.identity (and openid.claimed_id if necessary) to our $identity - if($this->data['openid_identity'] == $this->data['openid_claimed_id'] || $this->select_id) { - $this->data['openid_claimed_id'] = $identity; - } - $this->data['openid_identity'] = $identity; - - # Preparing fields to be signed - $params = array( - 'op_endpoint' => $this->serverLocation, - 'claimed_id' => $this->data['openid_claimed_id'], - 'identity' => $this->data['openid_identity'], - 'return_to' => $this->data['openid_return_to'], - 'realm' => $this->data['openid_realm'], - 'response_nonce' => gmdate("Y-m-d\TH:i:s\Z"), - 'assoc_handle' => $this->assoc['handle'], - ); - - $params += $this->responseAttributes($attributes); - - # Has the RP used an invalid association handle? - if (isset($this->data['openid_assoc_handle']) - && $this->data['openid_assoc_handle'] != $this->assoc['handle'] - ) { - $params['invalidate_handle'] = $this->data['openid_assoc_handle']; - } - - # Signing the $params - $sig = hash_hmac($this->assoc['hash'], $this->keyValueForm($params), $this->assoc['mac'], true); - $req = array( - 'openid.mode' => 'id_res', - 'openid.signed' => implode(',', array_keys($params)), - 'openid.sig' => base64_encode($sig), - ); - - # Saving the nonce and commiting the association. - $this->assoc['nonce'] = $params['response_nonce']; - $this->setAssoc($this->assoc['handle'], $this->assoc); - - # Preparing and sending the response itself - foreach($params as $name => $value) { - $req['openid.' . $name] = $value; - } - - $this->redirect($this->response($req)); - } - - /** - * Prepares an array of attributes to send - */ - protected function responseAttributes($attributes) - { - if(!$attributes) return array(); - - $ns = 'http://axschema.org/'; - - $response = array(); - if(isset($this->data['ax'])) { - $response['ns.ax'] = 'http://openid.net/srv/ax/1.0'; - foreach($attributes as $name => $value) { - $alias = strtr($name, '/', '_'); - $response['ax.type.' . $alias] = $ns . $name; - $response['ax.value.' . $alias] = $value; - } - return $response; - } - - foreach($attributes as $name => $value) { - if(!isset($this->ax_to_sreg[$name])) { - continue; - } - - $response['sreg.' . $this->ax_to_sreg[$name]] = $value; - } - return $response; - } - - /** - * Encodes fields in key-value form. - * @param Array $params Fields to be encoded. - * @return String $params in key-value form. - */ - protected function keyValueForm($params) - { - $str = ''; - foreach($params as $name => $value) { - $str .= "$name:$value\n"; - } - - return $str; - } - - /** - * Responds with an information that the user has canceled authentication. - */ - protected function cancel() - { - $this->redirect($this->response(array('openid.mode' => 'cancel'))); - } - - /** - * Converts base64 encoded number to it's decimal representation. - * @param String $str base64 encoded number. - * @return String Decimal representation of that number. - */ - protected function b64dec($str) - { - $bytes = unpack('C*', base64_decode($str)); - $n = 0; - foreach($bytes as $byte) { - $n = $this->add($this->mul($n, 256), $byte); - } - - return $n; - } - - /** - * Complements b64dec. - */ - protected function decb64($num) - { - $bytes = array(); - while($num) { - array_unshift($bytes, $this->mod($num, 256)); - $num = $this->div($num, 256); - } - - if($bytes && $bytes[0] > 127) { - array_unshift($bytes,0); - } - - array_unshift($bytes, 'C*'); - - return base64_encode(call_user_func_array('pack', $bytes)); - } - - function __call($name, $args) - { - switch($name) { - case 'add': - case 'mul': - case 'pow': - case 'mod': - case 'div': - case 'powmod': - if(function_exists('gmp_strval')) { - return gmp_strval(call_user_func_array($this->$name, $args)); - } - return call_user_func_array($this->$name, $args); - default: - throw new BadMethodCallException(); - } - } -} diff --git a/library/sticky-kit/sticky-kit.js b/library/sticky-kit/sticky-kit.js deleted file mode 100644 index 00b1ea2ff..000000000 --- a/library/sticky-kit/sticky-kit.js +++ /dev/null @@ -1,265 +0,0 @@ -// Generated by CoffeeScript 1.10.0 - -/** -@license Sticky-kit v1.1.3 | MIT | Leaf Corcoran 2015 | http://leafo.net - */ - -(function() { - var $, win; - - $ = window.jQuery; - - win = $(window); - - $.fn.stick_in_parent = function(opts) { - var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class; - if (opts == null) { - opts = {}; - } - sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, recalc_every = opts.recalc_every, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer, enable_bottoming = opts.bottoming; - if (offset_top == null) { - offset_top = 0; - } - if (parent_selector == null) { - parent_selector = void 0; - } - if (inner_scrolling == null) { - inner_scrolling = true; - } - if (sticky_class == null) { - sticky_class = "is_stuck"; - } - doc = $(document); - if (enable_bottoming == null) { - enable_bottoming = true; - } - outer_width = function(el) { - var _el, computed, w; - if (window.getComputedStyle) { - _el = el[0]; - computed = window.getComputedStyle(el[0]); - w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right")); - if (computed.getPropertyValue("box-sizing") !== "border-box") { - w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right")); - } - return w; - } else { - return el.outerWidth(true); - } - }; - fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) { - var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick; - if (elm.data("sticky_kit")) { - return; - } - elm.data("sticky_kit", true); - last_scroll_height = doc.height(); - parent = elm.parent(); - if (parent_selector != null) { - parent = parent.closest(parent_selector); - } - if (!parent.length) { - throw "failed to find stick parent"; - } - fixed = false; - bottomed = false; - spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />"); - if (spacer) { - spacer.css('position', elm.css('position')); - } - recalc = function() { - var border_top, padding_top, restore; - if (detached) { - return; - } - last_scroll_height = doc.height(); - border_top = parseInt(parent.css("border-top-width"), 10); - padding_top = parseInt(parent.css("padding-top"), 10); - padding_bottom = parseInt(parent.css("padding-bottom"), 10); - parent_top = parent.offset().top + border_top + padding_top; - parent_height = parent.height(); - if (fixed) { - fixed = false; - bottomed = false; - if (manual_spacer == null) { - elm.insertAfter(spacer); - spacer.detach(); - } - elm.css({ - position: "", - top: "", - width: "", - bottom: "" - }).removeClass(sticky_class); - restore = true; - } - top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top; - height = elm.outerHeight(true); - el_float = elm.css("float"); - if (spacer) { - spacer.css({ - width: outer_width(elm), - height: height, - display: elm.css("display"), - "vertical-align": elm.css("vertical-align"), - "float": el_float - }); - } - if (restore) { - return tick(); - } - }; - recalc(); - if (height === parent_height) { - return; - } - last_pos = void 0; - offset = offset_top; - recalc_counter = recalc_every; - tick = function() { - var css, delta, recalced, scroll, will_bottom, win_height; - if (detached) { - return; - } - recalced = false; - if (recalc_counter != null) { - recalc_counter -= 1; - if (recalc_counter <= 0) { - recalc_counter = recalc_every; - recalc(); - recalced = true; - } - } - if (!recalced && doc.height() !== last_scroll_height) { - recalc(); - recalced = true; - } - scroll = win.scrollTop(); - if (last_pos != null) { - delta = scroll - last_pos; - } - last_pos = scroll; - if (fixed) { - if (enable_bottoming) { - will_bottom = scroll + height + offset > parent_height + parent_top; - if (bottomed && !will_bottom) { - bottomed = false; - elm.css({ - position: "fixed", - bottom: "", - top: offset - }).trigger("sticky_kit:unbottom"); - } - } - if (scroll < top) { - fixed = false; - offset = offset_top; - if (manual_spacer == null) { - if (el_float === "left" || el_float === "right") { - elm.insertAfter(spacer); - } - spacer.detach(); - } - css = { - position: "", - width: "", - top: "" - }; - elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick"); - } - if (inner_scrolling) { - win_height = win.height(); - if (height + offset_top > win_height) { - if (!bottomed) { - offset -= delta; - offset = Math.max(win_height - height, offset); - offset = Math.min(offset_top, offset); - if (fixed) { - elm.css({ - top: offset + "px" - }); - } - } - } - } - } else { - if (scroll > top) { - fixed = true; - css = { - position: "fixed", - top: offset - }; - css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px"; - elm.css(css).addClass(sticky_class); - if (manual_spacer == null) { - elm.after(spacer); - if (el_float === "left" || el_float === "right") { - spacer.append(elm); - } - } - elm.trigger("sticky_kit:stick"); - } - } - if (fixed && enable_bottoming) { - if (will_bottom == null) { - will_bottom = scroll + height + offset > parent_height + parent_top; - } - if (!bottomed && will_bottom) { - bottomed = true; - if (parent.css("position") === "static") { - parent.css({ - position: "relative" - }); - } - return elm.css({ - position: "absolute", - bottom: padding_bottom, - top: "auto" - }).trigger("sticky_kit:bottom"); - } - } - }; - recalc_and_tick = function() { - recalc(); - return tick(); - }; - detach = function() { - detached = true; - win.off("touchmove", tick); - win.off("scroll", tick); - win.off("resize", recalc_and_tick); - $(document.body).off("sticky_kit:recalc", recalc_and_tick); - elm.off("sticky_kit:detach", detach); - elm.removeData("sticky_kit"); - elm.css({ - position: "", - bottom: "", - top: "", - width: "" - }); - parent.position("position", ""); - if (fixed) { - if (manual_spacer == null) { - if (el_float === "left" || el_float === "right") { - elm.insertAfter(spacer); - } - spacer.remove(); - } - return elm.removeClass(sticky_class); - } - }; - win.on("touchmove", tick); - win.on("scroll", tick); - win.on("resize", recalc_and_tick); - $(document.body).on("sticky_kit:recalc", recalc_and_tick); - elm.on("sticky_kit:detach", detach); - return setTimeout(tick, 0); - }; - for (i = 0, len = this.length; i < len; i++) { - elm = this[i]; - fn($(elm)); - } - return this; - }; - -}).call(this); diff --git a/library/sticky-kit/sticky-kit.min.js b/library/sticky-kit/sticky-kit.min.js deleted file mode 100644 index c4d7f2e3b..000000000 --- a/library/sticky-kit/sticky-kit.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - Sticky-kit v1.1.3 | MIT | Leaf Corcoran 2015 | http://leafo.net -*/ -(function(){var c,f;c=window.jQuery;f=c(window);c.fn.stick_in_parent=function(b){var A,w,J,n,B,K,p,q,L,k,E,t;null==b&&(b={});t=b.sticky_class;B=b.inner_scrolling;E=b.recalc_every;k=b.parent;q=b.offset_top;p=b.spacer;w=b.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=c(document);null==w&&(w=!0);L=function(a){var b;return window.getComputedStyle?(a=window.getComputedStyle(a[0]),b=parseFloat(a.getPropertyValue("width"))+parseFloat(a.getPropertyValue("margin-left"))+ -parseFloat(a.getPropertyValue("margin-right")),"border-box"!==a.getPropertyValue("box-sizing")&&(b+=parseFloat(a.getPropertyValue("border-left-width"))+parseFloat(a.getPropertyValue("border-right-width"))+parseFloat(a.getPropertyValue("padding-left"))+parseFloat(a.getPropertyValue("padding-right"))),b):a.outerWidth(!0)};J=function(a,b,n,C,F,u,r,G){var v,H,m,D,I,d,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k));if(!g.length)throw"failed to find stick parent"; -v=m=!1;(h=null!=p?p&&a.closest(p):c("<div />"))&&h.css("position",a.css("position"));x=function(){var d,f,e;if(!G&&(I=A.height(),d=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),b=parseInt(g.css("padding-bottom"),10),n=g.offset().top+d+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q,u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:L(a), -height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,d=q,z=E,l=function(){var c,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+d>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:d}).trigger("sticky_kit:unbottom"))),e<F&&(m=!1,d=q,null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.detach()),c={position:"",width:"",top:""},a.css(c).removeClass(t).trigger("sticky_kit:unstick")), -B&&(c=f.height(),u+q>c&&!v&&(d-=l,d=Math.max(c-u,d),d=Math.min(q,d),m&&a.css({top:d+"px"})))):e>F&&(m=!0,c={position:"fixed",top:d},c.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(c).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+d>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}),a.css({position:"absolute",bottom:b,top:"auto"}).trigger("sticky_kit:bottom")}, -y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);c(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize",y),c(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l, -0)}};n=0;for(K=this.length;n<K;n++)b=this[n],J(c(b));return this}}).call(this); diff --git a/library/symfony/options-resolver/CHANGELOG.md b/library/symfony/options-resolver/CHANGELOG.md deleted file mode 100644 index 5f6d15b2c..000000000 --- a/library/symfony/options-resolver/CHANGELOG.md +++ /dev/null @@ -1,46 +0,0 @@ -CHANGELOG -========= - -2.6.0 ------ - - * deprecated OptionsResolverInterface - * [BC BREAK] removed "array" type hint from OptionsResolverInterface methods - setRequired(), setAllowedValues(), addAllowedValues(), setAllowedTypes() and - addAllowedTypes() - * added OptionsResolver::setDefault() - * added OptionsResolver::hasDefault() - * added OptionsResolver::setNormalizer() - * added OptionsResolver::isRequired() - * added OptionsResolver::getRequiredOptions() - * added OptionsResolver::isMissing() - * added OptionsResolver::getMissingOptions() - * added OptionsResolver::setDefined() - * added OptionsResolver::isDefined() - * added OptionsResolver::getDefinedOptions() - * added OptionsResolver::remove() - * added OptionsResolver::clear() - * deprecated OptionsResolver::replaceDefaults() - * deprecated OptionsResolver::setOptional() in favor of setDefined() - * deprecated OptionsResolver::isKnown() in favor of isDefined() - * [BC BREAK] OptionsResolver::isRequired() returns true now if a required - option has a default value set - * [BC BREAK] merged Options into OptionsResolver and turned Options into an - interface - * deprecated Options::overload() (now in OptionsResolver) - * deprecated Options::set() (now in OptionsResolver) - * deprecated Options::get() (now in OptionsResolver) - * deprecated Options::has() (now in OptionsResolver) - * deprecated Options::replace() (now in OptionsResolver) - * [BC BREAK] Options::get() (now in OptionsResolver) can only be used within - lazy option/normalizer closures now - * [BC BREAK] removed Traversable interface from Options since using within - lazy option/normalizer closures resulted in exceptions - * [BC BREAK] removed Options::all() since using within lazy option/normalizer - closures resulted in exceptions - * [BC BREAK] OptionDefinitionException now extends LogicException instead of - RuntimeException - * [BC BREAK] normalizers are not executed anymore for unset options - * normalizers are executed after validating the options now - * [BC BREAK] an UndefinedOptionsException is now thrown instead of an - InvalidOptionsException when non-existing options are passed diff --git a/library/symfony/options-resolver/Exception/AccessException.php b/library/symfony/options-resolver/Exception/AccessException.php deleted file mode 100644 index c12b68064..000000000 --- a/library/symfony/options-resolver/Exception/AccessException.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Exception; - -/** - * Thrown when trying to read an option outside of or write it inside of - * {@link \Symfony\Component\OptionsResolver\Options::resolve()}. - * - * @author Bernhard Schussek <bschussek@gmail.com> - */ -class AccessException extends \LogicException implements ExceptionInterface -{ -} diff --git a/library/symfony/options-resolver/Exception/ExceptionInterface.php b/library/symfony/options-resolver/Exception/ExceptionInterface.php deleted file mode 100644 index b62bb51d4..000000000 --- a/library/symfony/options-resolver/Exception/ExceptionInterface.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Exception; - -/** - * Marker interface for all exceptions thrown by the OptionsResolver component. - * - * @author Bernhard Schussek <bschussek@gmail.com> - */ -interface ExceptionInterface -{ -} diff --git a/library/symfony/options-resolver/Exception/InvalidArgumentException.php b/library/symfony/options-resolver/Exception/InvalidArgumentException.php deleted file mode 100644 index 6d421d68b..000000000 --- a/library/symfony/options-resolver/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Exception; - -/** - * Thrown when an argument is invalid. - * - * @author Bernhard Schussek <bschussek@gmail.com> - */ -class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface -{ -} diff --git a/library/symfony/options-resolver/Exception/InvalidOptionsException.php b/library/symfony/options-resolver/Exception/InvalidOptionsException.php deleted file mode 100644 index 6fd4f125f..000000000 --- a/library/symfony/options-resolver/Exception/InvalidOptionsException.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Exception; - -/** - * Thrown when the value of an option does not match its validation rules. - * - * You should make sure a valid value is passed to the option. - * - * @author Bernhard Schussek <bschussek@gmail.com> - */ -class InvalidOptionsException extends InvalidArgumentException -{ -} diff --git a/library/symfony/options-resolver/Exception/MissingOptionsException.php b/library/symfony/options-resolver/Exception/MissingOptionsException.php deleted file mode 100644 index faa487f16..000000000 --- a/library/symfony/options-resolver/Exception/MissingOptionsException.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Exception; - -/** - * Exception thrown when a required option is missing. - * - * Add the option to the passed options array. - * - * @author Bernhard Schussek <bschussek@gmail.com> - */ -class MissingOptionsException extends InvalidArgumentException -{ -} diff --git a/library/symfony/options-resolver/Exception/NoSuchOptionException.php b/library/symfony/options-resolver/Exception/NoSuchOptionException.php deleted file mode 100644 index 4c3280f4c..000000000 --- a/library/symfony/options-resolver/Exception/NoSuchOptionException.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Exception; - -/** - * Thrown when trying to read an option that has no value set. - * - * When accessing optional options from within a lazy option or normalizer you should first - * check whether the optional option is set. You can do this with `isset($options['optional'])`. - * In contrast to the {@link UndefinedOptionsException}, this is a runtime exception that can - * occur when evaluating lazy options. - * - * @author Tobias Schultze <http://tobion.de> - */ -class NoSuchOptionException extends \OutOfBoundsException implements ExceptionInterface -{ -} diff --git a/library/symfony/options-resolver/Exception/OptionDefinitionException.php b/library/symfony/options-resolver/Exception/OptionDefinitionException.php deleted file mode 100644 index e8e339d44..000000000 --- a/library/symfony/options-resolver/Exception/OptionDefinitionException.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Exception; - -/** - * Thrown when two lazy options have a cyclic dependency. - * - * @author Bernhard Schussek <bschussek@gmail.com> - */ -class OptionDefinitionException extends \LogicException implements ExceptionInterface -{ -} diff --git a/library/symfony/options-resolver/Exception/UndefinedOptionsException.php b/library/symfony/options-resolver/Exception/UndefinedOptionsException.php deleted file mode 100644 index 6ca3fce47..000000000 --- a/library/symfony/options-resolver/Exception/UndefinedOptionsException.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Exception; - -/** - * Exception thrown when an undefined option is passed. - * - * You should remove the options in question from your code or define them - * beforehand. - * - * @author Bernhard Schussek <bschussek@gmail.com> - */ -class UndefinedOptionsException extends InvalidArgumentException -{ -} diff --git a/library/symfony/options-resolver/LICENSE b/library/symfony/options-resolver/LICENSE deleted file mode 100644 index 43028bc60..000000000 --- a/library/symfony/options-resolver/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2004-2015 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/library/symfony/options-resolver/Options.php b/library/symfony/options-resolver/Options.php deleted file mode 100644 index d444ec423..000000000 --- a/library/symfony/options-resolver/Options.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver; - -/** - * Contains resolved option values. - * - * @author Bernhard Schussek <bschussek@gmail.com> - * @author Tobias Schultze <http://tobion.de> - */ -interface Options extends \ArrayAccess, \Countable -{ -} diff --git a/library/symfony/options-resolver/OptionsResolver.php b/library/symfony/options-resolver/OptionsResolver.php deleted file mode 100644 index e0578af71..000000000 --- a/library/symfony/options-resolver/OptionsResolver.php +++ /dev/null @@ -1,1218 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver; - -use Symfony\Component\OptionsResolver\Exception\AccessException; -use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; -use Symfony\Component\OptionsResolver\Exception\MissingOptionsException; -use Symfony\Component\OptionsResolver\Exception\NoSuchOptionException; -use Symfony\Component\OptionsResolver\Exception\OptionDefinitionException; -use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; - -/** - * Validates options and merges them with default values. - * - * @author Bernhard Schussek <bschussek@gmail.com> - * @author Tobias Schultze <http://tobion.de> - */ -class OptionsResolver implements Options, OptionsResolverInterface -{ - /** - * The fully qualified name of the {@link Options} interface. - * - * @internal - */ - const OPTIONS_INTERFACE = 'Symfony\\Component\\OptionsResolver\\Options'; - - /** - * The names of all defined options. - * - * @var array - */ - private $defined = array(); - - /** - * The default option values. - * - * @var array - */ - private $defaults = array(); - - /** - * The names of required options. - * - * @var array - */ - private $required = array(); - - /** - * The resolved option values. - * - * @var array - */ - private $resolved = array(); - - /** - * A list of normalizer closures. - * - * @var \Closure[] - */ - private $normalizers = array(); - - /** - * A list of accepted values for each option. - * - * @var array - */ - private $allowedValues = array(); - - /** - * A list of accepted types for each option. - * - * @var array - */ - private $allowedTypes = array(); - - /** - * A list of closures for evaluating lazy options. - * - * @var array - */ - private $lazy = array(); - - /** - * A list of lazy options whose closure is currently being called. - * - * This list helps detecting circular dependencies between lazy options. - * - * @var array - */ - private $calling = array(); - - /** - * Whether the instance is locked for reading. - * - * Once locked, the options cannot be changed anymore. This is - * necessary in order to avoid inconsistencies during the resolving - * process. If any option is changed after being read, all evaluated - * lazy options that depend on this option would become invalid. - * - * @var bool - */ - private $locked = false; - - private static $typeAliases = array( - 'boolean' => 'bool', - 'integer' => 'int', - 'double' => 'float', - ); - - /** - * Sets the default value of a given option. - * - * If the default value should be set based on other options, you can pass - * a closure with the following signature: - * - * function (Options $options) { - * // ... - * } - * - * The closure will be evaluated when {@link resolve()} is called. The - * closure has access to the resolved values of other options through the - * passed {@link Options} instance: - * - * function (Options $options) { - * if (isset($options['port'])) { - * // ... - * } - * } - * - * If you want to access the previously set default value, add a second - * argument to the closure's signature: - * - * $options->setDefault('name', 'Default Name'); - * - * $options->setDefault('name', function (Options $options, $previousValue) { - * // 'Default Name' === $previousValue - * }); - * - * This is mostly useful if the configuration of the {@link Options} object - * is spread across different locations of your code, such as base and - * sub-classes. - * - * @param string $option The name of the option - * @param mixed $value The default value of the option - * - * @return OptionsResolver This instance - * - * @throws AccessException If called from a lazy option or normalizer - */ - public function setDefault($option, $value) - { - // Setting is not possible once resolving starts, because then lazy - // options could manipulate the state of the object, leading to - // inconsistent results. - if ($this->locked) { - throw new AccessException('Default values cannot be set from a lazy option or normalizer.'); - } - - // If an option is a closure that should be evaluated lazily, store it - // in the "lazy" property. - if ($value instanceof \Closure) { - $reflClosure = new \ReflectionFunction($value); - $params = $reflClosure->getParameters(); - - if (isset($params[0]) && null !== ($class = $params[0]->getClass()) && self::OPTIONS_INTERFACE === $class->name) { - // Initialize the option if no previous value exists - if (!isset($this->defaults[$option])) { - $this->defaults[$option] = null; - } - - // Ignore previous lazy options if the closure has no second parameter - if (!isset($this->lazy[$option]) || !isset($params[1])) { - $this->lazy[$option] = array(); - } - - // Store closure for later evaluation - $this->lazy[$option][] = $value; - $this->defined[$option] = true; - - // Make sure the option is processed - unset($this->resolved[$option]); - - return $this; - } - } - - // This option is not lazy anymore - unset($this->lazy[$option]); - - // Yet undefined options can be marked as resolved, because we only need - // to resolve options with lazy closures, normalizers or validation - // rules, none of which can exist for undefined options - // If the option was resolved before, update the resolved value - if (!isset($this->defined[$option]) || array_key_exists($option, $this->resolved)) { - $this->resolved[$option] = $value; - } - - $this->defaults[$option] = $value; - $this->defined[$option] = true; - - return $this; - } - - /** - * Sets a list of default values. - * - * @param array $defaults The default values to set - * - * @return OptionsResolver This instance - * - * @throws AccessException If called from a lazy option or normalizer - */ - public function setDefaults(array $defaults) - { - foreach ($defaults as $option => $value) { - $this->setDefault($option, $value); - } - - return $this; - } - - /** - * Returns whether a default value is set for an option. - * - * Returns true if {@link setDefault()} was called for this option. - * An option is also considered set if it was set to null. - * - * @param string $option The option name - * - * @return bool Whether a default value is set - */ - public function hasDefault($option) - { - return array_key_exists($option, $this->defaults); - } - - /** - * Marks one or more options as required. - * - * @param string|string[] $optionNames One or more option names - * - * @return OptionsResolver This instance - * - * @throws AccessException If called from a lazy option or normalizer - */ - public function setRequired($optionNames) - { - if ($this->locked) { - throw new AccessException('Options cannot be made required from a lazy option or normalizer.'); - } - - foreach ((array) $optionNames as $option) { - $this->defined[$option] = true; - $this->required[$option] = true; - } - - return $this; - } - - /** - * Returns whether an option is required. - * - * An option is required if it was passed to {@link setRequired()}. - * - * @param string $option The name of the option - * - * @return bool Whether the option is required - */ - public function isRequired($option) - { - return isset($this->required[$option]); - } - - /** - * Returns the names of all required options. - * - * @return string[] The names of the required options - * - * @see isRequired() - */ - public function getRequiredOptions() - { - return array_keys($this->required); - } - - /** - * Returns whether an option is missing a default value. - * - * An option is missing if it was passed to {@link setRequired()}, but not - * to {@link setDefault()}. This option must be passed explicitly to - * {@link resolve()}, otherwise an exception will be thrown. - * - * @param string $option The name of the option - * - * @return bool Whether the option is missing - */ - public function isMissing($option) - { - return isset($this->required[$option]) && !array_key_exists($option, $this->defaults); - } - - /** - * Returns the names of all options missing a default value. - * - * @return string[] The names of the missing options - * - * @see isMissing() - */ - public function getMissingOptions() - { - return array_keys(array_diff_key($this->required, $this->defaults)); - } - - /** - * Defines a valid option name. - * - * Defines an option name without setting a default value. The option will - * be accepted when passed to {@link resolve()}. When not passed, the - * option will not be included in the resolved options. - * - * @param string|string[] $optionNames One or more option names - * - * @return OptionsResolver This instance - * - * @throws AccessException If called from a lazy option or normalizer - */ - public function setDefined($optionNames) - { - if ($this->locked) { - throw new AccessException('Options cannot be defined from a lazy option or normalizer.'); - } - - foreach ((array) $optionNames as $option) { - $this->defined[$option] = true; - } - - return $this; - } - - /** - * Returns whether an option is defined. - * - * Returns true for any option passed to {@link setDefault()}, - * {@link setRequired()} or {@link setDefined()}. - * - * @param string $option The option name - * - * @return bool Whether the option is defined - */ - public function isDefined($option) - { - return isset($this->defined[$option]); - } - - /** - * Returns the names of all defined options. - * - * @return string[] The names of the defined options - * - * @see isDefined() - */ - public function getDefinedOptions() - { - return array_keys($this->defined); - } - - /** - * Sets the normalizer for an option. - * - * The normalizer should be a closure with the following signature: - * - * ```php - * function (Options $options, $value) { - * // ... - * } - * ``` - * - * The closure is invoked when {@link resolve()} is called. The closure - * has access to the resolved values of other options through the passed - * {@link Options} instance. - * - * The second parameter passed to the closure is the value of - * the option. - * - * The resolved option value is set to the return value of the closure. - * - * @param string $option The option name - * @param \Closure $normalizer The normalizer - * - * @return OptionsResolver This instance - * - * @throws UndefinedOptionsException If the option is undefined - * @throws AccessException If called from a lazy option or normalizer - */ - public function setNormalizer($option, \Closure $normalizer) - { - if ($this->locked) { - throw new AccessException('Normalizers cannot be set from a lazy option or normalizer.'); - } - - if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); - } - - $this->normalizers[$option] = $normalizer; - - // Make sure the option is processed - unset($this->resolved[$option]); - - return $this; - } - - /** - * Sets the normalizers for an array of options. - * - * @param array $normalizers An array of closures - * - * @return OptionsResolver This instance - * - * @throws UndefinedOptionsException If the option is undefined - * @throws AccessException If called from a lazy option or normalizer - * - * @see setNormalizer() - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function setNormalizers(array $normalizers) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use setNormalizer() instead.', E_USER_DEPRECATED); - - foreach ($normalizers as $option => $normalizer) { - $this->setNormalizer($option, $normalizer); - } - - return $this; - } - - /** - * Sets allowed values for an option. - * - * Instead of passing values, you may also pass a closures with the - * following signature: - * - * function ($value) { - * // return true or false - * } - * - * The closure receives the value as argument and should return true to - * accept the value and false to reject the value. - * - * @param string $option The option name - * @param mixed $allowedValues One or more acceptable values/closures - * - * @return OptionsResolver This instance - * - * @throws UndefinedOptionsException If the option is undefined - * @throws AccessException If called from a lazy option or normalizer - */ - public function setAllowedValues($option, $allowedValues = null) - { - if ($this->locked) { - throw new AccessException('Allowed values cannot be set from a lazy option or normalizer.'); - } - - // BC - if (is_array($option) && null === $allowedValues) { - @trigger_error('Calling the '.__METHOD__.' method with an array of options is deprecated since version 2.6 and will be removed in 3.0. Use the new signature with a single option instead.', E_USER_DEPRECATED); - - foreach ($option as $optionName => $optionValues) { - $this->setAllowedValues($optionName, $optionValues); - } - - return $this; - } - - if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); - } - - $this->allowedValues[$option] = is_array($allowedValues) ? $allowedValues : array($allowedValues); - - // Make sure the option is processed - unset($this->resolved[$option]); - - return $this; - } - - /** - * Adds allowed values for an option. - * - * The values are merged with the allowed values defined previously. - * - * Instead of passing values, you may also pass a closures with the - * following signature: - * - * function ($value) { - * // return true or false - * } - * - * The closure receives the value as argument and should return true to - * accept the value and false to reject the value. - * - * @param string $option The option name - * @param mixed $allowedValues One or more acceptable values/closures - * - * @return OptionsResolver This instance - * - * @throws UndefinedOptionsException If the option is undefined - * @throws AccessException If called from a lazy option or normalizer - */ - public function addAllowedValues($option, $allowedValues = null) - { - if ($this->locked) { - throw new AccessException('Allowed values cannot be added from a lazy option or normalizer.'); - } - - // BC - if (is_array($option) && null === $allowedValues) { - @trigger_error('Calling the '.__METHOD__.' method with an array of options is deprecated since version 2.6 and will be removed in 3.0. Use the new signature with a single option instead.', E_USER_DEPRECATED); - - foreach ($option as $optionName => $optionValues) { - $this->addAllowedValues($optionName, $optionValues); - } - - return $this; - } - - if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); - } - - if (!is_array($allowedValues)) { - $allowedValues = array($allowedValues); - } - - if (!isset($this->allowedValues[$option])) { - $this->allowedValues[$option] = $allowedValues; - } else { - $this->allowedValues[$option] = array_merge($this->allowedValues[$option], $allowedValues); - } - - // Make sure the option is processed - unset($this->resolved[$option]); - - return $this; - } - - /** - * Sets allowed types for an option. - * - * Any type for which a corresponding is_<type>() function exists is - * acceptable. Additionally, fully-qualified class or interface names may - * be passed. - * - * @param string $option The option name - * @param string|string[] $allowedTypes One or more accepted types - * - * @return OptionsResolver This instance - * - * @throws UndefinedOptionsException If the option is undefined - * @throws AccessException If called from a lazy option or normalizer - */ - public function setAllowedTypes($option, $allowedTypes = null) - { - if ($this->locked) { - throw new AccessException('Allowed types cannot be set from a lazy option or normalizer.'); - } - - // BC - if (is_array($option) && null === $allowedTypes) { - @trigger_error('Calling the '.__METHOD__.' method with an array of options is deprecated since version 2.6 and will be removed in 3.0. Use the new signature with a single option instead.', E_USER_DEPRECATED); - - foreach ($option as $optionName => $optionTypes) { - $this->setAllowedTypes($optionName, $optionTypes); - } - - return $this; - } - - if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); - } - - $this->allowedTypes[$option] = (array) $allowedTypes; - - // Make sure the option is processed - unset($this->resolved[$option]); - - return $this; - } - - /** - * Adds allowed types for an option. - * - * The types are merged with the allowed types defined previously. - * - * Any type for which a corresponding is_<type>() function exists is - * acceptable. Additionally, fully-qualified class or interface names may - * be passed. - * - * @param string $option The option name - * @param string|string[] $allowedTypes One or more accepted types - * - * @return OptionsResolver This instance - * - * @throws UndefinedOptionsException If the option is undefined - * @throws AccessException If called from a lazy option or normalizer - */ - public function addAllowedTypes($option, $allowedTypes = null) - { - if ($this->locked) { - throw new AccessException('Allowed types cannot be added from a lazy option or normalizer.'); - } - - // BC - if (is_array($option) && null === $allowedTypes) { - @trigger_error('Calling the '.__METHOD__.' method with an array of options is deprecated since version 2.6 and will be removed in 3.0. Use the new signature with a single option instead.', E_USER_DEPRECATED); - - foreach ($option as $optionName => $optionTypes) { - $this->addAllowedTypes($optionName, $optionTypes); - } - - return $this; - } - - if (!isset($this->defined[$option])) { - throw new UndefinedOptionsException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); - } - - if (!isset($this->allowedTypes[$option])) { - $this->allowedTypes[$option] = (array) $allowedTypes; - } else { - $this->allowedTypes[$option] = array_merge($this->allowedTypes[$option], (array) $allowedTypes); - } - - // Make sure the option is processed - unset($this->resolved[$option]); - - return $this; - } - - /** - * Removes the option with the given name. - * - * Undefined options are ignored. - * - * @param string|string[] $optionNames One or more option names - * - * @return OptionsResolver This instance - * - * @throws AccessException If called from a lazy option or normalizer - */ - public function remove($optionNames) - { - if ($this->locked) { - throw new AccessException('Options cannot be removed from a lazy option or normalizer.'); - } - - foreach ((array) $optionNames as $option) { - unset($this->defined[$option], $this->defaults[$option], $this->required[$option], $this->resolved[$option]); - unset($this->lazy[$option], $this->normalizers[$option], $this->allowedTypes[$option], $this->allowedValues[$option]); - } - - return $this; - } - - /** - * Removes all options. - * - * @return OptionsResolver This instance - * - * @throws AccessException If called from a lazy option or normalizer - */ - public function clear() - { - if ($this->locked) { - throw new AccessException('Options cannot be cleared from a lazy option or normalizer.'); - } - - $this->defined = array(); - $this->defaults = array(); - $this->required = array(); - $this->resolved = array(); - $this->lazy = array(); - $this->normalizers = array(); - $this->allowedTypes = array(); - $this->allowedValues = array(); - - return $this; - } - - /** - * Merges options with the default values stored in the container and - * validates them. - * - * Exceptions are thrown if: - * - * - Undefined options are passed; - * - Required options are missing; - * - Options have invalid types; - * - Options have invalid values. - * - * @param array $options A map of option names to values - * - * @return array The merged and validated options - * - * @throws UndefinedOptionsException If an option name is undefined - * @throws InvalidOptionsException If an option doesn't fulfill the - * specified validation rules - * @throws MissingOptionsException If a required option is missing - * @throws OptionDefinitionException If there is a cyclic dependency between - * lazy options and/or normalizers - * @throws NoSuchOptionException If a lazy option reads an unavailable option - * @throws AccessException If called from a lazy option or normalizer - */ - public function resolve(array $options = array()) - { - if ($this->locked) { - throw new AccessException('Options cannot be resolved from a lazy option or normalizer.'); - } - - // Allow this method to be called multiple times - $clone = clone $this; - - // Make sure that no unknown options are passed - $diff = array_diff_key($options, $clone->defined); - - if (count($diff) > 0) { - ksort($clone->defined); - ksort($diff); - - throw new UndefinedOptionsException(sprintf( - (count($diff) > 1 ? 'The options "%s" do not exist.' : 'The option "%s" does not exist.').' Defined options are: "%s".', - implode('", "', array_keys($diff)), - implode('", "', array_keys($clone->defined)) - )); - } - - // Override options set by the user - foreach ($options as $option => $value) { - $clone->defaults[$option] = $value; - unset($clone->resolved[$option], $clone->lazy[$option]); - } - - // Check whether any required option is missing - $diff = array_diff_key($clone->required, $clone->defaults); - - if (count($diff) > 0) { - ksort($diff); - - throw new MissingOptionsException(sprintf( - count($diff) > 1 ? 'The required options "%s" are missing.' : 'The required option "%s" is missing.', - implode('", "', array_keys($diff)) - )); - } - - // Lock the container - $clone->locked = true; - - // Now process the individual options. Use offsetGet(), which resolves - // the option itself and any options that the option depends on - foreach ($clone->defaults as $option => $_) { - $clone->offsetGet($option); - } - - return $clone->resolved; - } - - /** - * Returns the resolved value of an option. - * - * @param string $option The option name - * - * @return mixed The option value - * - * @throws AccessException If accessing this method outside of - * {@link resolve()} - * @throws NoSuchOptionException If the option is not set - * @throws InvalidOptionsException If the option doesn't fulfill the - * specified validation rules - * @throws OptionDefinitionException If there is a cyclic dependency between - * lazy options and/or normalizers - */ - public function offsetGet($option) - { - if (!$this->locked) { - throw new AccessException('Array access is only supported within closures of lazy options and normalizers.'); - } - - // Shortcut for resolved options - if (array_key_exists($option, $this->resolved)) { - return $this->resolved[$option]; - } - - // Check whether the option is set at all - if (!array_key_exists($option, $this->defaults)) { - if (!isset($this->defined[$option])) { - throw new NoSuchOptionException(sprintf( - 'The option "%s" does not exist. Defined options are: "%s".', - $option, - implode('", "', array_keys($this->defined)) - )); - } - - throw new NoSuchOptionException(sprintf( - 'The optional option "%s" has no value set. You should make sure it is set with "isset" before reading it.', - $option - )); - } - - $value = $this->defaults[$option]; - - // Resolve the option if the default value is lazily evaluated - if (isset($this->lazy[$option])) { - // If the closure is already being called, we have a cyclic - // dependency - if (isset($this->calling[$option])) { - throw new OptionDefinitionException(sprintf( - 'The options "%s" have a cyclic dependency.', - implode('", "', array_keys($this->calling)) - )); - } - - // The following section must be protected from cyclic - // calls. Set $calling for the current $option to detect a cyclic - // dependency - // BEGIN - $this->calling[$option] = true; - try { - foreach ($this->lazy[$option] as $closure) { - $value = $closure($this, $value); - } - } catch (\Exception $e) { - unset($this->calling[$option]); - throw $e; - } - unset($this->calling[$option]); - // END - } - - // Validate the type of the resolved option - if (isset($this->allowedTypes[$option])) { - $valid = false; - - foreach ($this->allowedTypes[$option] as $type) { - $type = isset(self::$typeAliases[$type]) ? self::$typeAliases[$type] : $type; - - if (function_exists($isFunction = 'is_'.$type)) { - if ($isFunction($value)) { - $valid = true; - break; - } - - continue; - } - - if ($value instanceof $type) { - $valid = true; - break; - } - } - - if (!$valid) { - throw new InvalidOptionsException(sprintf( - 'The option "%s" with value %s is expected to be of type '. - '"%s", but is of type "%s".', - $option, - $this->formatValue($value), - implode('" or "', $this->allowedTypes[$option]), - $this->formatTypeOf($value) - )); - } - } - - // Validate the value of the resolved option - if (isset($this->allowedValues[$option])) { - $success = false; - $printableAllowedValues = array(); - - foreach ($this->allowedValues[$option] as $allowedValue) { - if ($allowedValue instanceof \Closure) { - if ($allowedValue($value)) { - $success = true; - break; - } - - // Don't include closures in the exception message - continue; - } elseif ($value === $allowedValue) { - $success = true; - break; - } - - $printableAllowedValues[] = $allowedValue; - } - - if (!$success) { - $message = sprintf( - 'The option "%s" with value %s is invalid.', - $option, - $this->formatValue($value) - ); - - if (count($printableAllowedValues) > 0) { - $message .= sprintf( - ' Accepted values are: %s.', - $this->formatValues($printableAllowedValues) - ); - } - - throw new InvalidOptionsException($message); - } - } - - // Normalize the validated option - if (isset($this->normalizers[$option])) { - // If the closure is already being called, we have a cyclic - // dependency - if (isset($this->calling[$option])) { - throw new OptionDefinitionException(sprintf( - 'The options "%s" have a cyclic dependency.', - implode('", "', array_keys($this->calling)) - )); - } - - $normalizer = $this->normalizers[$option]; - - // The following section must be protected from cyclic - // calls. Set $calling for the current $option to detect a cyclic - // dependency - // BEGIN - $this->calling[$option] = true; - try { - $value = $normalizer($this, $value); - } catch (\Exception $e) { - unset($this->calling[$option]); - throw $e; - } - unset($this->calling[$option]); - // END - } - - // Mark as resolved - $this->resolved[$option] = $value; - - return $value; - } - - /** - * Returns whether a resolved option with the given name exists. - * - * @param string $option The option name - * - * @return bool Whether the option is set - * - * @throws AccessException If accessing this method outside of {@link resolve()} - * - * @see \ArrayAccess::offsetExists() - */ - public function offsetExists($option) - { - if (!$this->locked) { - throw new AccessException('Array access is only supported within closures of lazy options and normalizers.'); - } - - return array_key_exists($option, $this->defaults); - } - - /** - * Not supported. - * - * @throws AccessException - */ - public function offsetSet($option, $value) - { - throw new AccessException('Setting options via array access is not supported. Use setDefault() instead.'); - } - - /** - * Not supported. - * - * @throws AccessException - */ - public function offsetUnset($option) - { - throw new AccessException('Removing options via array access is not supported. Use remove() instead.'); - } - - /** - * Returns the number of set options. - * - * This may be only a subset of the defined options. - * - * @return int Number of options - * - * @throws AccessException If accessing this method outside of {@link resolve()} - * - * @see \Countable::count() - */ - public function count() - { - if (!$this->locked) { - throw new AccessException('Counting is only supported within closures of lazy options and normalizers.'); - } - - return count($this->defaults); - } - - /** - * Alias of {@link setDefault()}. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function set($option, $value) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the setDefaults() method instead.', E_USER_DEPRECATED); - - return $this->setDefault($option, $value); - } - - /** - * Shortcut for {@link clear()} and {@link setDefaults()}. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function replace(array $defaults) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the clear() and setDefaults() methods instead.', E_USER_DEPRECATED); - - $this->clear(); - - return $this->setDefaults($defaults); - } - - /** - * Alias of {@link setDefault()}. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function overload($option, $value) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the setDefault() method instead.', E_USER_DEPRECATED); - - return $this->setDefault($option, $value); - } - - /** - * Alias of {@link offsetGet()}. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function get($option) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the ArrayAccess syntax instead to get an option value.', E_USER_DEPRECATED); - - return $this->offsetGet($option); - } - - /** - * Alias of {@link offsetExists()}. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function has($option) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the ArrayAccess syntax instead to get an option value.', E_USER_DEPRECATED); - - return $this->offsetExists($option); - } - - /** - * Shortcut for {@link clear()} and {@link setDefaults()}. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function replaceDefaults(array $defaultValues) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the clear() and setDefaults() methods instead.', E_USER_DEPRECATED); - - $this->clear(); - - return $this->setDefaults($defaultValues); - } - - /** - * Alias of {@link setDefined()}. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function setOptional(array $optionNames) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the setDefined() method instead.', E_USER_DEPRECATED); - - return $this->setDefined($optionNames); - } - - /** - * Alias of {@link isDefined()}. - * - * @deprecated since version 2.6, to be removed in 3.0. - */ - public function isKnown($option) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0. Use the isDefined() method instead.', E_USER_DEPRECATED); - - return $this->isDefined($option); - } - - /** - * Returns a string representation of the type of the value. - * - * This method should be used if you pass the type of a value as - * message parameter to a constraint violation. Note that such - * parameters should usually not be included in messages aimed at - * non-technical people. - * - * @param mixed $value The value to return the type of - * - * @return string The type of the value - */ - private function formatTypeOf($value) - { - return is_object($value) ? get_class($value) : gettype($value); - } - - /** - * Returns a string representation of the value. - * - * This method returns the equivalent PHP tokens for most scalar types - * (i.e. "false" for false, "1" for 1 etc.). Strings are always wrapped - * in double quotes ("). - * - * @param mixed $value The value to format as string - * - * @return string The string representation of the passed value - */ - private function formatValue($value) - { - if (is_object($value)) { - return get_class($value); - } - - if (is_array($value)) { - return 'array'; - } - - if (is_string($value)) { - return '"'.$value.'"'; - } - - if (is_resource($value)) { - return 'resource'; - } - - if (null === $value) { - return 'null'; - } - - if (false === $value) { - return 'false'; - } - - if (true === $value) { - return 'true'; - } - - return (string) $value; - } - - /** - * Returns a string representation of a list of values. - * - * Each of the values is converted to a string using - * {@link formatValue()}. The values are then concatenated with commas. - * - * @param array $values A list of values - * - * @return string The string representation of the value list - * - * @see formatValue() - */ - private function formatValues(array $values) - { - foreach ($values as $key => $value) { - $values[$key] = $this->formatValue($value); - } - - return implode(', ', $values); - } -} diff --git a/library/symfony/options-resolver/OptionsResolverInterface.php b/library/symfony/options-resolver/OptionsResolverInterface.php deleted file mode 100644 index aebc8df22..000000000 --- a/library/symfony/options-resolver/OptionsResolverInterface.php +++ /dev/null @@ -1,212 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver; - -use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; -use Symfony\Component\OptionsResolver\Exception\MissingOptionsException; -use Symfony\Component\OptionsResolver\Exception\OptionDefinitionException; - -/** - * @author Bernhard Schussek <bschussek@gmail.com> - * - * @deprecated since version 2.6, to be removed in 3.0. Use {@link OptionsResolver} instead. - */ -interface OptionsResolverInterface -{ - /** - * Sets default option values. - * - * The options can either be values of any types or closures that - * evaluate the option value lazily. These closures must have one - * of the following signatures: - * - * <code> - * function (Options $options) - * function (Options $options, $value) - * </code> - * - * The second parameter passed to the closure is the previously - * set default value, in case you are overwriting an existing - * default value. - * - * The closures should return the lazily created option value. - * - * @param array $defaultValues A list of option names as keys and default - * values or closures as values. - * - * @return OptionsResolverInterface The resolver instance. - */ - public function setDefaults(array $defaultValues); - - /** - * Replaces default option values. - * - * Old defaults are erased, which means that closures passed here cannot - * access the previous default value. This may be useful to improve - * performance if the previous default value is calculated by an expensive - * closure. - * - * @param array $defaultValues A list of option names as keys and default - * values or closures as values. - * - * @return OptionsResolverInterface The resolver instance. - */ - public function replaceDefaults(array $defaultValues); - - /** - * Sets optional options. - * - * This method declares valid option names without setting default values for them. - * If these options are not passed to {@link resolve()} and no default has been set - * for them, they will be missing in the final options array. This can be helpful - * if you want to determine whether an option has been set or not because otherwise - * {@link resolve()} would trigger an exception for unknown options. - * - * @param array $optionNames A list of option names. - * - * @return OptionsResolverInterface The resolver instance. - */ - public function setOptional(array $optionNames); - - /** - * Sets required options. - * - * If these options are not passed to {@link resolve()} and no default has been set for - * them, an exception will be thrown. - * - * @param array $optionNames A list of option names. - * - * @return OptionsResolverInterface The resolver instance. - */ - public function setRequired($optionNames); - - /** - * Sets allowed values for a list of options. - * - * @param array $allowedValues A list of option names as keys and arrays - * with values acceptable for that option as - * values. - * - * @return OptionsResolverInterface The resolver instance. - * - * @throws InvalidOptionsException If an option has not been defined - * (see {@link isKnown()}) for which - * an allowed value is set. - */ - public function setAllowedValues($allowedValues); - - /** - * Adds allowed values for a list of options. - * - * The values are merged with the allowed values defined previously. - * - * @param array $allowedValues A list of option names as keys and arrays - * with values acceptable for that option as - * values. - * - * @return OptionsResolverInterface The resolver instance. - * - * @throws InvalidOptionsException If an option has not been defined - * (see {@link isKnown()}) for which - * an allowed value is set. - */ - public function addAllowedValues($allowedValues); - - /** - * Sets allowed types for a list of options. - * - * @param array $allowedTypes A list of option names as keys and type - * names passed as string or array as values. - * - * @return OptionsResolverInterface The resolver instance. - * - * @throws InvalidOptionsException If an option has not been defined for - * which an allowed type is set. - */ - public function setAllowedTypes($allowedTypes); - - /** - * Adds allowed types for a list of options. - * - * The types are merged with the allowed types defined previously. - * - * @param array $allowedTypes A list of option names as keys and type - * names passed as string or array as values. - * - * @return OptionsResolverInterface The resolver instance. - * - * @throws InvalidOptionsException If an option has not been defined for - * which an allowed type is set. - */ - public function addAllowedTypes($allowedTypes); - - /** - * Sets normalizers that are applied on resolved options. - * - * The normalizers should be closures with the following signature: - * - * <code> - * function (Options $options, $value) - * </code> - * - * The second parameter passed to the closure is the value of - * the option. - * - * The closure should return the normalized value. - * - * @param array $normalizers An array of closures. - * - * @return OptionsResolverInterface The resolver instance. - */ - public function setNormalizers(array $normalizers); - - /** - * Returns whether an option is known. - * - * An option is known if it has been passed to either {@link setDefaults()}, - * {@link setRequired()} or {@link setOptional()} before. - * - * @param string $option The name of the option. - * - * @return bool Whether the option is known. - */ - public function isKnown($option); - - /** - * Returns whether an option is required. - * - * An option is required if it has been passed to {@link setRequired()}, - * but not to {@link setDefaults()}. That is, the option has been declared - * as required and no default value has been set. - * - * @param string $option The name of the option. - * - * @return bool Whether the option is required. - */ - public function isRequired($option); - - /** - * Returns the combination of the default and the passed options. - * - * @param array $options The custom option values. - * - * @return array A list of options and their values. - * - * @throws InvalidOptionsException If any of the passed options has not - * been defined or does not contain an - * allowed value. - * @throws MissingOptionsException If a required option is missing. - * @throws OptionDefinitionException If a cyclic dependency is detected - * between two lazy options. - */ - public function resolve(array $options = array()); -} diff --git a/library/symfony/options-resolver/README.md b/library/symfony/options-resolver/README.md deleted file mode 100644 index cd7a7405d..000000000 --- a/library/symfony/options-resolver/README.md +++ /dev/null @@ -1,20 +0,0 @@ -OptionsResolver Component -========================= - -This component processes and validates option arrays. - -Documentation -------------- - -The documentation for the component can be found [online] [1]. - -Resources ---------- - -You can run the unit tests with the following command: - - $ cd path/to/Symfony/Component/OptionsResolver/ - $ composer install - $ phpunit - -[1]: https://symfony.com/doc/current/components/options_resolver.html diff --git a/library/symfony/options-resolver/Tests/LegacyOptionsResolverTest.php b/library/symfony/options-resolver/Tests/LegacyOptionsResolverTest.php deleted file mode 100644 index ee89f5279..000000000 --- a/library/symfony/options-resolver/Tests/LegacyOptionsResolverTest.php +++ /dev/null @@ -1,733 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Tests; - -use Symfony\Component\OptionsResolver\OptionsResolver; -use Symfony\Component\OptionsResolver\Options; - -/** - * @group legacy - */ -class LegacyOptionsResolverTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var OptionsResolver - */ - private $resolver; - - protected function setUp() - { - $this->resolver = new OptionsResolver(); - } - - public function testResolve() - { - $this->resolver->setDefaults(array( - 'one' => '1', - 'two' => '2', - )); - - $options = array( - 'two' => '20', - ); - - $this->assertEquals(array( - 'one' => '1', - 'two' => '20', - ), $this->resolver->resolve($options)); - } - - public function testResolveNumericOptions() - { - $this->resolver->setDefaults(array( - '1' => '1', - '2' => '2', - )); - - $options = array( - '2' => '20', - ); - - $this->assertEquals(array( - '1' => '1', - '2' => '20', - ), $this->resolver->resolve($options)); - } - - public function testResolveLazy() - { - $this->resolver->setDefaults(array( - 'one' => '1', - 'two' => function (Options $options) { - return '20'; - }, - )); - - $this->assertEquals(array( - 'one' => '1', - 'two' => '20', - ), $this->resolver->resolve(array())); - } - - public function testTypeAliasesForAllowedTypes() - { - $this->resolver->setDefaults(array( - 'force' => false, - )); - - $this->resolver->setAllowedTypes(array( - 'force' => 'boolean', - )); - - $this->resolver->resolve(array( - 'force' => true, - )); - } - - public function testResolveLazyDependencyOnOptional() - { - $this->resolver->setDefaults(array( - 'one' => '1', - 'two' => function (Options $options) { - return $options['one'].'2'; - }, - )); - - $options = array( - 'one' => '10', - ); - - $this->assertEquals(array( - 'one' => '10', - 'two' => '102', - ), $this->resolver->resolve($options)); - } - - public function testResolveLazyDependencyOnMissingOptionalWithoutDefault() - { - $test = $this; - - $this->resolver->setOptional(array( - 'one', - )); - - $this->resolver->setDefaults(array( - 'two' => function (Options $options) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->assertFalse(isset($options['one'])); - - return '2'; - }, - )); - - $options = array(); - - $this->assertEquals(array( - 'two' => '2', - ), $this->resolver->resolve($options)); - } - - public function testResolveLazyDependencyOnOptionalWithoutDefault() - { - $test = $this; - - $this->resolver->setOptional(array( - 'one', - )); - - $this->resolver->setDefaults(array( - 'two' => function (Options $options) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->assertTrue(isset($options['one'])); - - return $options['one'].'2'; - }, - )); - - $options = array( - 'one' => '10', - ); - - $this->assertEquals(array( - 'one' => '10', - 'two' => '102', - ), $this->resolver->resolve($options)); - } - - public function testResolveLazyDependencyOnRequired() - { - $this->resolver->setRequired(array( - 'one', - )); - $this->resolver->setDefaults(array( - 'two' => function (Options $options) { - return $options['one'].'2'; - }, - )); - - $options = array( - 'one' => '10', - ); - - $this->assertEquals(array( - 'one' => '10', - 'two' => '102', - ), $this->resolver->resolve($options)); - } - - public function testResolveLazyReplaceDefaults() - { - $test = $this; - - $this->resolver->setDefaults(array( - 'one' => function (Options $options) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->fail('Previous closure should not be executed'); - }, - )); - - $this->resolver->replaceDefaults(array( - 'one' => function (Options $options, $previousValue) { - return '1'; - }, - )); - - $this->assertEquals(array( - 'one' => '1', - ), $this->resolver->resolve(array())); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException - * @expectedExceptionMessage The option "foo" does not exist. Defined options are: "one", "three", "two". - */ - public function testResolveFailsIfNonExistingOption() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setRequired(array( - 'two', - )); - - $this->resolver->setOptional(array( - 'three', - )); - - $this->resolver->resolve(array( - 'foo' => 'bar', - )); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException - */ - public function testResolveFailsIfMissingRequiredOption() - { - $this->resolver->setRequired(array( - 'one', - )); - - $this->resolver->setDefaults(array( - 'two' => '2', - )); - - $this->resolver->resolve(array( - 'two' => '20', - )); - } - - public function testResolveSucceedsIfOptionValueAllowed() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setAllowedValues(array( - 'one' => array('1', 'one'), - )); - - $options = array( - 'one' => 'one', - ); - - $this->assertEquals(array( - 'one' => 'one', - ), $this->resolver->resolve($options)); - } - - public function testResolveSucceedsIfOptionValueAllowed2() - { - $this->resolver->setDefaults(array( - 'one' => '1', - 'two' => '2', - )); - - $this->resolver->setAllowedValues(array( - 'one' => '1', - 'two' => '2', - )); - $this->resolver->addAllowedValues(array( - 'one' => 'one', - 'two' => 'two', - )); - - $options = array( - 'one' => '1', - 'two' => 'two', - ); - - $this->assertEquals(array( - 'one' => '1', - 'two' => 'two', - ), $this->resolver->resolve($options)); - } - - public function testResolveSucceedsIfOptionalWithAllowedValuesNotSet() - { - $this->resolver->setRequired(array( - 'one', - )); - - $this->resolver->setOptional(array( - 'two', - )); - - $this->resolver->setAllowedValues(array( - 'one' => array('1', 'one'), - 'two' => array('2', 'two'), - )); - - $options = array( - 'one' => '1', - ); - - $this->assertEquals(array( - 'one' => '1', - ), $this->resolver->resolve($options)); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfOptionValueNotAllowed() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setAllowedValues(array( - 'one' => array('1', 'one'), - )); - - $this->resolver->resolve(array( - 'one' => '2', - )); - } - - public function testResolveSucceedsIfOptionTypeAllowed() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => 'string', - )); - - $options = array( - 'one' => 'one', - ); - - $this->assertEquals(array( - 'one' => 'one', - ), $this->resolver->resolve($options)); - } - - public function testResolveSucceedsIfOptionTypeAllowedPassArray() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => array('string', 'bool'), - )); - - $options = array( - 'one' => true, - ); - - $this->assertEquals(array( - 'one' => true, - ), $this->resolver->resolve($options)); - } - - public function testResolveSucceedsIfOptionTypeAllowedPassObject() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => 'object', - )); - - $object = new \stdClass(); - $options = array( - 'one' => $object, - ); - - $this->assertEquals(array( - 'one' => $object, - ), $this->resolver->resolve($options)); - } - - public function testResolveSucceedsIfOptionTypeAllowedPassClass() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => '\stdClass', - )); - - $object = new \stdClass(); - $options = array( - 'one' => $object, - ); - - $this->assertEquals(array( - 'one' => $object, - ), $this->resolver->resolve($options)); - } - - public function testResolveSucceedsIfOptionTypeAllowedAddTypes() - { - $this->resolver->setDefaults(array( - 'one' => '1', - 'two' => '2', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => 'string', - 'two' => 'bool', - )); - $this->resolver->addAllowedTypes(array( - 'one' => 'float', - 'two' => 'integer', - )); - - $options = array( - 'one' => 1.23, - 'two' => false, - ); - - $this->assertEquals(array( - 'one' => 1.23, - 'two' => false, - ), $this->resolver->resolve($options)); - } - - public function testResolveSucceedsIfOptionalWithTypeAndWithoutValue() - { - $this->resolver->setOptional(array( - 'one', - 'two', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => 'string', - 'two' => 'int', - )); - - $options = array( - 'two' => 1, - ); - - $this->assertEquals(array( - 'two' => 1, - ), $this->resolver->resolve($options)); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfOptionTypeNotAllowed() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => array('string', 'bool'), - )); - - $this->resolver->resolve(array( - 'one' => 1.23, - )); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfOptionTypeNotAllowedMultipleOptions() - { - $this->resolver->setDefaults(array( - 'one' => '1', - 'two' => '2', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => 'string', - 'two' => 'bool', - )); - - $this->resolver->resolve(array( - 'one' => 'foo', - 'two' => 1.23, - )); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfOptionTypeNotAllowedAddTypes() - { - $this->resolver->setDefaults(array( - 'one' => '1', - )); - - $this->resolver->setAllowedTypes(array( - 'one' => 'string', - )); - $this->resolver->addAllowedTypes(array( - 'one' => 'bool', - )); - - $this->resolver->resolve(array( - 'one' => 1.23, - )); - } - - public function testFluidInterface() - { - $this->resolver->setDefaults(array('one' => '1')) - ->replaceDefaults(array('one' => '2')) - ->setAllowedValues(array('one' => array('1', '2'))) - ->addAllowedValues(array('one' => array('3'))) - ->setRequired(array('two')) - ->setOptional(array('three')); - - $options = array( - 'two' => '2', - ); - - $this->assertEquals(array( - 'one' => '2', - 'two' => '2', - ), $this->resolver->resolve($options)); - } - - public function testKnownIfDefaultWasSet() - { - $this->assertFalse($this->resolver->isKnown('foo')); - - $this->resolver->setDefaults(array( - 'foo' => 'bar', - )); - - $this->assertTrue($this->resolver->isKnown('foo')); - } - - public function testKnownIfRequired() - { - $this->assertFalse($this->resolver->isKnown('foo')); - - $this->resolver->setRequired(array( - 'foo', - )); - - $this->assertTrue($this->resolver->isKnown('foo')); - } - - public function testKnownIfOptional() - { - $this->assertFalse($this->resolver->isKnown('foo')); - - $this->resolver->setOptional(array( - 'foo', - )); - - $this->assertTrue($this->resolver->isKnown('foo')); - } - - public function testRequiredIfRequired() - { - $this->assertFalse($this->resolver->isRequired('foo')); - - $this->resolver->setRequired(array( - 'foo', - )); - - $this->assertTrue($this->resolver->isRequired('foo')); - } - - public function testNormalizersTransformFinalOptions() - { - $this->resolver->setDefaults(array( - 'foo' => 'bar', - 'bam' => 'baz', - )); - $this->resolver->setNormalizers(array( - 'foo' => function (Options $options, $value) { - return $options['bam'].'['.$value.']'; - }, - )); - - $expected = array( - 'foo' => 'baz[bar]', - 'bam' => 'baz', - ); - - $this->assertEquals($expected, $this->resolver->resolve(array())); - - $expected = array( - 'foo' => 'boo[custom]', - 'bam' => 'boo', - ); - - $this->assertEquals($expected, $this->resolver->resolve(array( - 'foo' => 'custom', - 'bam' => 'boo', - ))); - } - - public function testResolveWithoutOptionSucceedsIfRequiredAndDefaultValue() - { - $this->resolver->setRequired(array( - 'foo', - )); - $this->resolver->setDefaults(array( - 'foo' => 'bar', - )); - - $this->assertEquals(array( - 'foo' => 'bar', - ), $this->resolver->resolve(array())); - } - - public function testResolveWithoutOptionSucceedsIfDefaultValueAndRequired() - { - $this->resolver->setDefaults(array( - 'foo' => 'bar', - )); - $this->resolver->setRequired(array( - 'foo', - )); - - $this->assertEquals(array( - 'foo' => 'bar', - ), $this->resolver->resolve(array())); - } - - public function testResolveSucceedsIfOptionRequiredAndValueAllowed() - { - $this->resolver->setRequired(array( - 'one', 'two', - )); - $this->resolver->setAllowedValues(array( - 'two' => array('2'), - )); - - $options = array( - 'one' => '1', - 'two' => '2', - ); - - $this->assertEquals($options, $this->resolver->resolve($options)); - } - - public function testResolveSucceedsIfValueAllowedCallbackReturnsTrue() - { - $this->resolver->setRequired(array( - 'test', - )); - $this->resolver->setAllowedValues(array( - 'test' => function ($value) { - return true; - }, - )); - - $options = array( - 'test' => true, - ); - - $this->assertEquals($options, $this->resolver->resolve($options)); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfValueAllowedCallbackReturnsFalse() - { - $this->resolver->setRequired(array( - 'test', - )); - $this->resolver->setAllowedValues(array( - 'test' => function ($value) { - return false; - }, - )); - - $options = array( - 'test' => true, - ); - - $this->assertEquals($options, $this->resolver->resolve($options)); - } - - public function testClone() - { - $this->resolver->setDefaults(array('one' => '1')); - - $clone = clone $this->resolver; - - // Changes after cloning don't affect each other - $this->resolver->setDefaults(array('two' => '2')); - $clone->setDefaults(array('three' => '3')); - - $this->assertEquals(array( - 'one' => '1', - 'two' => '2', - ), $this->resolver->resolve()); - - $this->assertEquals(array( - 'one' => '1', - 'three' => '3', - ), $clone->resolve()); - } - - public function testOverloadReturnsThis() - { - $this->assertSame($this->resolver, $this->resolver->overload('foo', 'bar')); - } - - public function testOverloadCallsSet() - { - $this->resolver->overload('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } -} diff --git a/library/symfony/options-resolver/Tests/LegacyOptionsTest.php b/library/symfony/options-resolver/Tests/LegacyOptionsTest.php deleted file mode 100644 index b65a09002..000000000 --- a/library/symfony/options-resolver/Tests/LegacyOptionsTest.php +++ /dev/null @@ -1,337 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Tests; - -use Symfony\Component\OptionsResolver\Options; -use Symfony\Component\OptionsResolver\OptionsResolver; - -/** - * @group legacy - */ -class LegacyOptionsTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var OptionsResolver - */ - private $options; - - protected function setUp() - { - $this->options = new OptionsResolver(); - } - - public function testSetLazyOption() - { - $test = $this; - - $this->options->set('foo', function (Options $options) use ($test) { - return 'dynamic'; - }); - - $this->assertEquals(array('foo' => 'dynamic'), $this->options->resolve()); - } - - public function testOverloadKeepsPreviousValue() - { - $test = $this; - - // defined by superclass - $this->options->set('foo', 'bar'); - - // defined by subclass - $this->options->overload('foo', function (Options $options, $previousValue) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->assertEquals('bar', $previousValue); - - return 'dynamic'; - }); - - $this->assertEquals(array('foo' => 'dynamic'), $this->options->resolve()); - } - - public function testPreviousValueIsEvaluatedIfLazy() - { - $test = $this; - - // defined by superclass - $this->options->set('foo', function (Options $options) { - return 'bar'; - }); - - // defined by subclass - $this->options->overload('foo', function (Options $options, $previousValue) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->assertEquals('bar', $previousValue); - - return 'dynamic'; - }); - - $this->assertEquals(array('foo' => 'dynamic'), $this->options->resolve()); - } - - public function testPreviousValueIsNotEvaluatedIfNoSecondArgument() - { - $test = $this; - - // defined by superclass - $this->options->set('foo', function (Options $options) use ($test) { - $test->fail('Should not be called'); - }); - - // defined by subclass, no $previousValue argument defined! - $this->options->overload('foo', function (Options $options) use ($test) { - return 'dynamic'; - }); - - $this->assertEquals(array('foo' => 'dynamic'), $this->options->resolve()); - } - - public function testLazyOptionCanAccessOtherOptions() - { - $test = $this; - - $this->options->set('foo', 'bar'); - - $this->options->set('bam', function (Options $options) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->assertEquals('bar', $options->get('foo')); - - return 'dynamic'; - }); - - $this->assertEquals(array('foo' => 'bar', 'bam' => 'dynamic'), $this->options->resolve()); - } - - public function testLazyOptionCanAccessOtherLazyOptions() - { - $test = $this; - - $this->options->set('foo', function (Options $options) { - return 'bar'; - }); - - $this->options->set('bam', function (Options $options) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->assertEquals('bar', $options->get('foo')); - - return 'dynamic'; - }); - - $this->assertEquals(array('foo' => 'bar', 'bam' => 'dynamic'), $this->options->resolve()); - } - - public function testNormalizer() - { - $this->options->set('foo', 'bar'); - - $this->options->setNormalizer('foo', function () { - return 'normalized'; - }); - - $this->assertEquals(array('foo' => 'normalized'), $this->options->resolve()); - } - - public function testNormalizerReceivesUnnormalizedValue() - { - $this->options->set('foo', 'bar'); - - $this->options->setNormalizer('foo', function (Options $options, $value) { - return 'normalized['.$value.']'; - }); - - $this->assertEquals(array('foo' => 'normalized[bar]'), $this->options->resolve()); - } - - public function testNormalizerCanAccessOtherOptions() - { - $test = $this; - - $this->options->set('foo', 'bar'); - $this->options->set('bam', 'baz'); - - $this->options->setNormalizer('bam', function (Options $options) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->assertEquals('bar', $options->get('foo')); - - return 'normalized'; - }); - - $this->assertEquals(array('foo' => 'bar', 'bam' => 'normalized'), $this->options->resolve()); - } - - public function testNormalizerCanAccessOtherLazyOptions() - { - $test = $this; - - $this->options->set('foo', function (Options $options) { - return 'bar'; - }); - $this->options->set('bam', 'baz'); - - $this->options->setNormalizer('bam', function (Options $options) use ($test) { - /* @var \PHPUnit_Framework_TestCase $test */ - $test->assertEquals('bar', $options->get('foo')); - - return 'normalized'; - }); - - $this->assertEquals(array('foo' => 'bar', 'bam' => 'normalized'), $this->options->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException - */ - public function testFailForCyclicDependencies() - { - $this->options->set('foo', function (Options $options) { - $options->get('bam'); - }); - - $this->options->set('bam', function (Options $options) { - $options->get('foo'); - }); - - $this->options->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException - */ - public function testFailForCyclicDependenciesBetweenNormalizers() - { - $this->options->set('foo', 'bar'); - $this->options->set('bam', 'baz'); - - $this->options->setNormalizer('foo', function (Options $options) { - $options->get('bam'); - }); - - $this->options->setNormalizer('bam', function (Options $options) { - $options->get('foo'); - }); - - $this->options->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException - */ - public function testFailForCyclicDependenciesBetweenNormalizerAndLazyOption() - { - $this->options->set('foo', function (Options $options) { - $options->get('bam'); - }); - $this->options->set('bam', 'baz'); - - $this->options->setNormalizer('bam', function (Options $options) { - $options->get('foo'); - }); - - $this->options->resolve(); - } - - public function testReplaceClearsAndSets() - { - $this->options->set('one', '1'); - - $this->options->replace(array( - 'two' => '2', - 'three' => function (Options $options) { - return '2' === $options['two'] ? '3' : 'foo'; - }, - )); - - $this->assertEquals(array( - 'two' => '2', - 'three' => '3', - ), $this->options->resolve()); - } - - public function testClearRemovesAllOptions() - { - $this->options->set('one', 1); - $this->options->set('two', 2); - - $this->options->clear(); - - $this->assertEmpty($this->options->resolve()); - } - - public function testOverloadCannotBeEvaluatedLazilyWithoutExpectedClosureParams() - { - $this->options->set('foo', 'bar'); - - $this->options->overload('foo', function () { - return 'test'; - }); - - $resolved = $this->options->resolve(); - $this->assertTrue(is_callable($resolved['foo'])); - } - - public function testOverloadCannotBeEvaluatedLazilyWithoutFirstParamTypeHint() - { - $this->options->set('foo', 'bar'); - - $this->options->overload('foo', function ($object) { - return 'test'; - }); - - $resolved = $this->options->resolve(); - $this->assertTrue(is_callable($resolved['foo'])); - } - - public function testRemoveOptionAndNormalizer() - { - $this->options->set('foo1', 'bar'); - $this->options->setNormalizer('foo1', function (Options $options) { - return ''; - }); - $this->options->set('foo2', 'bar'); - $this->options->setNormalizer('foo2', function (Options $options) { - return ''; - }); - - $this->options->remove('foo2'); - $this->assertEquals(array('foo1' => ''), $this->options->resolve()); - } - - public function testReplaceOptionAndNormalizer() - { - $this->options->set('foo1', 'bar'); - $this->options->setNormalizer('foo1', function (Options $options) { - return ''; - }); - $this->options->set('foo2', 'bar'); - $this->options->setNormalizer('foo2', function (Options $options) { - return ''; - }); - - $this->options->replace(array('foo1' => 'new')); - $this->assertEquals(array('foo1' => 'new'), $this->options->resolve()); - } - - public function testClearOptionAndNormalizer() - { - $this->options->set('foo1', 'bar'); - $this->options->setNormalizer('foo1', function (Options $options) { - return ''; - }); - $this->options->set('foo2', 'bar'); - $this->options->setNormalizer('foo2', function (Options $options) { - return ''; - }); - - $this->options->clear(); - $this->assertEmpty($this->options->resolve()); - } -} diff --git a/library/symfony/options-resolver/Tests/OptionsResolver2Dot6Test.php b/library/symfony/options-resolver/Tests/OptionsResolver2Dot6Test.php deleted file mode 100644 index 9158c5ba0..000000000 --- a/library/symfony/options-resolver/Tests/OptionsResolver2Dot6Test.php +++ /dev/null @@ -1,1550 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\OptionsResolver\Tests; - -use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; -use Symfony\Component\OptionsResolver\Options; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class OptionsResolver2Dot6Test extends \PHPUnit_Framework_TestCase -{ - /** - * @var OptionsResolver - */ - private $resolver; - - protected function setUp() - { - $this->resolver = new OptionsResolver(); - } - - //////////////////////////////////////////////////////////////////////////// - // resolve() - //////////////////////////////////////////////////////////////////////////// - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException - * @expectedExceptionMessage The option "foo" does not exist. Defined options are: "a", "z". - */ - public function testResolveFailsIfNonExistingOption() - { - $this->resolver->setDefault('z', '1'); - $this->resolver->setDefault('a', '2'); - - $this->resolver->resolve(array('foo' => 'bar')); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException - * @expectedExceptionMessage The options "baz", "foo", "ping" do not exist. Defined options are: "a", "z". - */ - public function testResolveFailsIfMultipleNonExistingOptions() - { - $this->resolver->setDefault('z', '1'); - $this->resolver->setDefault('a', '2'); - - $this->resolver->resolve(array('ping' => 'pong', 'foo' => 'bar', 'baz' => 'bam')); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testResolveFailsFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->resolve(array()); - }); - - $this->resolver->resolve(); - } - - //////////////////////////////////////////////////////////////////////////// - // setDefault()/hasDefault() - //////////////////////////////////////////////////////////////////////////// - - public function testSetDefaultReturnsThis() - { - $this->assertSame($this->resolver, $this->resolver->setDefault('foo', 'bar')); - } - - public function testSetDefault() - { - $this->resolver->setDefault('one', '1'); - $this->resolver->setDefault('two', '20'); - - $this->assertEquals(array( - 'one' => '1', - 'two' => '20', - ), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfSetDefaultFromLazyOption() - { - $this->resolver->setDefault('lazy', function (Options $options) { - $options->setDefault('default', 42); - }); - - $this->resolver->resolve(); - } - - public function testHasDefault() - { - $this->assertFalse($this->resolver->hasDefault('foo')); - $this->resolver->setDefault('foo', 42); - $this->assertTrue($this->resolver->hasDefault('foo')); - } - - public function testHasDefaultWithNullValue() - { - $this->assertFalse($this->resolver->hasDefault('foo')); - $this->resolver->setDefault('foo', null); - $this->assertTrue($this->resolver->hasDefault('foo')); - } - - //////////////////////////////////////////////////////////////////////////// - // lazy setDefault() - //////////////////////////////////////////////////////////////////////////// - - public function testSetLazyReturnsThis() - { - $this->assertSame($this->resolver, $this->resolver->setDefault('foo', function (Options $options) {})); - } - - public function testSetLazyClosure() - { - $this->resolver->setDefault('foo', function (Options $options) { - return 'lazy'; - }); - - $this->assertEquals(array('foo' => 'lazy'), $this->resolver->resolve()); - } - - public function testClosureWithoutTypeHintNotInvoked() - { - $closure = function ($options) { - \PHPUnit_Framework_Assert::fail('Should not be called'); - }; - - $this->resolver->setDefault('foo', $closure); - - $this->assertSame(array('foo' => $closure), $this->resolver->resolve()); - } - - public function testClosureWithoutParametersNotInvoked() - { - $closure = function () { - \PHPUnit_Framework_Assert::fail('Should not be called'); - }; - - $this->resolver->setDefault('foo', $closure); - - $this->assertSame(array('foo' => $closure), $this->resolver->resolve()); - } - - public function testAccessPreviousDefaultValue() - { - // defined by superclass - $this->resolver->setDefault('foo', 'bar'); - - // defined by subclass - $this->resolver->setDefault('foo', function (Options $options, $previousValue) { - \PHPUnit_Framework_Assert::assertEquals('bar', $previousValue); - - return 'lazy'; - }); - - $this->assertEquals(array('foo' => 'lazy'), $this->resolver->resolve()); - } - - public function testAccessPreviousLazyDefaultValue() - { - // defined by superclass - $this->resolver->setDefault('foo', function (Options $options) { - return 'bar'; - }); - - // defined by subclass - $this->resolver->setDefault('foo', function (Options $options, $previousValue) { - \PHPUnit_Framework_Assert::assertEquals('bar', $previousValue); - - return 'lazy'; - }); - - $this->assertEquals(array('foo' => 'lazy'), $this->resolver->resolve()); - } - - public function testPreviousValueIsNotEvaluatedIfNoSecondArgument() - { - // defined by superclass - $this->resolver->setDefault('foo', function () { - \PHPUnit_Framework_Assert::fail('Should not be called'); - }); - - // defined by subclass, no $previousValue argument defined! - $this->resolver->setDefault('foo', function (Options $options) { - return 'lazy'; - }); - - $this->assertEquals(array('foo' => 'lazy'), $this->resolver->resolve()); - } - - public function testOverwrittenLazyOptionNotEvaluated() - { - $this->resolver->setDefault('foo', function (Options $options) { - \PHPUnit_Framework_Assert::fail('Should not be called'); - }); - - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testInvokeEachLazyOptionOnlyOnce() - { - $calls = 0; - - $this->resolver->setDefault('lazy1', function (Options $options) use (&$calls) { - \PHPUnit_Framework_Assert::assertSame(1, ++$calls); - - $options['lazy2']; - }); - - $this->resolver->setDefault('lazy2', function (Options $options) use (&$calls) { - \PHPUnit_Framework_Assert::assertSame(2, ++$calls); - }); - - $this->resolver->resolve(); - - $this->assertSame(2, $calls); - } - - //////////////////////////////////////////////////////////////////////////// - // setRequired()/isRequired()/getRequiredOptions() - //////////////////////////////////////////////////////////////////////////// - - public function testSetRequiredReturnsThis() - { - $this->assertSame($this->resolver, $this->resolver->setRequired('foo')); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfSetRequiredFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->setRequired('bar'); - }); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\MissingOptionsException - */ - public function testResolveFailsIfRequiredOptionMissing() - { - $this->resolver->setRequired('foo'); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfRequiredOptionSet() - { - $this->resolver->setRequired('foo'); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertNotEmpty($this->resolver->resolve()); - } - - public function testResolveSucceedsIfRequiredOptionPassed() - { - $this->resolver->setRequired('foo'); - - $this->assertNotEmpty($this->resolver->resolve(array('foo' => 'bar'))); - } - - public function testIsRequired() - { - $this->assertFalse($this->resolver->isRequired('foo')); - $this->resolver->setRequired('foo'); - $this->assertTrue($this->resolver->isRequired('foo')); - } - - public function testRequiredIfSetBefore() - { - $this->assertFalse($this->resolver->isRequired('foo')); - - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setRequired('foo'); - - $this->assertTrue($this->resolver->isRequired('foo')); - } - - public function testStillRequiredAfterSet() - { - $this->assertFalse($this->resolver->isRequired('foo')); - - $this->resolver->setRequired('foo'); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertTrue($this->resolver->isRequired('foo')); - } - - public function testIsNotRequiredAfterRemove() - { - $this->assertFalse($this->resolver->isRequired('foo')); - $this->resolver->setRequired('foo'); - $this->resolver->remove('foo'); - $this->assertFalse($this->resolver->isRequired('foo')); - } - - public function testIsNotRequiredAfterClear() - { - $this->assertFalse($this->resolver->isRequired('foo')); - $this->resolver->setRequired('foo'); - $this->resolver->clear(); - $this->assertFalse($this->resolver->isRequired('foo')); - } - - public function testGetRequiredOptions() - { - $this->resolver->setRequired(array('foo', 'bar')); - $this->resolver->setDefault('bam', 'baz'); - $this->resolver->setDefault('foo', 'boo'); - - $this->assertSame(array('foo', 'bar'), $this->resolver->getRequiredOptions()); - } - - //////////////////////////////////////////////////////////////////////////// - // isMissing()/getMissingOptions() - //////////////////////////////////////////////////////////////////////////// - - public function testIsMissingIfNotSet() - { - $this->assertFalse($this->resolver->isMissing('foo')); - $this->resolver->setRequired('foo'); - $this->assertTrue($this->resolver->isMissing('foo')); - } - - public function testIsNotMissingIfSet() - { - $this->resolver->setDefault('foo', 'bar'); - - $this->assertFalse($this->resolver->isMissing('foo')); - $this->resolver->setRequired('foo'); - $this->assertFalse($this->resolver->isMissing('foo')); - } - - public function testIsNotMissingAfterRemove() - { - $this->resolver->setRequired('foo'); - $this->resolver->remove('foo'); - $this->assertFalse($this->resolver->isMissing('foo')); - } - - public function testIsNotMissingAfterClear() - { - $this->resolver->setRequired('foo'); - $this->resolver->clear(); - $this->assertFalse($this->resolver->isRequired('foo')); - } - - public function testGetMissingOptions() - { - $this->resolver->setRequired(array('foo', 'bar')); - $this->resolver->setDefault('bam', 'baz'); - $this->resolver->setDefault('foo', 'boo'); - - $this->assertSame(array('bar'), $this->resolver->getMissingOptions()); - } - - //////////////////////////////////////////////////////////////////////////// - // setDefined()/isDefined()/getDefinedOptions() - //////////////////////////////////////////////////////////////////////////// - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfSetDefinedFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->setDefined('bar'); - }); - - $this->resolver->resolve(); - } - - public function testDefinedOptionsNotIncludedInResolvedOptions() - { - $this->resolver->setDefined('foo'); - - $this->assertSame(array(), $this->resolver->resolve()); - } - - public function testDefinedOptionsIncludedIfDefaultSetBefore() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setDefined('foo'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testDefinedOptionsIncludedIfDefaultSetAfter() - { - $this->resolver->setDefined('foo'); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testDefinedOptionsIncludedIfPassedToResolve() - { - $this->resolver->setDefined('foo'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve(array('foo' => 'bar'))); - } - - public function testIsDefined() - { - $this->assertFalse($this->resolver->isDefined('foo')); - $this->resolver->setDefined('foo'); - $this->assertTrue($this->resolver->isDefined('foo')); - } - - public function testLazyOptionsAreDefined() - { - $this->assertFalse($this->resolver->isDefined('foo')); - $this->resolver->setDefault('foo', function (Options $options) {}); - $this->assertTrue($this->resolver->isDefined('foo')); - } - - public function testRequiredOptionsAreDefined() - { - $this->assertFalse($this->resolver->isDefined('foo')); - $this->resolver->setRequired('foo'); - $this->assertTrue($this->resolver->isDefined('foo')); - } - - public function testSetOptionsAreDefined() - { - $this->assertFalse($this->resolver->isDefined('foo')); - $this->resolver->setDefault('foo', 'bar'); - $this->assertTrue($this->resolver->isDefined('foo')); - } - - public function testGetDefinedOptions() - { - $this->resolver->setDefined(array('foo', 'bar')); - $this->resolver->setDefault('baz', 'bam'); - $this->resolver->setRequired('boo'); - - $this->assertSame(array('foo', 'bar', 'baz', 'boo'), $this->resolver->getDefinedOptions()); - } - - public function testRemovedOptionsAreNotDefined() - { - $this->assertFalse($this->resolver->isDefined('foo')); - $this->resolver->setDefined('foo'); - $this->assertTrue($this->resolver->isDefined('foo')); - $this->resolver->remove('foo'); - $this->assertFalse($this->resolver->isDefined('foo')); - } - - public function testClearedOptionsAreNotDefined() - { - $this->assertFalse($this->resolver->isDefined('foo')); - $this->resolver->setDefined('foo'); - $this->assertTrue($this->resolver->isDefined('foo')); - $this->resolver->clear(); - $this->assertFalse($this->resolver->isDefined('foo')); - } - - //////////////////////////////////////////////////////////////////////////// - // setAllowedTypes() - //////////////////////////////////////////////////////////////////////////// - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException - */ - public function testSetAllowedTypesFailsIfUnknownOption() - { - $this->resolver->setAllowedTypes('foo', 'string'); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfSetAllowedTypesFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->setAllowedTypes('bar', 'string'); - }); - - $this->resolver->setDefault('bar', 'baz'); - - $this->resolver->resolve(); - } - - /** - * @dataProvider provideInvalidTypes - */ - public function testResolveFailsIfInvalidType($actualType, $allowedType, $exceptionMessage) - { - $this->resolver->setDefined('option'); - $this->resolver->setAllowedTypes('option', $allowedType); - $this->setExpectedException('Symfony\Component\OptionsResolver\Exception\InvalidOptionsException', $exceptionMessage); - $this->resolver->resolve(array('option' => $actualType)); - } - - public function provideInvalidTypes() - { - return array( - array(true, 'string', 'The option "option" with value true is expected to be of type "string", but is of type "boolean".'), - array(false, 'string', 'The option "option" with value false is expected to be of type "string", but is of type "boolean".'), - array(fopen(__FILE__, 'r'), 'string', 'The option "option" with value resource is expected to be of type "string", but is of type "resource".'), - array(array(), 'string', 'The option "option" with value array is expected to be of type "string", but is of type "array".'), - array(new OptionsResolver(), 'string', 'The option "option" with value Symfony\Component\OptionsResolver\OptionsResolver is expected to be of type "string", but is of type "Symfony\Component\OptionsResolver\OptionsResolver".'), - array(42, 'string', 'The option "option" with value 42 is expected to be of type "string", but is of type "integer".'), - array(null, 'string', 'The option "option" with value null is expected to be of type "string", but is of type "NULL".'), - array('bar', '\stdClass', 'The option "option" with value "bar" is expected to be of type "\stdClass", but is of type "string".'), - ); - } - - public function testResolveSucceedsIfValidType() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedTypes('foo', 'string'); - - $this->assertNotEmpty($this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - * @expectedExceptionMessage The option "foo" with value 42 is expected to be of type "string" or "bool", but is of type "integer". - */ - public function testResolveFailsIfInvalidTypeMultiple() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->setAllowedTypes('foo', array('string', 'bool')); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfValidTypeMultiple() - { - $this->resolver->setDefault('foo', true); - $this->resolver->setAllowedTypes('foo', array('string', 'bool')); - - $this->assertNotEmpty($this->resolver->resolve()); - } - - public function testResolveSucceedsIfInstanceOfClass() - { - $this->resolver->setDefault('foo', new \stdClass()); - $this->resolver->setAllowedTypes('foo', '\stdClass'); - - $this->assertNotEmpty($this->resolver->resolve()); - } - - //////////////////////////////////////////////////////////////////////////// - // addAllowedTypes() - //////////////////////////////////////////////////////////////////////////// - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException - */ - public function testAddAllowedTypesFailsIfUnknownOption() - { - $this->resolver->addAllowedTypes('foo', 'string'); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfAddAllowedTypesFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->addAllowedTypes('bar', 'string'); - }); - - $this->resolver->setDefault('bar', 'baz'); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfInvalidAddedType() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->addAllowedTypes('foo', 'string'); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfValidAddedType() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->addAllowedTypes('foo', 'string'); - - $this->assertNotEmpty($this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfInvalidAddedTypeMultiple() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->addAllowedTypes('foo', array('string', 'bool')); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfValidAddedTypeMultiple() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->addAllowedTypes('foo', array('string', 'bool')); - - $this->assertNotEmpty($this->resolver->resolve()); - } - - public function testAddAllowedTypesDoesNotOverwrite() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedTypes('foo', 'string'); - $this->resolver->addAllowedTypes('foo', 'bool'); - - $this->resolver->setDefault('foo', 'bar'); - - $this->assertNotEmpty($this->resolver->resolve()); - } - - public function testAddAllowedTypesDoesNotOverwrite2() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedTypes('foo', 'string'); - $this->resolver->addAllowedTypes('foo', 'bool'); - - $this->resolver->setDefault('foo', false); - - $this->assertNotEmpty($this->resolver->resolve()); - } - - //////////////////////////////////////////////////////////////////////////// - // setAllowedValues() - //////////////////////////////////////////////////////////////////////////// - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException - */ - public function testSetAllowedValuesFailsIfUnknownOption() - { - $this->resolver->setAllowedValues('foo', 'bar'); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfSetAllowedValuesFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->setAllowedValues('bar', 'baz'); - }); - - $this->resolver->setDefault('bar', 'baz'); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - * @expectedExceptionMessage The option "foo" with value 42 is invalid. Accepted values are: "bar". - */ - public function testResolveFailsIfInvalidValue() - { - $this->resolver->setDefined('foo'); - $this->resolver->setAllowedValues('foo', 'bar'); - - $this->resolver->resolve(array('foo' => 42)); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - * @expectedExceptionMessage The option "foo" with value null is invalid. Accepted values are: "bar". - */ - public function testResolveFailsIfInvalidValueIsNull() - { - $this->resolver->setDefault('foo', null); - $this->resolver->setAllowedValues('foo', 'bar'); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfInvalidValueStrict() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->setAllowedValues('foo', '42'); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfValidValue() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedValues('foo', 'bar'); - - $this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testResolveSucceedsIfValidValueIsNull() - { - $this->resolver->setDefault('foo', null); - $this->resolver->setAllowedValues('foo', null); - - $this->assertEquals(array('foo' => null), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - * @expectedExceptionMessage The option "foo" with value 42 is invalid. Accepted values are: "bar", false, null. - */ - public function testResolveFailsIfInvalidValueMultiple() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->setAllowedValues('foo', array('bar', false, null)); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfValidValueMultiple() - { - $this->resolver->setDefault('foo', 'baz'); - $this->resolver->setAllowedValues('foo', array('bar', 'baz')); - - $this->assertEquals(array('foo' => 'baz'), $this->resolver->resolve()); - } - - public function testResolveFailsIfClosureReturnsFalse() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->setAllowedValues('foo', function ($value) use (&$passedValue) { - $passedValue = $value; - - return false; - }); - - try { - $this->resolver->resolve(); - $this->fail('Should fail'); - } catch (InvalidOptionsException $e) { - } - - $this->assertSame(42, $passedValue); - } - - public function testResolveSucceedsIfClosureReturnsTrue() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedValues('foo', function ($value) use (&$passedValue) { - $passedValue = $value; - - return true; - }); - - $this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve()); - $this->assertSame('bar', $passedValue); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfAllClosuresReturnFalse() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->setAllowedValues('foo', array( - function () { return false; }, - function () { return false; }, - function () { return false; }, - )); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfAnyClosureReturnsTrue() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedValues('foo', array( - function () { return false; }, - function () { return true; }, - function () { return false; }, - )); - - $this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve()); - } - - //////////////////////////////////////////////////////////////////////////// - // addAllowedValues() - //////////////////////////////////////////////////////////////////////////// - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException - */ - public function testAddAllowedValuesFailsIfUnknownOption() - { - $this->resolver->addAllowedValues('foo', 'bar'); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfAddAllowedValuesFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->addAllowedValues('bar', 'baz'); - }); - - $this->resolver->setDefault('bar', 'baz'); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfInvalidAddedValue() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->addAllowedValues('foo', 'bar'); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfValidAddedValue() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->addAllowedValues('foo', 'bar'); - - $this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testResolveSucceedsIfValidAddedValueIsNull() - { - $this->resolver->setDefault('foo', null); - $this->resolver->addAllowedValues('foo', null); - - $this->assertEquals(array('foo' => null), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfInvalidAddedValueMultiple() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->addAllowedValues('foo', array('bar', 'baz')); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfValidAddedValueMultiple() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->addAllowedValues('foo', array('bar', 'baz')); - - $this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testAddAllowedValuesDoesNotOverwrite() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedValues('foo', 'bar'); - $this->resolver->addAllowedValues('foo', 'baz'); - - $this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testAddAllowedValuesDoesNotOverwrite2() - { - $this->resolver->setDefault('foo', 'baz'); - $this->resolver->setAllowedValues('foo', 'bar'); - $this->resolver->addAllowedValues('foo', 'baz'); - - $this->assertEquals(array('foo' => 'baz'), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testResolveFailsIfAllAddedClosuresReturnFalse() - { - $this->resolver->setDefault('foo', 42); - $this->resolver->setAllowedValues('foo', function () { return false; }); - $this->resolver->addAllowedValues('foo', function () { return false; }); - - $this->resolver->resolve(); - } - - public function testResolveSucceedsIfAnyAddedClosureReturnsTrue() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedValues('foo', function () { return false; }); - $this->resolver->addAllowedValues('foo', function () { return true; }); - - $this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testResolveSucceedsIfAnyAddedClosureReturnsTrue2() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedValues('foo', function () { return true; }); - $this->resolver->addAllowedValues('foo', function () { return false; }); - - $this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve()); - } - - //////////////////////////////////////////////////////////////////////////// - // setNormalizer() - //////////////////////////////////////////////////////////////////////////// - - public function testSetNormalizerReturnsThis() - { - $this->resolver->setDefault('foo', 'bar'); - $this->assertSame($this->resolver, $this->resolver->setNormalizer('foo', function () {})); - } - - public function testSetNormalizerClosure() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setNormalizer('foo', function () { - return 'normalized'; - }); - - $this->assertEquals(array('foo' => 'normalized'), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException - */ - public function testSetNormalizerFailsIfUnknownOption() - { - $this->resolver->setNormalizer('foo', function () {}); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfSetNormalizerFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->setNormalizer('foo', function () {}); - }); - - $this->resolver->setDefault('bar', 'baz'); - - $this->resolver->resolve(); - } - - public function testNormalizerReceivesSetOption() - { - $this->resolver->setDefault('foo', 'bar'); - - $this->resolver->setNormalizer('foo', function (Options $options, $value) { - return 'normalized['.$value.']'; - }); - - $this->assertEquals(array('foo' => 'normalized[bar]'), $this->resolver->resolve()); - } - - public function testNormalizerReceivesPassedOption() - { - $this->resolver->setDefault('foo', 'bar'); - - $this->resolver->setNormalizer('foo', function (Options $options, $value) { - return 'normalized['.$value.']'; - }); - - $resolved = $this->resolver->resolve(array('foo' => 'baz')); - - $this->assertEquals(array('foo' => 'normalized[baz]'), $resolved); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testValidateTypeBeforeNormalization() - { - $this->resolver->setDefault('foo', 'bar'); - - $this->resolver->setAllowedTypes('foo', 'int'); - - $this->resolver->setNormalizer('foo', function () { - \PHPUnit_Framework_Assert::fail('Should not be called.'); - }); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException - */ - public function testValidateValueBeforeNormalization() - { - $this->resolver->setDefault('foo', 'bar'); - - $this->resolver->setAllowedValues('foo', 'baz'); - - $this->resolver->setNormalizer('foo', function () { - \PHPUnit_Framework_Assert::fail('Should not be called.'); - }); - - $this->resolver->resolve(); - } - - public function testNormalizerCanAccessOtherOptions() - { - $this->resolver->setDefault('default', 'bar'); - $this->resolver->setDefault('norm', 'baz'); - - $this->resolver->setNormalizer('norm', function (Options $options) { - /* @var \PHPUnit_Framework_TestCase $test */ - \PHPUnit_Framework_Assert::assertSame('bar', $options['default']); - - return 'normalized'; - }); - - $this->assertEquals(array( - 'default' => 'bar', - 'norm' => 'normalized', - ), $this->resolver->resolve()); - } - - public function testNormalizerCanAccessLazyOptions() - { - $this->resolver->setDefault('lazy', function (Options $options) { - return 'bar'; - }); - $this->resolver->setDefault('norm', 'baz'); - - $this->resolver->setNormalizer('norm', function (Options $options) { - /* @var \PHPUnit_Framework_TestCase $test */ - \PHPUnit_Framework_Assert::assertEquals('bar', $options['lazy']); - - return 'normalized'; - }); - - $this->assertEquals(array( - 'lazy' => 'bar', - 'norm' => 'normalized', - ), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException - */ - public function testFailIfCyclicDependencyBetweenNormalizers() - { - $this->resolver->setDefault('norm1', 'bar'); - $this->resolver->setDefault('norm2', 'baz'); - - $this->resolver->setNormalizer('norm1', function (Options $options) { - $options['norm2']; - }); - - $this->resolver->setNormalizer('norm2', function (Options $options) { - $options['norm1']; - }); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException - */ - public function testFailIfCyclicDependencyBetweenNormalizerAndLazyOption() - { - $this->resolver->setDefault('lazy', function (Options $options) { - $options['norm']; - }); - - $this->resolver->setDefault('norm', 'baz'); - - $this->resolver->setNormalizer('norm', function (Options $options) { - $options['lazy']; - }); - - $this->resolver->resolve(); - } - - public function testCatchedExceptionFromNormalizerDoesNotCrashOptionResolver() - { - $throw = true; - - $this->resolver->setDefaults(array('catcher' => null, 'thrower' => null)); - - $this->resolver->setNormalizer('catcher', function (Options $options) { - try { - return $options['thrower']; - } catch(\Exception $e) { - return false; - } - }); - - $this->resolver->setNormalizer('thrower', function (Options $options) use (&$throw) { - if ($throw) { - $throw = false; - throw new \UnexpectedValueException('throwing'); - } - - return true; - }); - - $this->resolver->resolve(); - } - - public function testCatchedExceptionFromLazyDoesNotCrashOptionResolver() - { - $throw = true; - - $this->resolver->setDefault('catcher', function (Options $options) { - try { - return $options['thrower']; - } catch(\Exception $e) { - return false; - } - }); - - $this->resolver->setDefault('thrower', function (Options $options) use (&$throw) { - if ($throw) { - $throw = false; - throw new \UnexpectedValueException('throwing'); - } - - return true; - }); - - $this->resolver->resolve(); - } - - public function testInvokeEachNormalizerOnlyOnce() - { - $calls = 0; - - $this->resolver->setDefault('norm1', 'bar'); - $this->resolver->setDefault('norm2', 'baz'); - - $this->resolver->setNormalizer('norm1', function ($options) use (&$calls) { - \PHPUnit_Framework_Assert::assertSame(1, ++$calls); - - $options['norm2']; - }); - $this->resolver->setNormalizer('norm2', function () use (&$calls) { - \PHPUnit_Framework_Assert::assertSame(2, ++$calls); - }); - - $this->resolver->resolve(); - - $this->assertSame(2, $calls); - } - - public function testNormalizerNotCalledForUnsetOptions() - { - $this->resolver->setDefined('norm'); - - $this->resolver->setNormalizer('norm', function () { - \PHPUnit_Framework_Assert::fail('Should not be called.'); - }); - - $this->assertEmpty($this->resolver->resolve()); - } - - //////////////////////////////////////////////////////////////////////////// - // setDefaults() - //////////////////////////////////////////////////////////////////////////// - - public function testSetDefaultsReturnsThis() - { - $this->assertSame($this->resolver, $this->resolver->setDefaults(array('foo', 'bar'))); - } - - public function testSetDefaults() - { - $this->resolver->setDefault('one', '1'); - $this->resolver->setDefault('two', 'bar'); - - $this->resolver->setDefaults(array( - 'two' => '2', - 'three' => '3', - )); - - $this->assertEquals(array( - 'one' => '1', - 'two' => '2', - 'three' => '3', - ), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfSetDefaultsFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->setDefaults(array('two' => '2')); - }); - - $this->resolver->resolve(); - } - - //////////////////////////////////////////////////////////////////////////// - // remove() - //////////////////////////////////////////////////////////////////////////// - - public function testRemoveReturnsThis() - { - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame($this->resolver, $this->resolver->remove('foo')); - } - - public function testRemoveSingleOption() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setDefault('baz', 'boo'); - $this->resolver->remove('foo'); - - $this->assertSame(array('baz' => 'boo'), $this->resolver->resolve()); - } - - public function testRemoveMultipleOptions() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setDefault('baz', 'boo'); - $this->resolver->setDefault('doo', 'dam'); - - $this->resolver->remove(array('foo', 'doo')); - - $this->assertSame(array('baz' => 'boo'), $this->resolver->resolve()); - } - - public function testRemoveLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - return 'lazy'; - }); - $this->resolver->remove('foo'); - - $this->assertSame(array(), $this->resolver->resolve()); - } - - public function testRemoveNormalizer() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setNormalizer('foo', function (Options $options, $value) { - return 'normalized'; - }); - $this->resolver->remove('foo'); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testRemoveAllowedTypes() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedTypes('foo', 'int'); - $this->resolver->remove('foo'); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testRemoveAllowedValues() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedValues('foo', array('baz', 'boo')); - $this->resolver->remove('foo'); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfRemoveFromLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->remove('bar'); - }); - - $this->resolver->setDefault('bar', 'baz'); - - $this->resolver->resolve(); - } - - public function testRemoveUnknownOptionIgnored() - { - $this->assertNotNull($this->resolver->remove('foo')); - } - - //////////////////////////////////////////////////////////////////////////// - // clear() - //////////////////////////////////////////////////////////////////////////// - - public function testClearReturnsThis() - { - $this->assertSame($this->resolver, $this->resolver->clear()); - } - - public function testClearRemovesAllOptions() - { - $this->resolver->setDefault('one', 1); - $this->resolver->setDefault('two', 2); - - $this->resolver->clear(); - - $this->assertEmpty($this->resolver->resolve()); - } - - public function testClearLazyOption() - { - $this->resolver->setDefault('foo', function (Options $options) { - return 'lazy'; - }); - $this->resolver->clear(); - - $this->assertSame(array(), $this->resolver->resolve()); - } - - public function testClearNormalizer() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setNormalizer('foo', function (Options $options, $value) { - return 'normalized'; - }); - $this->resolver->clear(); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testClearAllowedTypes() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedTypes('foo', 'int'); - $this->resolver->clear(); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - public function testClearAllowedValues() - { - $this->resolver->setDefault('foo', 'bar'); - $this->resolver->setAllowedValues('foo', 'baz'); - $this->resolver->clear(); - $this->resolver->setDefault('foo', 'bar'); - - $this->assertSame(array('foo' => 'bar'), $this->resolver->resolve()); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testFailIfClearFromLazyption() - { - $this->resolver->setDefault('foo', function (Options $options) { - $options->clear(); - }); - - $this->resolver->setDefault('bar', 'baz'); - - $this->resolver->resolve(); - } - - public function testClearOptionAndNormalizer() - { - $this->resolver->setDefault('foo1', 'bar'); - $this->resolver->setNormalizer('foo1', function (Options $options) { - return ''; - }); - $this->resolver->setDefault('foo2', 'bar'); - $this->resolver->setNormalizer('foo2', function (Options $options) { - return ''; - }); - - $this->resolver->clear(); - $this->assertEmpty($this->resolver->resolve()); - } - - //////////////////////////////////////////////////////////////////////////// - // ArrayAccess - //////////////////////////////////////////////////////////////////////////// - - public function testArrayAccess() - { - $this->resolver->setDefault('default1', 0); - $this->resolver->setDefault('default2', 1); - $this->resolver->setRequired('required'); - $this->resolver->setDefined('defined'); - $this->resolver->setDefault('lazy1', function (Options $options) { - return 'lazy'; - }); - - $this->resolver->setDefault('lazy2', function (Options $options) { - \PHPUnit_Framework_Assert::assertTrue(isset($options['default1'])); - \PHPUnit_Framework_Assert::assertTrue(isset($options['default2'])); - \PHPUnit_Framework_Assert::assertTrue(isset($options['required'])); - \PHPUnit_Framework_Assert::assertTrue(isset($options['lazy1'])); - \PHPUnit_Framework_Assert::assertTrue(isset($options['lazy2'])); - \PHPUnit_Framework_Assert::assertFalse(isset($options['defined'])); - - \PHPUnit_Framework_Assert::assertSame(0, $options['default1']); - \PHPUnit_Framework_Assert::assertSame(42, $options['default2']); - \PHPUnit_Framework_Assert::assertSame('value', $options['required']); - \PHPUnit_Framework_Assert::assertSame('lazy', $options['lazy1']); - - // Obviously $options['lazy'] and $options['defined'] cannot be - // accessed - }); - - $this->resolver->resolve(array('default2' => 42, 'required' => 'value')); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testArrayAccessGetFailsOutsideResolve() - { - $this->resolver->setDefault('default', 0); - - $this->resolver['default']; - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testArrayAccessExistsFailsOutsideResolve() - { - $this->resolver->setDefault('default', 0); - - isset($this->resolver['default']); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testArrayAccessSetNotSupported() - { - $this->resolver['default'] = 0; - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testArrayAccessUnsetNotSupported() - { - $this->resolver->setDefault('default', 0); - - unset($this->resolver['default']); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\NoSuchOptionException - * @expectedExceptionMessage The option "undefined" does not exist. Defined options are: "foo", "lazy". - */ - public function testFailIfGetNonExisting() - { - $this->resolver->setDefault('foo', 'bar'); - - $this->resolver->setDefault('lazy', function (Options $options) { - $options['undefined']; - }); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\NoSuchOptionException - * @expectedExceptionMessage The optional option "defined" has no value set. You should make sure it is set with "isset" before reading it. - */ - public function testFailIfGetDefinedButUnset() - { - $this->resolver->setDefined('defined'); - - $this->resolver->setDefault('lazy', function (Options $options) { - $options['defined']; - }); - - $this->resolver->resolve(); - } - - /** - * @expectedException \Symfony\Component\OptionsResolver\Exception\OptionDefinitionException - */ - public function testFailIfCyclicDependency() - { - $this->resolver->setDefault('lazy1', function (Options $options) { - $options['lazy2']; - }); - - $this->resolver->setDefault('lazy2', function (Options $options) { - $options['lazy1']; - }); - - $this->resolver->resolve(); - } - - //////////////////////////////////////////////////////////////////////////// - // Countable - //////////////////////////////////////////////////////////////////////////// - - public function testCount() - { - $this->resolver->setDefault('default', 0); - $this->resolver->setRequired('required'); - $this->resolver->setDefined('defined'); - $this->resolver->setDefault('lazy1', function () {}); - - $this->resolver->setDefault('lazy2', function (Options $options) { - \PHPUnit_Framework_Assert::assertCount(4, $options); - }); - - $this->assertCount(4, $this->resolver->resolve(array('required' => 'value'))); - } - - /** - * In resolve() we count the options that are actually set (which may be - * only a subset of the defined options). Outside of resolve(), it's not - * clear what is counted. - * - * @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException - */ - public function testCountFailsOutsideResolve() - { - $this->resolver->setDefault('foo', 0); - $this->resolver->setRequired('bar'); - $this->resolver->setDefined('bar'); - $this->resolver->setDefault('lazy1', function () {}); - - count($this->resolver); - } -} diff --git a/library/symfony/options-resolver/phpunit.xml.dist b/library/symfony/options-resolver/phpunit.xml.dist deleted file mode 100644 index abf84614b..000000000 --- a/library/symfony/options-resolver/phpunit.xml.dist +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd" - backupGlobals="false" - colors="true" - bootstrap="vendor/autoload.php" -> - <php> - <ini name="error_reporting" value="-1" /> - </php> - - <testsuites> - <testsuite name="Symfony OptionsResolver Component Test Suite"> - <directory>./Tests/</directory> - </testsuite> - </testsuites> - - <filter> - <whitelist> - <directory>./</directory> - <exclude> - <directory>./Resources</directory> - <directory>./Tests</directory> - <directory>./vendor</directory> - </exclude> - </whitelist> - </filter> -</phpunit> diff --git a/library/symfony/process/CHANGELOG.md b/library/symfony/process/CHANGELOG.md deleted file mode 100644 index 2f3c1beb7..000000000 --- a/library/symfony/process/CHANGELOG.md +++ /dev/null @@ -1,40 +0,0 @@ -CHANGELOG -========= - -2.5.0 ------ - - * added support for PTY mode - * added the convenience method "mustRun" - * deprecation: Process::setStdin() is deprecated in favor of Process::setInput() - * deprecation: Process::getStdin() is deprecated in favor of Process::getInput() - * deprecation: Process::setInput() and ProcessBuilder::setInput() do not accept non-scalar types - -2.4.0 ------ - - * added the ability to define an idle timeout - -2.3.0 ------ - - * added ProcessUtils::escapeArgument() to fix the bug in escapeshellarg() function on Windows - * added Process::signal() - * added Process::getPid() - * added support for a TTY mode - -2.2.0 ------ - - * added ProcessBuilder::setArguments() to reset the arguments on a builder - * added a way to retrieve the standard and error output incrementally - * added Process:restart() - -2.1.0 ------ - - * added support for non-blocking processes (start(), wait(), isRunning(), stop()) - * enhanced Windows compatibility - * added Process::getExitCodeText() that returns a string representation for - the exit code returned by the process - * added ProcessBuilder diff --git a/library/symfony/process/Exception/ExceptionInterface.php b/library/symfony/process/Exception/ExceptionInterface.php deleted file mode 100644 index 75c1c9e5d..000000000 --- a/library/symfony/process/Exception/ExceptionInterface.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -/** - * Marker Interface for the Process Component. - * - * @author Johannes M. Schmitt <schmittjoh@gmail.com> - */ -interface ExceptionInterface -{ -} diff --git a/library/symfony/process/Exception/InvalidArgumentException.php b/library/symfony/process/Exception/InvalidArgumentException.php deleted file mode 100644 index 926ee2118..000000000 --- a/library/symfony/process/Exception/InvalidArgumentException.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -/** - * InvalidArgumentException for the Process Component. - * - * @author Romain Neutron <imprec@gmail.com> - */ -class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface -{ -} diff --git a/library/symfony/process/Exception/LogicException.php b/library/symfony/process/Exception/LogicException.php deleted file mode 100644 index be3d490dd..000000000 --- a/library/symfony/process/Exception/LogicException.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -/** - * LogicException for the Process Component. - * - * @author Romain Neutron <imprec@gmail.com> - */ -class LogicException extends \LogicException implements ExceptionInterface -{ -} diff --git a/library/symfony/process/Exception/ProcessFailedException.php b/library/symfony/process/Exception/ProcessFailedException.php deleted file mode 100644 index 328acfde5..000000000 --- a/library/symfony/process/Exception/ProcessFailedException.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -use Symfony\Component\Process\Process; - -/** - * Exception for failed processes. - * - * @author Johannes M. Schmitt <schmittjoh@gmail.com> - */ -class ProcessFailedException extends RuntimeException -{ - private $process; - - public function __construct(Process $process) - { - if ($process->isSuccessful()) { - throw new InvalidArgumentException('Expected a failed process, but the given process was successful.'); - } - - $error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s", - $process->getCommandLine(), - $process->getExitCode(), - $process->getExitCodeText(), - $process->getWorkingDirectory() - ); - - if (!$process->isOutputDisabled()) { - $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", - $process->getOutput(), - $process->getErrorOutput() - ); - } - - parent::__construct($error); - - $this->process = $process; - } - - public function getProcess() - { - return $this->process; - } -} diff --git a/library/symfony/process/Exception/ProcessTimedOutException.php b/library/symfony/process/Exception/ProcessTimedOutException.php deleted file mode 100644 index d45114696..000000000 --- a/library/symfony/process/Exception/ProcessTimedOutException.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -use Symfony\Component\Process\Process; - -/** - * Exception that is thrown when a process times out. - * - * @author Johannes M. Schmitt <schmittjoh@gmail.com> - */ -class ProcessTimedOutException extends RuntimeException -{ - const TYPE_GENERAL = 1; - const TYPE_IDLE = 2; - - private $process; - private $timeoutType; - - public function __construct(Process $process, $timeoutType) - { - $this->process = $process; - $this->timeoutType = $timeoutType; - - parent::__construct(sprintf( - 'The process "%s" exceeded the timeout of %s seconds.', - $process->getCommandLine(), - $this->getExceededTimeout() - )); - } - - public function getProcess() - { - return $this->process; - } - - public function isGeneralTimeout() - { - return $this->timeoutType === self::TYPE_GENERAL; - } - - public function isIdleTimeout() - { - return $this->timeoutType === self::TYPE_IDLE; - } - - public function getExceededTimeout() - { - switch ($this->timeoutType) { - case self::TYPE_GENERAL: - return $this->process->getTimeout(); - - case self::TYPE_IDLE: - return $this->process->getIdleTimeout(); - - default: - throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)); - } - } -} diff --git a/library/symfony/process/Exception/RuntimeException.php b/library/symfony/process/Exception/RuntimeException.php deleted file mode 100644 index adead2536..000000000 --- a/library/symfony/process/Exception/RuntimeException.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Exception; - -/** - * RuntimeException for the Process Component. - * - * @author Johannes M. Schmitt <schmittjoh@gmail.com> - */ -class RuntimeException extends \RuntimeException implements ExceptionInterface -{ -} diff --git a/library/symfony/process/ExecutableFinder.php b/library/symfony/process/ExecutableFinder.php deleted file mode 100644 index fa11cb6e4..000000000 --- a/library/symfony/process/ExecutableFinder.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -/** - * Generic executable finder. - * - * @author Fabien Potencier <fabien@symfony.com> - * @author Johannes M. Schmitt <schmittjoh@gmail.com> - */ -class ExecutableFinder -{ - private $suffixes = array('.exe', '.bat', '.cmd', '.com'); - - /** - * Replaces default suffixes of executable. - * - * @param array $suffixes - */ - public function setSuffixes(array $suffixes) - { - $this->suffixes = $suffixes; - } - - /** - * Adds new possible suffix to check for executable. - * - * @param string $suffix - */ - public function addSuffix($suffix) - { - $this->suffixes[] = $suffix; - } - - /** - * Finds an executable by name. - * - * @param string $name The executable name (without the extension) - * @param string $default The default to return if no executable is found - * @param array $extraDirs Additional dirs to check into - * - * @return string The executable path or default value - */ - public function find($name, $default = null, array $extraDirs = array()) - { - if (ini_get('open_basedir')) { - $searchPath = explode(PATH_SEPARATOR, ini_get('open_basedir')); - $dirs = array(); - foreach ($searchPath as $path) { - // Silencing against https://bugs.php.net/69240 - if (@is_dir($path)) { - $dirs[] = $path; - } else { - if (basename($path) == $name && is_executable($path)) { - return $path; - } - } - } - } else { - $dirs = array_merge( - explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), - $extraDirs - ); - } - - $suffixes = array(''); - if ('\\' === DIRECTORY_SEPARATOR) { - $pathExt = getenv('PATHEXT'); - $suffixes = $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes; - } - foreach ($suffixes as $suffix) { - foreach ($dirs as $dir) { - if (is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === DIRECTORY_SEPARATOR || is_executable($file))) { - return $file; - } - } - } - - return $default; - } -} diff --git a/library/symfony/process/LICENSE b/library/symfony/process/LICENSE deleted file mode 100644 index 43028bc60..000000000 --- a/library/symfony/process/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2004-2015 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/library/symfony/process/PhpExecutableFinder.php b/library/symfony/process/PhpExecutableFinder.php deleted file mode 100644 index fb297825f..000000000 --- a/library/symfony/process/PhpExecutableFinder.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -/** - * An executable finder specifically designed for the PHP executable. - * - * @author Fabien Potencier <fabien@symfony.com> - * @author Johannes M. Schmitt <schmittjoh@gmail.com> - */ -class PhpExecutableFinder -{ - private $executableFinder; - - public function __construct() - { - $this->executableFinder = new ExecutableFinder(); - } - - /** - * Finds The PHP executable. - * - * @param bool $includeArgs Whether or not include command arguments - * - * @return string|false The PHP executable path or false if it cannot be found - */ - public function find($includeArgs = true) - { - $args = $this->findArguments(); - $args = $includeArgs && $args ? ' '.implode(' ', $args) : ''; - - // HHVM support - if (defined('HHVM_VERSION')) { - return (getenv('PHP_BINARY') ?: PHP_BINARY).$args; - } - - // PHP_BINARY return the current sapi executable - if (defined('PHP_BINARY') && PHP_BINARY && in_array(PHP_SAPI, array('cli', 'cli-server', 'phpdbg')) && is_file(PHP_BINARY)) { - return PHP_BINARY.$args; - } - - if ($php = getenv('PHP_PATH')) { - if (!is_executable($php)) { - return false; - } - - return $php; - } - - if ($php = getenv('PHP_PEAR_PHP_BIN')) { - if (is_executable($php)) { - return $php; - } - } - - $dirs = array(PHP_BINDIR); - if ('\\' === DIRECTORY_SEPARATOR) { - $dirs[] = 'C:\xampp\php\\'; - } - - return $this->executableFinder->find('php', false, $dirs); - } - - /** - * Finds the PHP executable arguments. - * - * @return array The PHP executable arguments - */ - public function findArguments() - { - $arguments = array(); - - if (defined('HHVM_VERSION')) { - $arguments[] = '--php'; - } elseif ('phpdbg' === PHP_SAPI) { - $arguments[] = '-qrr'; - } - - return $arguments; - } -} diff --git a/library/symfony/process/PhpProcess.php b/library/symfony/process/PhpProcess.php deleted file mode 100644 index 8333412f4..000000000 --- a/library/symfony/process/PhpProcess.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -use Symfony\Component\Process\Exception\RuntimeException; - -/** - * PhpProcess runs a PHP script in an independent process. - * - * $p = new PhpProcess('<?php echo "foo"; ?>'); - * $p->run(); - * print $p->getOutput()."\n"; - * - * @author Fabien Potencier <fabien@symfony.com> - */ -class PhpProcess extends Process -{ - /** - * Constructor. - * - * @param string $script The PHP script to run (as a string) - * @param string|null $cwd The working directory or null to use the working dir of the current PHP process - * @param array|null $env The environment variables or null to use the same environment as the current PHP process - * @param int $timeout The timeout in seconds - * @param array $options An array of options for proc_open - */ - public function __construct($script, $cwd = null, array $env = null, $timeout = 120, array $options = array()) - { - $executableFinder = new PhpExecutableFinder(); - if (false === $php = $executableFinder->find()) { - $php = null; - } - if ('phpdbg' === PHP_SAPI) { - $file = tempnam(sys_get_temp_dir(), 'dbg'); - file_put_contents($file, $script); - register_shutdown_function('unlink', $file); - $php .= ' '.ProcessUtils::escapeArgument($file); - $script = null; - } - - parent::__construct($php, $cwd, $env, $script, $timeout, $options); - } - - /** - * Sets the path to the PHP binary to use. - */ - public function setPhpBinary($php) - { - $this->setCommandLine($php); - } - - /** - * {@inheritdoc} - */ - public function start($callback = null) - { - if (null === $this->getCommandLine()) { - throw new RuntimeException('Unable to find the PHP executable.'); - } - - parent::start($callback); - } -} diff --git a/library/symfony/process/Pipes/AbstractPipes.php b/library/symfony/process/Pipes/AbstractPipes.php deleted file mode 100644 index 1ca85739f..000000000 --- a/library/symfony/process/Pipes/AbstractPipes.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Pipes; - -/** - * @author Romain Neutron <imprec@gmail.com> - * - * @internal - */ -abstract class AbstractPipes implements PipesInterface -{ - /** @var array */ - public $pipes = array(); - - /** @var string */ - protected $inputBuffer = ''; - /** @var resource|null */ - protected $input; - - /** @var bool */ - private $blocked = true; - - /** - * {@inheritdoc} - */ - public function close() - { - foreach ($this->pipes as $pipe) { - fclose($pipe); - } - $this->pipes = array(); - } - - /** - * Returns true if a system call has been interrupted. - * - * @return bool - */ - protected function hasSystemCallBeenInterrupted() - { - $lastError = error_get_last(); - - // stream_select returns false when the `select` system call is interrupted by an incoming signal - return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call'); - } - - /** - * Unblocks streams. - */ - protected function unblock() - { - if (!$this->blocked) { - return; - } - - foreach ($this->pipes as $pipe) { - stream_set_blocking($pipe, 0); - } - if (null !== $this->input) { - stream_set_blocking($this->input, 0); - } - - $this->blocked = false; - } -} diff --git a/library/symfony/process/Pipes/PipesInterface.php b/library/symfony/process/Pipes/PipesInterface.php deleted file mode 100644 index 09d3f61d6..000000000 --- a/library/symfony/process/Pipes/PipesInterface.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Pipes; - -/** - * PipesInterface manages descriptors and pipes for the use of proc_open. - * - * @author Romain Neutron <imprec@gmail.com> - * - * @internal - */ -interface PipesInterface -{ - const CHUNK_SIZE = 16384; - - /** - * Returns an array of descriptors for the use of proc_open. - * - * @return array - */ - public function getDescriptors(); - - /** - * Returns an array of filenames indexed by their related stream in case these pipes use temporary files. - * - * @return string[] - */ - public function getFiles(); - - /** - * Reads data in file handles and pipes. - * - * @param bool $blocking Whether to use blocking calls or not. - * @param bool $close Whether to close pipes if they've reached EOF. - * - * @return string[] An array of read data indexed by their fd. - */ - public function readAndWrite($blocking, $close = false); - - /** - * Returns if the current state has open file handles or pipes. - * - * @return bool - */ - public function areOpen(); - - /** - * Closes file handles and pipes. - */ - public function close(); -} diff --git a/library/symfony/process/Pipes/UnixPipes.php b/library/symfony/process/Pipes/UnixPipes.php deleted file mode 100644 index f8a0d1997..000000000 --- a/library/symfony/process/Pipes/UnixPipes.php +++ /dev/null @@ -1,214 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Pipes; - -use Symfony\Component\Process\Process; - -/** - * UnixPipes implementation uses unix pipes as handles. - * - * @author Romain Neutron <imprec@gmail.com> - * - * @internal - */ -class UnixPipes extends AbstractPipes -{ - /** @var bool */ - private $ttyMode; - /** @var bool */ - private $ptyMode; - /** @var bool */ - private $disableOutput; - - public function __construct($ttyMode, $ptyMode, $input, $disableOutput) - { - $this->ttyMode = (bool) $ttyMode; - $this->ptyMode = (bool) $ptyMode; - $this->disableOutput = (bool) $disableOutput; - - if (is_resource($input)) { - $this->input = $input; - } else { - $this->inputBuffer = (string) $input; - } - } - - public function __destruct() - { - $this->close(); - } - - /** - * {@inheritdoc} - */ - public function getDescriptors() - { - if ($this->disableOutput) { - $nullstream = fopen('/dev/null', 'c'); - - return array( - array('pipe', 'r'), - $nullstream, - $nullstream, - ); - } - - if ($this->ttyMode) { - return array( - array('file', '/dev/tty', 'r'), - array('file', '/dev/tty', 'w'), - array('file', '/dev/tty', 'w'), - ); - } - - if ($this->ptyMode && Process::isPtySupported()) { - return array( - array('pty'), - array('pty'), - array('pty'), - ); - } - - return array( - array('pipe', 'r'), - array('pipe', 'w'), // stdout - array('pipe', 'w'), // stderr - ); - } - - /** - * {@inheritdoc} - */ - public function getFiles() - { - return array(); - } - - /** - * {@inheritdoc} - */ - public function readAndWrite($blocking, $close = false) - { - // only stdin is left open, job has been done ! - // we can now close it - if (1 === count($this->pipes) && array(0) === array_keys($this->pipes)) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - - if (empty($this->pipes)) { - return array(); - } - - $this->unblock(); - - $read = array(); - - if (null !== $this->input) { - // if input is a resource, let's add it to stream_select argument to - // fill a buffer - $r = array_merge($this->pipes, array('input' => $this->input)); - } else { - $r = $this->pipes; - } - // discard read on stdin - unset($r[0]); - - $w = isset($this->pipes[0]) ? array($this->pipes[0]) : null; - $e = null; - - // let's have a look if something changed in streams - if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { - // if a system call has been interrupted, forget about it, let's try again - // otherwise, an error occurred, let's reset pipes - if (!$this->hasSystemCallBeenInterrupted()) { - $this->pipes = array(); - } - - return $read; - } - - // nothing has changed - if (0 === $n) { - return $read; - } - - foreach ($r as $pipe) { - // prior PHP 5.4 the array passed to stream_select is modified and - // lose key association, we have to find back the key - $type = (false !== $found = array_search($pipe, $this->pipes)) ? $found : 'input'; - $data = ''; - while ('' !== $dataread = (string) fread($pipe, self::CHUNK_SIZE)) { - $data .= $dataread; - } - - if ('' !== $data) { - if ($type === 'input') { - $this->inputBuffer .= $data; - } else { - $read[$type] = $data; - } - } - - if (false === $data || (true === $close && feof($pipe) && '' === $data)) { - if ($type === 'input') { - // no more data to read on input resource - // use an empty buffer in the next reads - $this->input = null; - } else { - fclose($this->pipes[$type]); - unset($this->pipes[$type]); - } - } - } - - if (null !== $w && 0 < count($w)) { - while (strlen($this->inputBuffer)) { - $written = fwrite($w[0], $this->inputBuffer, 2 << 18); // write 512k - if ($written > 0) { - $this->inputBuffer = (string) substr($this->inputBuffer, $written); - } else { - break; - } - } - } - - // no input to read on resource, buffer is empty and stdin still open - if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - - return $read; - } - - /** - * {@inheritdoc} - */ - public function areOpen() - { - return (bool) $this->pipes; - } - - /** - * Creates a new UnixPipes instance. - * - * @param Process $process - * @param string|resource $input - * - * @return UnixPipes - */ - public static function create(Process $process, $input) - { - return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled()); - } -} diff --git a/library/symfony/process/Pipes/WindowsPipes.php b/library/symfony/process/Pipes/WindowsPipes.php deleted file mode 100644 index 1472f8c6c..000000000 --- a/library/symfony/process/Pipes/WindowsPipes.php +++ /dev/null @@ -1,253 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Pipes; - -use Symfony\Component\Process\Process; -use Symfony\Component\Process\Exception\RuntimeException; - -/** - * WindowsPipes implementation uses temporary files as handles. - * - * @see https://bugs.php.net/bug.php?id=51800 - * @see https://bugs.php.net/bug.php?id=65650 - * - * @author Romain Neutron <imprec@gmail.com> - * - * @internal - */ -class WindowsPipes extends AbstractPipes -{ - /** @var array */ - private $files = array(); - /** @var array */ - private $fileHandles = array(); - /** @var array */ - private $readBytes = array( - Process::STDOUT => 0, - Process::STDERR => 0, - ); - /** @var bool */ - private $disableOutput; - - public function __construct($disableOutput, $input) - { - $this->disableOutput = (bool) $disableOutput; - - if (!$this->disableOutput) { - // Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big. - // Workaround for this problem is to use temporary files instead of pipes on Windows platform. - // - // @see https://bugs.php.net/bug.php?id=51800 - $this->files = array( - Process::STDOUT => tempnam(sys_get_temp_dir(), 'out_sf_proc'), - Process::STDERR => tempnam(sys_get_temp_dir(), 'err_sf_proc'), - ); - foreach ($this->files as $offset => $file) { - if (false === $file || false === $this->fileHandles[$offset] = fopen($file, 'rb')) { - throw new RuntimeException('A temporary file could not be opened to write the process output to, verify that your TEMP environment variable is writable'); - } - } - } - - if (is_resource($input)) { - $this->input = $input; - } else { - $this->inputBuffer = $input; - } - } - - public function __destruct() - { - $this->close(); - $this->removeFiles(); - } - - /** - * {@inheritdoc} - */ - public function getDescriptors() - { - if ($this->disableOutput) { - $nullstream = fopen('NUL', 'c'); - - return array( - array('pipe', 'r'), - $nullstream, - $nullstream, - ); - } - - // We're not using pipe on Windows platform as it hangs (https://bugs.php.net/bug.php?id=51800) - // We're not using file handles as it can produce corrupted output https://bugs.php.net/bug.php?id=65650 - // So we redirect output within the commandline and pass the nul device to the process - return array( - array('pipe', 'r'), - array('file', 'NUL', 'w'), - array('file', 'NUL', 'w'), - ); - } - - /** - * {@inheritdoc} - */ - public function getFiles() - { - return $this->files; - } - - /** - * {@inheritdoc} - */ - public function readAndWrite($blocking, $close = false) - { - $this->write($blocking, $close); - - $read = array(); - $fh = $this->fileHandles; - foreach ($fh as $type => $fileHandle) { - if (0 !== fseek($fileHandle, $this->readBytes[$type])) { - continue; - } - $data = ''; - $dataread = null; - while (!feof($fileHandle)) { - if (false !== $dataread = fread($fileHandle, self::CHUNK_SIZE)) { - $data .= $dataread; - } - } - if (0 < $length = strlen($data)) { - $this->readBytes[$type] += $length; - $read[$type] = $data; - } - - if (false === $dataread || (true === $close && feof($fileHandle) && '' === $data)) { - fclose($this->fileHandles[$type]); - unset($this->fileHandles[$type]); - } - } - - return $read; - } - - /** - * {@inheritdoc} - */ - public function areOpen() - { - return (bool) $this->pipes && (bool) $this->fileHandles; - } - - /** - * {@inheritdoc} - */ - public function close() - { - parent::close(); - foreach ($this->fileHandles as $handle) { - fclose($handle); - } - $this->fileHandles = array(); - } - - /** - * Creates a new WindowsPipes instance. - * - * @param Process $process The process - * @param $input - * - * @return WindowsPipes - */ - public static function create(Process $process, $input) - { - return new static($process->isOutputDisabled(), $input); - } - - /** - * Removes temporary files. - */ - private function removeFiles() - { - foreach ($this->files as $filename) { - if (file_exists($filename)) { - @unlink($filename); - } - } - $this->files = array(); - } - - /** - * Writes input to stdin. - * - * @param bool $blocking - * @param bool $close - */ - private function write($blocking, $close) - { - if (empty($this->pipes)) { - return; - } - - $this->unblock(); - - $r = null !== $this->input ? array('input' => $this->input) : null; - $w = isset($this->pipes[0]) ? array($this->pipes[0]) : null; - $e = null; - - // let's have a look if something changed in streams - if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { - // if a system call has been interrupted, forget about it, let's try again - // otherwise, an error occurred, let's reset pipes - if (!$this->hasSystemCallBeenInterrupted()) { - $this->pipes = array(); - } - - return; - } - - // nothing has changed - if (0 === $n) { - return; - } - - if (null !== $w && 0 < count($r)) { - $data = ''; - while ($dataread = fread($r['input'], self::CHUNK_SIZE)) { - $data .= $dataread; - } - - $this->inputBuffer .= $data; - - if (false === $data || (true === $close && feof($r['input']) && '' === $data)) { - // no more data to read on input resource - // use an empty buffer in the next reads - $this->input = null; - } - } - - if (null !== $w && 0 < count($w)) { - while (strlen($this->inputBuffer)) { - $written = fwrite($w[0], $this->inputBuffer, 2 << 18); - if ($written > 0) { - $this->inputBuffer = (string) substr($this->inputBuffer, $written); - } else { - break; - } - } - } - - // no input to read on resource, buffer is empty and stdin still open - if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) { - fclose($this->pipes[0]); - unset($this->pipes[0]); - } - } -} diff --git a/library/symfony/process/Process.php b/library/symfony/process/Process.php deleted file mode 100644 index 003b6b7e5..000000000 --- a/library/symfony/process/Process.php +++ /dev/null @@ -1,1515 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -use Symfony\Component\Process\Exception\InvalidArgumentException; -use Symfony\Component\Process\Exception\LogicException; -use Symfony\Component\Process\Exception\ProcessFailedException; -use Symfony\Component\Process\Exception\ProcessTimedOutException; -use Symfony\Component\Process\Exception\RuntimeException; -use Symfony\Component\Process\Pipes\PipesInterface; -use Symfony\Component\Process\Pipes\UnixPipes; -use Symfony\Component\Process\Pipes\WindowsPipes; - -/** - * Process is a thin wrapper around proc_* functions to easily - * start independent PHP processes. - * - * @author Fabien Potencier <fabien@symfony.com> - * @author Romain Neutron <imprec@gmail.com> - */ -class Process -{ - const ERR = 'err'; - const OUT = 'out'; - - const STATUS_READY = 'ready'; - const STATUS_STARTED = 'started'; - const STATUS_TERMINATED = 'terminated'; - - const STDIN = 0; - const STDOUT = 1; - const STDERR = 2; - - // Timeout Precision in seconds. - const TIMEOUT_PRECISION = 0.2; - - private $callback; - private $commandline; - private $cwd; - private $env; - private $input; - private $starttime; - private $lastOutputTime; - private $timeout; - private $idleTimeout; - private $options; - private $exitcode; - private $fallbackExitcode; - private $processInformation; - private $outputDisabled = false; - private $stdout; - private $stderr; - private $enhanceWindowsCompatibility = true; - private $enhanceSigchildCompatibility; - private $process; - private $status = self::STATUS_READY; - private $incrementalOutputOffset = 0; - private $incrementalErrorOutputOffset = 0; - private $tty; - private $pty; - - private $useFileHandles = false; - /** @var PipesInterface */ - private $processPipes; - - private $latestSignal; - - private static $sigchild; - - /** - * Exit codes translation table. - * - * User-defined errors must use exit codes in the 64-113 range. - * - * @var array - */ - public static $exitCodes = array( - 0 => 'OK', - 1 => 'General error', - 2 => 'Misuse of shell builtins', - - 126 => 'Invoked command cannot execute', - 127 => 'Command not found', - 128 => 'Invalid exit argument', - - // signals - 129 => 'Hangup', - 130 => 'Interrupt', - 131 => 'Quit and dump core', - 132 => 'Illegal instruction', - 133 => 'Trace/breakpoint trap', - 134 => 'Process aborted', - 135 => 'Bus error: "access to undefined portion of memory object"', - 136 => 'Floating point exception: "erroneous arithmetic operation"', - 137 => 'Kill (terminate immediately)', - 138 => 'User-defined 1', - 139 => 'Segmentation violation', - 140 => 'User-defined 2', - 141 => 'Write to pipe with no one reading', - 142 => 'Signal raised by alarm', - 143 => 'Termination (request to terminate)', - // 144 - not defined - 145 => 'Child process terminated, stopped (or continued*)', - 146 => 'Continue if stopped', - 147 => 'Stop executing temporarily', - 148 => 'Terminal stop signal', - 149 => 'Background process attempting to read from tty ("in")', - 150 => 'Background process attempting to write to tty ("out")', - 151 => 'Urgent data available on socket', - 152 => 'CPU time limit exceeded', - 153 => 'File size limit exceeded', - 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"', - 155 => 'Profiling timer expired', - // 156 - not defined - 157 => 'Pollable event', - // 158 - not defined - 159 => 'Bad syscall', - ); - - /** - * Constructor. - * - * @param string $commandline The command line to run - * @param string|null $cwd The working directory or null to use the working dir of the current PHP process - * @param array|null $env The environment variables or null to use the same environment as the current PHP process - * @param string|null $input The input - * @param int|float|null $timeout The timeout in seconds or null to disable - * @param array $options An array of options for proc_open - * - * @throws RuntimeException When proc_open is not installed - */ - public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 120, array $options = array()) - { - if (!function_exists('proc_open')) { - throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); - } - - $this->commandline = $commandline; - $this->cwd = $cwd; - - // on Windows, if the cwd changed via chdir(), proc_open defaults to the dir where PHP was started - // on Gnu/Linux, PHP builds with --enable-maintainer-zts are also affected - // @see : https://bugs.php.net/bug.php?id=51800 - // @see : https://bugs.php.net/bug.php?id=50524 - if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\' === DIRECTORY_SEPARATOR)) { - $this->cwd = getcwd(); - } - if (null !== $env) { - $this->setEnv($env); - } - - $this->input = $input; - $this->setTimeout($timeout); - $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR; - $this->pty = false; - $this->enhanceWindowsCompatibility = true; - $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled(); - $this->options = array_replace(array('suppress_errors' => true, 'binary_pipes' => true), $options); - } - - public function __destruct() - { - // stop() will check if we have a process running. - $this->stop(); - } - - public function __clone() - { - $this->resetProcessData(); - } - - /** - * Runs the process. - * - * The callback receives the type of output (out or err) and - * some bytes from the output in real-time. It allows to have feedback - * from the independent process during execution. - * - * The STDOUT and STDERR are also available after the process is finished - * via the getOutput() and getErrorOutput() methods. - * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - * - * @return int The exit status code - * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process stopped after receiving signal - * @throws LogicException In case a callback is provided and output has been disabled - */ - public function run($callback = null) - { - $this->start($callback); - - return $this->wait(); - } - - /** - * Runs the process. - * - * This is identical to run() except that an exception is thrown if the process - * exits with a non-zero exit code. - * - * @param callable|null $callback - * - * @return self - * - * @throws RuntimeException if PHP was compiled with --enable-sigchild and the enhanced sigchild compatibility mode is not enabled - * @throws ProcessFailedException if the process didn't terminate successfully - */ - public function mustRun($callback = null) - { - if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); - } - - if (0 !== $this->run($callback)) { - throw new ProcessFailedException($this); - } - - return $this; - } - - /** - * Starts the process and returns after writing the input to STDIN. - * - * This method blocks until all STDIN data is sent to the process then it - * returns while the process runs in the background. - * - * The termination of the process can be awaited with wait(). - * - * The callback receives the type of output (out or err) and some bytes from - * the output in real-time while writing the standard input to the process. - * It allows to have feedback from the independent process during execution. - * If there is no callback passed, the wait() method can be called - * with true as a second parameter then the callback will get all data occurred - * in (and since) the start call. - * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process is already running - * @throws LogicException In case a callback is provided and output has been disabled - */ - public function start($callback = null) - { - if ($this->isRunning()) { - throw new RuntimeException('Process is already running'); - } - if ($this->outputDisabled && null !== $callback) { - throw new LogicException('Output has been disabled, enable it to allow the use of a callback.'); - } - - $this->resetProcessData(); - $this->starttime = $this->lastOutputTime = microtime(true); - $this->callback = $this->buildCallback($callback); - $descriptors = $this->getDescriptors(); - - $commandline = $this->commandline; - - if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) { - $commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')'; - foreach ($this->processPipes->getFiles() as $offset => $filename) { - $commandline .= ' '.$offset.'>'.ProcessUtils::escapeArgument($filename); - } - $commandline .= '"'; - - if (!isset($this->options['bypass_shell'])) { - $this->options['bypass_shell'] = true; - } - } - - $ptsWorkaround = null; - - if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { - // Workaround for the bug, when PTS functionality is enabled. - // @see : https://bugs.php.net/69442 - $ptsWorkaround = fopen(__FILE__, 'r'); - } - - $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); - - if ($ptsWorkaround) { - fclose($ptsWorkaround); - } - - if (!is_resource($this->process)) { - throw new RuntimeException('Unable to launch a new process.'); - } - $this->status = self::STATUS_STARTED; - - if ($this->tty) { - return; - } - - $this->updateStatus(false); - $this->checkTimeout(); - } - - /** - * Restarts the process. - * - * Be warned that the process is cloned before being started. - * - * @param callable|null $callback A PHP callback to run whenever there is some - * output available on STDOUT or STDERR - * - * @return Process The new process - * - * @throws RuntimeException When process can't be launched - * @throws RuntimeException When process is already running - * - * @see start() - */ - public function restart($callback = null) - { - if ($this->isRunning()) { - throw new RuntimeException('Process is already running'); - } - - $process = clone $this; - $process->start($callback); - - return $process; - } - - /** - * Waits for the process to terminate. - * - * The callback receives the type of output (out or err) and some bytes - * from the output in real-time while writing the standard input to the process. - * It allows to have feedback from the independent process during execution. - * - * @param callable|null $callback A valid PHP callback - * - * @return int The exitcode of the process - * - * @throws RuntimeException When process timed out - * @throws RuntimeException When process stopped after receiving signal - * @throws LogicException When process is not yet started - */ - public function wait($callback = null) - { - $this->requireProcessIsStarted(__FUNCTION__); - - $this->updateStatus(false); - if (null !== $callback) { - $this->callback = $this->buildCallback($callback); - } - - do { - $this->checkTimeout(); - $running = '\\' === DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen(); - $close = '\\' !== DIRECTORY_SEPARATOR || !$running; - $this->readPipes(true, $close); - } while ($running); - - while ($this->isRunning()) { - usleep(1000); - } - - if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) { - throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig'])); - } - - return $this->exitcode; - } - - /** - * Returns the Pid (process identifier), if applicable. - * - * @return int|null The process id if running, null otherwise - * - * @throws RuntimeException In case --enable-sigchild is activated - */ - public function getPid() - { - if ($this->isSigchildEnabled()) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved.'); - } - - $this->updateStatus(false); - - return $this->isRunning() ? $this->processInformation['pid'] : null; - } - - /** - * Sends a POSIX signal to the process. - * - * @param int $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php) - * - * @return Process - * - * @throws LogicException In case the process is not running - * @throws RuntimeException In case --enable-sigchild is activated - * @throws RuntimeException In case of failure - */ - public function signal($signal) - { - $this->doSignal($signal, true); - - return $this; - } - - /** - * Disables fetching output and error output from the underlying process. - * - * @return Process - * - * @throws RuntimeException In case the process is already running - * @throws LogicException if an idle timeout is set - */ - public function disableOutput() - { - if ($this->isRunning()) { - throw new RuntimeException('Disabling output while the process is running is not possible.'); - } - if (null !== $this->idleTimeout) { - throw new LogicException('Output can not be disabled while an idle timeout is set.'); - } - - $this->outputDisabled = true; - - return $this; - } - - /** - * Enables fetching output and error output from the underlying process. - * - * @return Process - * - * @throws RuntimeException In case the process is already running - */ - public function enableOutput() - { - if ($this->isRunning()) { - throw new RuntimeException('Enabling output while the process is running is not possible.'); - } - - $this->outputDisabled = false; - - return $this; - } - - /** - * Returns true in case the output is disabled, false otherwise. - * - * @return bool - */ - public function isOutputDisabled() - { - return $this->outputDisabled; - } - - /** - * Returns the current output of the process (STDOUT). - * - * @return string The process output - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - */ - public function getOutput() - { - if ($this->outputDisabled) { - throw new LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted(__FUNCTION__); - - $this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true); - - return $this->stdout; - } - - /** - * Returns the output incrementally. - * - * In comparison with the getOutput method which always return the whole - * output, this one returns the new output since the last call. - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - * - * @return string The process output since the last call - */ - public function getIncrementalOutput() - { - $this->requireProcessIsStarted(__FUNCTION__); - - $data = $this->getOutput(); - - $latest = substr($data, $this->incrementalOutputOffset); - - if (false === $latest) { - return ''; - } - - $this->incrementalOutputOffset = strlen($data); - - return $latest; - } - - /** - * Clears the process output. - * - * @return Process - */ - public function clearOutput() - { - $this->stdout = ''; - $this->incrementalOutputOffset = 0; - - return $this; - } - - /** - * Returns the current error output of the process (STDERR). - * - * @return string The process error output - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - */ - public function getErrorOutput() - { - if ($this->outputDisabled) { - throw new LogicException('Output has been disabled.'); - } - - $this->requireProcessIsStarted(__FUNCTION__); - - $this->readPipes(false, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true); - - return $this->stderr; - } - - /** - * Returns the errorOutput incrementally. - * - * In comparison with the getErrorOutput method which always return the - * whole error output, this one returns the new error output since the last - * call. - * - * @throws LogicException in case the output has been disabled - * @throws LogicException In case the process is not started - * - * @return string The process error output since the last call - */ - public function getIncrementalErrorOutput() - { - $this->requireProcessIsStarted(__FUNCTION__); - - $data = $this->getErrorOutput(); - - $latest = substr($data, $this->incrementalErrorOutputOffset); - - if (false === $latest) { - return ''; - } - - $this->incrementalErrorOutputOffset = strlen($data); - - return $latest; - } - - /** - * Clears the process output. - * - * @return Process - */ - public function clearErrorOutput() - { - $this->stderr = ''; - $this->incrementalErrorOutputOffset = 0; - - return $this; - } - - /** - * Returns the exit code returned by the process. - * - * @return null|int The exit status code, null if the Process is not terminated - * - * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled - */ - public function getExitCode() - { - if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); - } - - $this->updateStatus(false); - - return $this->exitcode; - } - - /** - * Returns a string representation for the exit code returned by the process. - * - * This method relies on the Unix exit code status standardization - * and might not be relevant for other operating systems. - * - * @return null|string A string representation for the exit status code, null if the Process is not terminated. - * - * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled - * - * @see http://tldp.org/LDP/abs/html/exitcodes.html - * @see http://en.wikipedia.org/wiki/Unix_signal - */ - public function getExitCodeText() - { - if (null === $exitcode = $this->getExitCode()) { - return; - } - - return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error'; - } - - /** - * Checks if the process ended successfully. - * - * @return bool true if the process ended successfully, false otherwise - */ - public function isSuccessful() - { - return 0 === $this->getExitCode(); - } - - /** - * Returns true if the child process has been terminated by an uncaught signal. - * - * It always returns false on Windows. - * - * @return bool - * - * @throws RuntimeException In case --enable-sigchild is activated - * @throws LogicException In case the process is not terminated - */ - public function hasBeenSignaled() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - if ($this->isSigchildEnabled()) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); - } - - $this->updateStatus(false); - - return $this->processInformation['signaled']; - } - - /** - * Returns the number of the signal that caused the child process to terminate its execution. - * - * It is only meaningful if hasBeenSignaled() returns true. - * - * @return int - * - * @throws RuntimeException In case --enable-sigchild is activated - * @throws LogicException In case the process is not terminated - */ - public function getTermSignal() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - if ($this->isSigchildEnabled()) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); - } - - $this->updateStatus(false); - - return $this->processInformation['termsig']; - } - - /** - * Returns true if the child process has been stopped by a signal. - * - * It always returns false on Windows. - * - * @return bool - * - * @throws LogicException In case the process is not terminated - */ - public function hasBeenStopped() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - $this->updateStatus(false); - - return $this->processInformation['stopped']; - } - - /** - * Returns the number of the signal that caused the child process to stop its execution. - * - * It is only meaningful if hasBeenStopped() returns true. - * - * @return int - * - * @throws LogicException In case the process is not terminated - */ - public function getStopSignal() - { - $this->requireProcessIsTerminated(__FUNCTION__); - - $this->updateStatus(false); - - return $this->processInformation['stopsig']; - } - - /** - * Checks if the process is currently running. - * - * @return bool true if the process is currently running, false otherwise - */ - public function isRunning() - { - if (self::STATUS_STARTED !== $this->status) { - return false; - } - - $this->updateStatus(false); - - return $this->processInformation['running']; - } - - /** - * Checks if the process has been started with no regard to the current state. - * - * @return bool true if status is ready, false otherwise - */ - public function isStarted() - { - return $this->status != self::STATUS_READY; - } - - /** - * Checks if the process is terminated. - * - * @return bool true if process is terminated, false otherwise - */ - public function isTerminated() - { - $this->updateStatus(false); - - return $this->status == self::STATUS_TERMINATED; - } - - /** - * Gets the process status. - * - * The status is one of: ready, started, terminated. - * - * @return string The current process status - */ - public function getStatus() - { - $this->updateStatus(false); - - return $this->status; - } - - /** - * Stops the process. - * - * @param int|float $timeout The timeout in seconds - * @param int $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9) - * - * @return int The exit-code of the process - */ - public function stop($timeout = 10, $signal = null) - { - $timeoutMicro = microtime(true) + $timeout; - if ($this->isRunning()) { - // given `SIGTERM` may not be defined and that `proc_terminate` uses the constant value and not the constant itself, we use the same here - $this->doSignal(15, false); - do { - usleep(1000); - } while ($this->isRunning() && microtime(true) < $timeoutMicro); - - if ($this->isRunning() && !$this->isSigchildEnabled()) { - // Avoid exception here: process is supposed to be running, but it might have stopped just - // after this line. In any case, let's silently discard the error, we cannot do anything. - $this->doSignal($signal ?: 9, false); - } - } - - $this->updateStatus(false); - if ($this->processInformation['running']) { - $this->close(); - } - - return $this->exitcode; - } - - /** - * Adds a line to the STDOUT stream. - * - * @param string $line The line to append - */ - public function addOutput($line) - { - $this->lastOutputTime = microtime(true); - $this->stdout .= $line; - } - - /** - * Adds a line to the STDERR stream. - * - * @param string $line The line to append - */ - public function addErrorOutput($line) - { - $this->lastOutputTime = microtime(true); - $this->stderr .= $line; - } - - /** - * Gets the command line to be executed. - * - * @return string The command to execute - */ - public function getCommandLine() - { - return $this->commandline; - } - - /** - * Sets the command line to be executed. - * - * @param string $commandline The command to execute - * - * @return self The current Process instance - */ - public function setCommandLine($commandline) - { - $this->commandline = $commandline; - - return $this; - } - - /** - * Gets the process timeout (max. runtime). - * - * @return float|null The timeout in seconds or null if it's disabled - */ - public function getTimeout() - { - return $this->timeout; - } - - /** - * Gets the process idle timeout (max. time since last output). - * - * @return float|null The timeout in seconds or null if it's disabled - */ - public function getIdleTimeout() - { - return $this->idleTimeout; - } - - /** - * Sets the process timeout (max. runtime). - * - * To disable the timeout, set this value to null. - * - * @param int|float|null $timeout The timeout in seconds - * - * @return self The current Process instance - * - * @throws InvalidArgumentException if the timeout is negative - */ - public function setTimeout($timeout) - { - $this->timeout = $this->validateTimeout($timeout); - - return $this; - } - - /** - * Sets the process idle timeout (max. time since last output). - * - * To disable the timeout, set this value to null. - * - * @param int|float|null $timeout The timeout in seconds - * - * @return self The current Process instance. - * - * @throws LogicException if the output is disabled - * @throws InvalidArgumentException if the timeout is negative - */ - public function setIdleTimeout($timeout) - { - if (null !== $timeout && $this->outputDisabled) { - throw new LogicException('Idle timeout can not be set while the output is disabled.'); - } - - $this->idleTimeout = $this->validateTimeout($timeout); - - return $this; - } - - /** - * Enables or disables the TTY mode. - * - * @param bool $tty True to enabled and false to disable - * - * @return self The current Process instance - * - * @throws RuntimeException In case the TTY mode is not supported - */ - public function setTty($tty) - { - if ('\\' === DIRECTORY_SEPARATOR && $tty) { - throw new RuntimeException('TTY mode is not supported on Windows platform.'); - } - if ($tty && (!file_exists('/dev/tty') || !is_readable('/dev/tty'))) { - throw new RuntimeException('TTY mode requires /dev/tty to be readable.'); - } - - $this->tty = (bool) $tty; - - return $this; - } - - /** - * Checks if the TTY mode is enabled. - * - * @return bool true if the TTY mode is enabled, false otherwise - */ - public function isTty() - { - return $this->tty; - } - - /** - * Sets PTY mode. - * - * @param bool $bool - * - * @return self - */ - public function setPty($bool) - { - $this->pty = (bool) $bool; - - return $this; - } - - /** - * Returns PTY state. - * - * @return bool - */ - public function isPty() - { - return $this->pty; - } - - /** - * Gets the working directory. - * - * @return string|null The current working directory or null on failure - */ - public function getWorkingDirectory() - { - if (null === $this->cwd) { - // getcwd() will return false if any one of the parent directories does not have - // the readable or search mode set, even if the current directory does - return getcwd() ?: null; - } - - return $this->cwd; - } - - /** - * Sets the current working directory. - * - * @param string $cwd The new working directory - * - * @return self The current Process instance - */ - public function setWorkingDirectory($cwd) - { - $this->cwd = $cwd; - - return $this; - } - - /** - * Gets the environment variables. - * - * @return array The current environment variables - */ - public function getEnv() - { - return $this->env; - } - - /** - * Sets the environment variables. - * - * An environment variable value should be a string. - * If it is an array, the variable is ignored. - * - * That happens in PHP when 'argv' is registered into - * the $_ENV array for instance. - * - * @param array $env The new environment variables - * - * @return self The current Process instance - */ - public function setEnv(array $env) - { - // Process can not handle env values that are arrays - $env = array_filter($env, function ($value) { - return !is_array($value); - }); - - $this->env = array(); - foreach ($env as $key => $value) { - $this->env[$key] = (string) $value; - } - - return $this; - } - - /** - * Gets the contents of STDIN. - * - * @return string|null The current contents - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use setInput() instead. - * This method is deprecated in favor of getInput. - */ - public function getStdin() - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the getInput() method instead.', E_USER_DEPRECATED); - - return $this->getInput(); - } - - /** - * Gets the Process input. - * - * @return null|string The Process input - */ - public function getInput() - { - return $this->input; - } - - /** - * Sets the contents of STDIN. - * - * @param string|null $stdin The new contents - * - * @return self The current Process instance - * - * @deprecated since version 2.5, to be removed in 3.0. - * Use setInput() instead. - * - * @throws LogicException In case the process is running - * @throws InvalidArgumentException In case the argument is invalid - */ - public function setStdin($stdin) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 2.5 and will be removed in 3.0. Use the setInput() method instead.', E_USER_DEPRECATED); - - return $this->setInput($stdin); - } - - /** - * Sets the input. - * - * This content will be passed to the underlying process standard input. - * - * @param mixed $input The content - * - * @return self The current Process instance - * - * @throws LogicException In case the process is running - * - * Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0. - */ - public function setInput($input) - { - if ($this->isRunning()) { - throw new LogicException('Input can not be set while the process is running.'); - } - - $this->input = ProcessUtils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input); - - return $this; - } - - /** - * Gets the options for proc_open. - * - * @return array The current options - */ - public function getOptions() - { - return $this->options; - } - - /** - * Sets the options for proc_open. - * - * @param array $options The new options - * - * @return self The current Process instance - */ - public function setOptions(array $options) - { - $this->options = $options; - - return $this; - } - - /** - * Gets whether or not Windows compatibility is enabled. - * - * This is true by default. - * - * @return bool - */ - public function getEnhanceWindowsCompatibility() - { - return $this->enhanceWindowsCompatibility; - } - - /** - * Sets whether or not Windows compatibility is enabled. - * - * @param bool $enhance - * - * @return self The current Process instance - */ - public function setEnhanceWindowsCompatibility($enhance) - { - $this->enhanceWindowsCompatibility = (bool) $enhance; - - return $this; - } - - /** - * Returns whether sigchild compatibility mode is activated or not. - * - * @return bool - */ - public function getEnhanceSigchildCompatibility() - { - return $this->enhanceSigchildCompatibility; - } - - /** - * Activates sigchild compatibility mode. - * - * Sigchild compatibility mode is required to get the exit code and - * determine the success of a process when PHP has been compiled with - * the --enable-sigchild option - * - * @param bool $enhance - * - * @return self The current Process instance - */ - public function setEnhanceSigchildCompatibility($enhance) - { - $this->enhanceSigchildCompatibility = (bool) $enhance; - - return $this; - } - - /** - * Performs a check between the timeout definition and the time the process started. - * - * In case you run a background process (with the start method), you should - * trigger this method regularly to ensure the process timeout - * - * @throws ProcessTimedOutException In case the timeout was reached - */ - public function checkTimeout() - { - if ($this->status !== self::STATUS_STARTED) { - return; - } - - if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) { - $this->stop(0); - - throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL); - } - - if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) { - $this->stop(0); - - throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE); - } - } - - /** - * Returns whether PTY is supported on the current operating system. - * - * @return bool - */ - public static function isPtySupported() - { - static $result; - - if (null !== $result) { - return $result; - } - - if ('\\' === DIRECTORY_SEPARATOR) { - return $result = false; - } - - $proc = @proc_open('echo 1', array(array('pty'), array('pty'), array('pty')), $pipes); - if (is_resource($proc)) { - proc_close($proc); - - return $result = true; - } - - return $result = false; - } - - /** - * Creates the descriptors needed by the proc_open. - * - * @return array - */ - private function getDescriptors() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->processPipes = WindowsPipes::create($this, $this->input); - } else { - $this->processPipes = UnixPipes::create($this, $this->input); - } - $descriptors = $this->processPipes->getDescriptors($this->outputDisabled); - - if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { - // last exit code is output on the fourth pipe and caught to work around --enable-sigchild - $descriptors = array_merge($descriptors, array(array('pipe', 'w'))); - - $this->commandline = '('.$this->commandline.') 3>/dev/null; code=$?; echo $code >&3; exit $code'; - } - - return $descriptors; - } - - /** - * Builds up the callback used by wait(). - * - * The callbacks adds all occurred output to the specific buffer and calls - * the user callback (if present) with the received output. - * - * @param callable|null $callback The user defined PHP callback - * - * @return \Closure A PHP closure - */ - protected function buildCallback($callback) - { - $that = $this; - $out = self::OUT; - $callback = function ($type, $data) use ($that, $callback, $out) { - if ($out == $type) { - $that->addOutput($data); - } else { - $that->addErrorOutput($data); - } - - if (null !== $callback) { - call_user_func($callback, $type, $data); - } - }; - - return $callback; - } - - /** - * Updates the status of the process, reads pipes. - * - * @param bool $blocking Whether to use a blocking read call. - */ - protected function updateStatus($blocking) - { - if (self::STATUS_STARTED !== $this->status) { - return; - } - - $this->processInformation = proc_get_status($this->process); - $this->captureExitCode(); - - $this->readPipes($blocking, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true); - - if (!$this->processInformation['running']) { - $this->close(); - } - } - - /** - * Returns whether PHP has been compiled with the '--enable-sigchild' option or not. - * - * @return bool - */ - protected function isSigchildEnabled() - { - if (null !== self::$sigchild) { - return self::$sigchild; - } - - if (!function_exists('phpinfo')) { - return self::$sigchild = false; - } - - ob_start(); - phpinfo(INFO_GENERAL); - - return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild'); - } - - /** - * Validates and returns the filtered timeout. - * - * @param int|float|null $timeout - * - * @return float|null - * - * @throws InvalidArgumentException if the given timeout is a negative number - */ - private function validateTimeout($timeout) - { - $timeout = (float) $timeout; - - if (0.0 === $timeout) { - $timeout = null; - } elseif ($timeout < 0) { - throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); - } - - return $timeout; - } - - /** - * Reads pipes, executes callback. - * - * @param bool $blocking Whether to use blocking calls or not. - * @param bool $close Whether to close file handles or not. - */ - private function readPipes($blocking, $close) - { - $result = $this->processPipes->readAndWrite($blocking, $close); - - $callback = $this->callback; - foreach ($result as $type => $data) { - if (3 == $type) { - $this->fallbackExitcode = (int) $data; - } else { - $callback($type === self::STDOUT ? self::OUT : self::ERR, $data); - } - } - } - - /** - * Captures the exitcode if mentioned in the process information. - */ - private function captureExitCode() - { - if (isset($this->processInformation['exitcode']) && -1 != $this->processInformation['exitcode']) { - $this->exitcode = $this->processInformation['exitcode']; - } - } - - /** - * Closes process resource, closes file handles, sets the exitcode. - * - * @return int The exitcode - */ - private function close() - { - $this->processPipes->close(); - if (is_resource($this->process)) { - $exitcode = proc_close($this->process); - } else { - $exitcode = -1; - } - - $this->exitcode = -1 !== $exitcode ? $exitcode : (null !== $this->exitcode ? $this->exitcode : -1); - $this->status = self::STATUS_TERMINATED; - - if (-1 === $this->exitcode && null !== $this->fallbackExitcode) { - $this->exitcode = $this->fallbackExitcode; - } elseif (-1 === $this->exitcode && $this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) { - // if process has been signaled, no exitcode but a valid termsig, apply Unix convention - $this->exitcode = 128 + $this->processInformation['termsig']; - } - - return $this->exitcode; - } - - /** - * Resets data related to the latest run of the process. - */ - private function resetProcessData() - { - $this->starttime = null; - $this->callback = null; - $this->exitcode = null; - $this->fallbackExitcode = null; - $this->processInformation = null; - $this->stdout = null; - $this->stderr = null; - $this->process = null; - $this->latestSignal = null; - $this->status = self::STATUS_READY; - $this->incrementalOutputOffset = 0; - $this->incrementalErrorOutputOffset = 0; - } - - /** - * Sends a POSIX signal to the process. - * - * @param int $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php) - * @param bool $throwException Whether to throw exception in case signal failed - * - * @return bool True if the signal was sent successfully, false otherwise - * - * @throws LogicException In case the process is not running - * @throws RuntimeException In case --enable-sigchild is activated - * @throws RuntimeException In case of failure - */ - private function doSignal($signal, $throwException) - { - if (!$this->isRunning()) { - if ($throwException) { - throw new LogicException('Can not send signal on a non running process.'); - } - - return false; - } - - if ($this->isSigchildEnabled()) { - if ($throwException) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - } - - return false; - } - - if ('\\' === DIRECTORY_SEPARATOR) { - exec(sprintf('taskkill /F /T /PID %d 2>&1', $this->getPid()), $output, $exitCode); - if ($exitCode) { - if ($throwException) { - throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output))); - } - - return false; - } - } - - if (true !== @proc_terminate($this->process, $signal) && '\\' !== DIRECTORY_SEPARATOR) { - if ($throwException) { - throw new RuntimeException(sprintf('Error while sending signal `%s`.', $signal)); - } - - return false; - } - - $this->latestSignal = $signal; - - return true; - } - - /** - * Ensures the process is running or terminated, throws a LogicException if the process has a not started. - * - * @param string $functionName The function name that was called. - * - * @throws LogicException If the process has not run. - */ - private function requireProcessIsStarted($functionName) - { - if (!$this->isStarted()) { - throw new LogicException(sprintf('Process must be started before calling %s.', $functionName)); - } - } - - /** - * Ensures the process is terminated, throws a LogicException if the process has a status different than `terminated`. - * - * @param string $functionName The function name that was called. - * - * @throws LogicException If the process is not yet terminated. - */ - private function requireProcessIsTerminated($functionName) - { - if (!$this->isTerminated()) { - throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName)); - } - } -} diff --git a/library/symfony/process/ProcessBuilder.php b/library/symfony/process/ProcessBuilder.php deleted file mode 100644 index a782fd69e..000000000 --- a/library/symfony/process/ProcessBuilder.php +++ /dev/null @@ -1,287 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -use Symfony\Component\Process\Exception\InvalidArgumentException; -use Symfony\Component\Process\Exception\LogicException; - -/** - * Process builder. - * - * @author Kris Wallsmith <kris@symfony.com> - */ -class ProcessBuilder -{ - private $arguments; - private $cwd; - private $env = array(); - private $input; - private $timeout = 60; - private $options = array(); - private $inheritEnv = true; - private $prefix = array(); - private $outputDisabled = false; - - /** - * Constructor. - * - * @param string[] $arguments An array of arguments - */ - public function __construct(array $arguments = array()) - { - $this->arguments = $arguments; - } - - /** - * Creates a process builder instance. - * - * @param string[] $arguments An array of arguments - * - * @return ProcessBuilder - */ - public static function create(array $arguments = array()) - { - return new static($arguments); - } - - /** - * Adds an unescaped argument to the command string. - * - * @param string $argument A command argument - * - * @return ProcessBuilder - */ - public function add($argument) - { - $this->arguments[] = $argument; - - return $this; - } - - /** - * Adds a prefix to the command string. - * - * The prefix is preserved when resetting arguments. - * - * @param string|array $prefix A command prefix or an array of command prefixes - * - * @return ProcessBuilder - */ - public function setPrefix($prefix) - { - $this->prefix = is_array($prefix) ? $prefix : array($prefix); - - return $this; - } - - /** - * Sets the arguments of the process. - * - * Arguments must not be escaped. - * Previous arguments are removed. - * - * @param string[] $arguments - * - * @return ProcessBuilder - */ - public function setArguments(array $arguments) - { - $this->arguments = $arguments; - - return $this; - } - - /** - * Sets the working directory. - * - * @param null|string $cwd The working directory - * - * @return ProcessBuilder - */ - public function setWorkingDirectory($cwd) - { - $this->cwd = $cwd; - - return $this; - } - - /** - * Sets whether environment variables will be inherited or not. - * - * @param bool $inheritEnv - * - * @return ProcessBuilder - */ - public function inheritEnvironmentVariables($inheritEnv = true) - { - $this->inheritEnv = $inheritEnv; - - return $this; - } - - /** - * Sets an environment variable. - * - * Setting a variable overrides its previous value. Use `null` to unset a - * defined environment variable. - * - * @param string $name The variable name - * @param null|string $value The variable value - * - * @return ProcessBuilder - */ - public function setEnv($name, $value) - { - $this->env[$name] = $value; - - return $this; - } - - /** - * Adds a set of environment variables. - * - * Already existing environment variables with the same name will be - * overridden by the new values passed to this method. Pass `null` to unset - * a variable. - * - * @param array $variables The variables - * - * @return ProcessBuilder - */ - public function addEnvironmentVariables(array $variables) - { - $this->env = array_replace($this->env, $variables); - - return $this; - } - - /** - * Sets the input of the process. - * - * @param mixed $input The input as a string - * - * @return ProcessBuilder - * - * @throws InvalidArgumentException In case the argument is invalid - * - * Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0. - */ - public function setInput($input) - { - $this->input = ProcessUtils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input); - - return $this; - } - - /** - * Sets the process timeout. - * - * To disable the timeout, set this value to null. - * - * @param float|null $timeout - * - * @return ProcessBuilder - * - * @throws InvalidArgumentException - */ - public function setTimeout($timeout) - { - if (null === $timeout) { - $this->timeout = null; - - return $this; - } - - $timeout = (float) $timeout; - - if ($timeout < 0) { - throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); - } - - $this->timeout = $timeout; - - return $this; - } - - /** - * Adds a proc_open option. - * - * @param string $name The option name - * @param string $value The option value - * - * @return ProcessBuilder - */ - public function setOption($name, $value) - { - $this->options[$name] = $value; - - return $this; - } - - /** - * Disables fetching output and error output from the underlying process. - * - * @return ProcessBuilder - */ - public function disableOutput() - { - $this->outputDisabled = true; - - return $this; - } - - /** - * Enables fetching output and error output from the underlying process. - * - * @return ProcessBuilder - */ - public function enableOutput() - { - $this->outputDisabled = false; - - return $this; - } - - /** - * Creates a Process instance and returns it. - * - * @return Process - * - * @throws LogicException In case no arguments have been provided - */ - public function getProcess() - { - if (0 === count($this->prefix) && 0 === count($this->arguments)) { - throw new LogicException('You must add() command arguments before calling getProcess().'); - } - - $options = $this->options; - - $arguments = array_merge($this->prefix, $this->arguments); - $script = implode(' ', array_map(array(__NAMESPACE__.'\\ProcessUtils', 'escapeArgument'), $arguments)); - - if ($this->inheritEnv) { - // include $_ENV for BC purposes - $env = array_replace($_ENV, $_SERVER, $this->env); - } else { - $env = $this->env; - } - - $process = new Process($script, $this->cwd, $env, $this->input, $this->timeout, $options); - - if ($this->outputDisabled) { - $process->disableOutput(); - } - - return $process; - } -} diff --git a/library/symfony/process/ProcessUtils.php b/library/symfony/process/ProcessUtils.php deleted file mode 100644 index 4f30b630d..000000000 --- a/library/symfony/process/ProcessUtils.php +++ /dev/null @@ -1,115 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process; - -use Symfony\Component\Process\Exception\InvalidArgumentException; - -/** - * ProcessUtils is a bunch of utility methods. - * - * This class contains static methods only and is not meant to be instantiated. - * - * @author Martin Hasoň <martin.hason@gmail.com> - */ -class ProcessUtils -{ - /** - * This class should not be instantiated. - */ - private function __construct() - { - } - - /** - * Escapes a string to be used as a shell argument. - * - * @param string $argument The argument that will be escaped - * - * @return string The escaped argument - */ - public static function escapeArgument($argument) - { - //Fix for PHP bug #43784 escapeshellarg removes % from given string - //Fix for PHP bug #49446 escapeshellarg doesn't work on Windows - //@see https://bugs.php.net/bug.php?id=43784 - //@see https://bugs.php.net/bug.php?id=49446 - if ('\\' === DIRECTORY_SEPARATOR) { - if ('' === $argument) { - return escapeshellarg($argument); - } - - $escapedArgument = ''; - $quote = false; - foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) { - if ('"' === $part) { - $escapedArgument .= '\\"'; - } elseif (self::isSurroundedBy($part, '%')) { - // Avoid environment variable expansion - $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%'; - } else { - // escape trailing backslash - if ('\\' === substr($part, -1)) { - $part .= '\\'; - } - $quote = true; - $escapedArgument .= $part; - } - } - if ($quote) { - $escapedArgument = '"'.$escapedArgument.'"'; - } - - return $escapedArgument; - } - - return escapeshellarg($argument); - } - - /** - * Validates and normalizes a Process input. - * - * @param string $caller The name of method call that validates the input - * @param mixed $input The input to validate - * - * @return string The validated input - * - * @throws InvalidArgumentException In case the input is not valid - * - * Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0. - */ - public static function validateInput($caller, $input) - { - if (null !== $input) { - if (is_resource($input)) { - return $input; - } - if (is_scalar($input)) { - return (string) $input; - } - // deprecated as of Symfony 2.5, to be removed in 3.0 - if (is_object($input) && method_exists($input, '__toString')) { - @trigger_error('Passing an object as an input is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED); - - return (string) $input; - } - - throw new InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller)); - } - - return $input; - } - - private static function isSurroundedBy($arg, $char) - { - return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1]; - } -} diff --git a/library/symfony/process/README.md b/library/symfony/process/README.md deleted file mode 100644 index 7222fe895..000000000 --- a/library/symfony/process/README.md +++ /dev/null @@ -1,65 +0,0 @@ -Process Component -================= - -Process executes commands in sub-processes. - -In this example, we run a simple directory listing and get the result back: - -```php -use Symfony\Component\Process\Process; -use Symfony\Component\Process\Exception\ProcessFailedException; - -$process = new Process('ls -lsa'); -$process->setTimeout(3600); -$process->run(); -if (!$process->isSuccessful()) { - throw new ProcessFailedException($process); -} - -print $process->getOutput(); -``` - -You can think that this is easy to achieve with plain PHP but it's not especially -if you want to take care of the subtle differences between the different platforms. - -You can simplify the code by using `mustRun()` instead of `run()`, which will -throw a `ProcessFailedException` automatically in case of a problem: - -```php -use Symfony\Component\Process\Process; - -$process = new Process('ls -lsa'); -$process->setTimeout(3600); -$process->mustRun(); - -print $process->getOutput(); -``` - -And if you want to be able to get some feedback in real-time, just pass an -anonymous function to the ``run()`` method and you will get the output buffer -as it becomes available: - -```php -use Symfony\Component\Process\Process; - -$process = new Process('ls -lsa'); -$process->run(function ($type, $buffer) { - if (Process::ERR === $type) { - echo 'ERR > '.$buffer; - } else { - echo 'OUT > '.$buffer; - } -}); -``` - -That's great if you want to execute a long running command (like rsync-ing files to a -remote server) and give feedback to the user in real-time. - -Resources ---------- - -You can run the unit tests with the following command: - - $ cd path/to/Symfony/Component/Process/ - $ composer install - $ phpunit diff --git a/library/symfony/process/Tests/AbstractProcessTest.php b/library/symfony/process/Tests/AbstractProcessTest.php deleted file mode 100644 index fca3729be..000000000 --- a/library/symfony/process/Tests/AbstractProcessTest.php +++ /dev/null @@ -1,1196 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\Exception\LogicException; -use Symfony\Component\Process\Exception\ProcessTimedOutException; -use Symfony\Component\Process\Exception\RuntimeException; -use Symfony\Component\Process\PhpExecutableFinder; -use Symfony\Component\Process\Pipes\PipesInterface; -use Symfony\Component\Process\Process; - -/** - * @author Robert Schönthal <seroscho@googlemail.com> - */ -abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase -{ - protected static $phpBin; - - public static function setUpBeforeClass() - { - $phpBin = new PhpExecutableFinder(); - self::$phpBin = 'phpdbg' === PHP_SAPI ? 'php' : $phpBin->find(); - } - - public function testThatProcessDoesNotThrowWarningDuringRun() - { - @trigger_error('Test Error', E_USER_NOTICE); - $process = $this->getProcess(self::$phpBin." -r 'sleep(3)'"); - $process->run(); - $actualError = error_get_last(); - $this->assertEquals('Test Error', $actualError['message']); - $this->assertEquals(E_USER_NOTICE, $actualError['type']); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException - */ - public function testNegativeTimeoutFromConstructor() - { - $this->getProcess('', null, null, null, -1); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException - */ - public function testNegativeTimeoutFromSetter() - { - $p = $this->getProcess(''); - $p->setTimeout(-1); - } - - public function testFloatAndNullTimeout() - { - $p = $this->getProcess(''); - - $p->setTimeout(10); - $this->assertSame(10.0, $p->getTimeout()); - - $p->setTimeout(null); - $this->assertNull($p->getTimeout()); - - $p->setTimeout(0.0); - $this->assertNull($p->getTimeout()); - } - - public function testStopWithTimeoutIsActuallyWorking() - { - if (!extension_loaded('pcntl')) { - $this->markTestSkipped('Extension pcntl is required.'); - } - - // exec is mandatory here since we send a signal to the process - // see https://github.com/symfony/symfony/issues/5030 about prepending - // command with exec - $p = $this->getProcess('exec '.self::$phpBin.' '.__DIR__.'/NonStopableProcess.php 3'); - $p->start(); - usleep(100000); - $start = microtime(true); - $p->stop(1.1, SIGKILL); - while ($p->isRunning()) { - usleep(1000); - } - $duration = microtime(true) - $start; - - $this->assertLessThan(4, $duration); - } - - public function testAllOutputIsActuallyReadOnTermination() - { - // this code will result in a maximum of 2 reads of 8192 bytes by calling - // start() and isRunning(). by the time getOutput() is called the process - // has terminated so the internal pipes array is already empty. normally - // the call to start() will not read any data as the process will not have - // generated output, but this is non-deterministic so we must count it as - // a possibility. therefore we need 2 * PipesInterface::CHUNK_SIZE plus - // another byte which will never be read. - $expectedOutputSize = PipesInterface::CHUNK_SIZE * 2 + 2; - - $code = sprintf('echo str_repeat(\'*\', %d);', $expectedOutputSize); - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code))); - - $p->start(); - // Let's wait enough time for process to finish... - // Here we don't call Process::run or Process::wait to avoid any read of pipes - usleep(500000); - - if ($p->isRunning()) { - $this->markTestSkipped('Process execution did not complete in the required time frame'); - } - - $o = $p->getOutput(); - - $this->assertEquals($expectedOutputSize, strlen($o)); - } - - public function testCallbacksAreExecutedWithStart() - { - $data = ''; - - $process = $this->getProcess('echo foo && php -r "sleep(1);" && echo foo'); - $process->start(function ($type, $buffer) use (&$data) { - $data .= $buffer; - }); - - while ($process->isRunning()) { - usleep(10000); - } - - $this->assertEquals(2, preg_match_all('/foo/', $data, $matches)); - } - - /** - * tests results from sub processes. - * - * @dataProvider responsesCodeProvider - */ - public function testProcessResponses($expected, $getter, $code) - { - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code))); - $p->run(); - - $this->assertSame($expected, $p->$getter()); - } - - /** - * tests results from sub processes. - * - * @dataProvider pipesCodeProvider - */ - public function testProcessPipes($code, $size) - { - $expected = str_repeat(str_repeat('*', 1024), $size).'!'; - $expectedLength = (1024 * $size) + 1; - - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code))); - $p->setInput($expected); - $p->run(); - - $this->assertEquals($expectedLength, strlen($p->getOutput())); - $this->assertEquals($expectedLength, strlen($p->getErrorOutput())); - } - - /** - * @dataProvider pipesCodeProvider - */ - public function testSetStreamAsInput($code, $size) - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestIncomplete('This test fails with a timeout on Windows, can someone investigate please?'); - } - $expected = str_repeat(str_repeat('*', 1024), $size).'!'; - $expectedLength = (1024 * $size) + 1; - - $stream = fopen('php://temporary', 'w+'); - fwrite($stream, $expected); - rewind($stream); - - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg($code)), null, null, null, 5); - $p->setInput($stream); - $p->run(); - - fclose($stream); - - $this->assertEquals($expectedLength, strlen($p->getOutput())); - $this->assertEquals($expectedLength, strlen($p->getErrorOutput())); - } - - public function testSetInputWhileRunningThrowsAnException() - { - $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $process->start(); - try { - $process->setInput('foobar'); - $process->stop(); - $this->fail('A LogicException should have been raised.'); - } catch (LogicException $e) { - $this->assertEquals('Input can not be set while the process is running.', $e->getMessage()); - } - $process->stop(); - } - - /** - * @dataProvider provideInvalidInputValues - * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException - * @expectedExceptionMessage Symfony\Component\Process\Process::setInput only accepts strings or stream resources. - */ - public function testInvalidInput($value) - { - $process = $this->getProcess(self::$phpBin.' -v'); - $process->setInput($value); - } - - public function provideInvalidInputValues() - { - return array( - array(array()), - array(new NonStringifiable()), - ); - } - - /** - * @dataProvider provideInputValues - */ - public function testValidInput($expected, $value) - { - $process = $this->getProcess(self::$phpBin.' -v'); - $process->setInput($value); - $this->assertSame($expected, $process->getInput()); - } - - public function provideInputValues() - { - return array( - array(null, null), - array('24.5', 24.5), - array('input data', 'input data'), - ); - } - - /** - * @dataProvider provideLegacyInputValues - * @group legacy - */ - public function testLegacyValidInput($expected, $value) - { - $process = $this->getProcess(self::$phpBin.' -v'); - $process->setInput($value); - $this->assertSame($expected, $process->getInput()); - } - - public function provideLegacyInputValues() - { - return array( - array('stringifiable', new Stringifiable()), - ); - } - - public function chainedCommandsOutputProvider() - { - if ('\\' === DIRECTORY_SEPARATOR) { - return array( - array("2 \r\n2\r\n", '&&', '2'), - ); - } - - return array( - array("1\n1\n", ';', '1'), - array("2\n2\n", '&&', '2'), - ); - } - - /** - * @dataProvider chainedCommandsOutputProvider - */ - public function testChainedCommandsOutput($expected, $operator, $input) - { - $process = $this->getProcess(sprintf('echo %s %s echo %s', $input, $operator, $input)); - $process->run(); - $this->assertEquals($expected, $process->getOutput()); - } - - public function testCallbackIsExecutedForOutput() - { - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('echo \'foo\';'))); - - $called = false; - $p->run(function ($type, $buffer) use (&$called) { - $called = $buffer === 'foo'; - }); - - $this->assertTrue($called, 'The callback should be executed with the output'); - } - - public function testGetErrorOutput() - { - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }'))); - - $p->run(); - $this->assertEquals(3, preg_match_all('/ERROR/', $p->getErrorOutput(), $matches)); - } - - public function testGetIncrementalErrorOutput() - { - // use a lock file to toggle between writing ("W") and reading ("R") the - // error stream - $lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock'); - file_put_contents($lock, 'W'); - - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }'))); - - $p->start(); - while ($p->isRunning()) { - if ('R' === file_get_contents($lock)) { - $this->assertLessThanOrEqual(1, preg_match_all('/ERROR/', $p->getIncrementalErrorOutput(), $matches)); - file_put_contents($lock, 'W'); - } - usleep(100); - } - - unlink($lock); - } - - public function testFlushErrorOutput() - { - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }'))); - - $p->run(); - $p->clearErrorOutput(); - $this->assertEmpty($p->getErrorOutput()); - } - - public function testGetEmptyIncrementalErrorOutput() - { - // use a lock file to toggle between writing ("W") and reading ("R") the - // output stream - $lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock'); - file_put_contents($lock, 'W'); - - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }'))); - - $p->start(); - - $shouldWrite = false; - - while ($p->isRunning()) { - if ('R' === file_get_contents($lock)) { - if (!$shouldWrite) { - $this->assertLessThanOrEqual(1, preg_match_all('/ERROR/', $p->getIncrementalOutput(), $matches)); - $shouldWrite = true; - } else { - $this->assertSame('', $p->getIncrementalOutput()); - - file_put_contents($lock, 'W'); - $shouldWrite = false; - } - } - usleep(100); - } - - unlink($lock); - } - - public function testGetOutput() - { - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { echo \' foo \'; $n++; }'))); - - $p->run(); - $this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches)); - } - - public function testGetIncrementalOutput() - { - // use a lock file to toggle between writing ("W") and reading ("R") the - // output stream - $lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock'); - file_put_contents($lock, 'W'); - - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { echo \' foo \'; $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }'))); - - $p->start(); - while ($p->isRunning()) { - if ('R' === file_get_contents($lock)) { - $this->assertLessThanOrEqual(1, preg_match_all('/foo/', $p->getIncrementalOutput(), $matches)); - file_put_contents($lock, 'W'); - } - usleep(100); - } - - unlink($lock); - } - - public function testFlushOutput() - { - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n=0;while ($n<3) {echo \' foo \';$n++;}'))); - - $p->run(); - $p->clearOutput(); - $this->assertEmpty($p->getOutput()); - } - - public function testGetEmptyIncrementalOutput() - { - // use a lock file to toggle between writing ("W") and reading ("R") the - // output stream - $lock = tempnam(sys_get_temp_dir(), get_class($this).'Lock'); - file_put_contents($lock, 'W'); - - $p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 0; while ($n < 3) { if (\'W\' === file_get_contents('.var_export($lock, true).')) { echo \' foo \'; $n++; file_put_contents('.var_export($lock, true).', \'R\'); } usleep(100); }'))); - - $p->start(); - - $shouldWrite = false; - - while ($p->isRunning()) { - if ('R' === file_get_contents($lock)) { - if (!$shouldWrite) { - $this->assertLessThanOrEqual(1, preg_match_all('/foo/', $p->getIncrementalOutput(), $matches)); - $shouldWrite = true; - } else { - $this->assertSame('', $p->getIncrementalOutput()); - - file_put_contents($lock, 'W'); - $shouldWrite = false; - } - } - usleep(100); - } - - unlink($lock); - } - - public function testZeroAsOutput() - { - if ('\\' === DIRECTORY_SEPARATOR) { - // see http://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line - $p = $this->getProcess('echo | set /p dummyName=0'); - } else { - $p = $this->getProcess('printf 0'); - } - - $p->run(); - $this->assertSame('0', $p->getOutput()); - } - - public function testExitCodeCommandFailed() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Windows does not support POSIX exit code'); - } - - // such command run in bash return an exitcode 127 - $process = $this->getProcess('nonexistingcommandIhopeneversomeonewouldnameacommandlikethis'); - $process->run(); - - $this->assertGreaterThan(0, $process->getExitCode()); - } - - public function testTTYCommand() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Windows does have /dev/tty support'); - } - - $process = $this->getProcess('echo "foo" >> /dev/null && '.self::$phpBin.' -r "usleep(100000);"'); - $process->setTty(true); - $process->start(); - $this->assertTrue($process->isRunning()); - $process->wait(); - - $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus()); - } - - public function testTTYCommandExitCode() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Windows does have /dev/tty support'); - } - - $process = $this->getProcess('echo "foo" >> /dev/null'); - $process->setTty(true); - $process->run(); - - $this->assertTrue($process->isSuccessful()); - } - - public function testTTYInWindowsEnvironment() - { - if ('\\' !== DIRECTORY_SEPARATOR) { - $this->markTestSkipped('This test is for Windows platform only'); - } - - $process = $this->getProcess('echo "foo" >> /dev/null'); - $process->setTty(false); - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'TTY mode is not supported on Windows platform.'); - $process->setTty(true); - } - - public function testExitCodeTextIsNullWhenExitCodeIsNull() - { - $process = $this->getProcess(''); - $this->assertNull($process->getExitCodeText()); - } - - public function testPTYCommand() - { - if (!Process::isPtySupported()) { - $this->markTestSkipped('PTY is not supported on this operating system.'); - } - - $process = $this->getProcess('echo "foo"'); - $process->setPty(true); - $process->run(); - - $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus()); - $this->assertEquals("foo\r\n", $process->getOutput()); - } - - public function testMustRun() - { - $process = $this->getProcess('echo foo'); - - $this->assertSame($process, $process->mustRun()); - $this->assertEquals('foo'.PHP_EOL, $process->getOutput()); - } - - public function testSuccessfulMustRunHasCorrectExitCode() - { - $process = $this->getProcess('echo foo')->mustRun(); - $this->assertEquals(0, $process->getExitCode()); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\ProcessFailedException - */ - public function testMustRunThrowsException() - { - $process = $this->getProcess('exit 1'); - $process->mustRun(); - } - - public function testExitCodeText() - { - $process = $this->getProcess(''); - $r = new \ReflectionObject($process); - $p = $r->getProperty('exitcode'); - $p->setAccessible(true); - - $p->setValue($process, 2); - $this->assertEquals('Misuse of shell builtins', $process->getExitCodeText()); - } - - public function testStartIsNonBlocking() - { - $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $start = microtime(true); - $process->start(); - $end = microtime(true); - $this->assertLessThan(0.4, $end - $start); - $process->wait(); - } - - public function testUpdateStatus() - { - $process = $this->getProcess(self::$phpBin.' -v'); - $process->run(); - $this->assertTrue(strlen($process->getOutput()) > 0); - } - - public function testGetExitCodeIsNullOnStart() - { - $process = $this->getProcess(self::$phpBin.' -r "usleep(200000);"'); - $this->assertNull($process->getExitCode()); - $process->start(); - $this->assertNull($process->getExitCode()); - $process->wait(); - $this->assertEquals(0, $process->getExitCode()); - } - - public function testGetExitCodeIsNullOnWhenStartingAgain() - { - $process = $this->getProcess(self::$phpBin.' -r "usleep(200000);"'); - $process->run(); - $this->assertEquals(0, $process->getExitCode()); - $process->start(); - $this->assertNull($process->getExitCode()); - $process->wait(); - $this->assertEquals(0, $process->getExitCode()); - } - - public function testGetExitCode() - { - $process = $this->getProcess(self::$phpBin.' -v'); - $process->run(); - $this->assertSame(0, $process->getExitCode()); - } - - public function testStatus() - { - $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $this->assertFalse($process->isRunning()); - $this->assertFalse($process->isStarted()); - $this->assertFalse($process->isTerminated()); - $this->assertSame(Process::STATUS_READY, $process->getStatus()); - $process->start(); - $this->assertTrue($process->isRunning()); - $this->assertTrue($process->isStarted()); - $this->assertFalse($process->isTerminated()); - $this->assertSame(Process::STATUS_STARTED, $process->getStatus()); - $process->wait(); - $this->assertFalse($process->isRunning()); - $this->assertTrue($process->isStarted()); - $this->assertTrue($process->isTerminated()); - $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus()); - } - - public function testStop() - { - $process = $this->getProcess(self::$phpBin.' -r "sleep(4);"'); - $process->start(); - $this->assertTrue($process->isRunning()); - $process->stop(); - $this->assertFalse($process->isRunning()); - } - - public function testIsSuccessful() - { - $process = $this->getProcess(self::$phpBin.' -v'); - $process->run(); - $this->assertTrue($process->isSuccessful()); - } - - public function testIsSuccessfulOnlyAfterTerminated() - { - $process = $this->getProcess(self::$phpBin.' -r "sleep(1);"'); - $process->start(); - - $this->assertFalse($process->isSuccessful()); - - while ($process->isRunning()) { - usleep(300000); - } - - $this->assertTrue($process->isSuccessful()); - } - - public function testIsNotSuccessful() - { - $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);throw new \Exception(\'BOUM\');"'); - $process->start(); - $this->assertTrue($process->isRunning()); - $process->wait(); - $this->assertFalse($process->isSuccessful()); - } - - public function testProcessIsNotSignaled() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Windows does not support POSIX signals'); - } - - $process = $this->getProcess(self::$phpBin.' -v'); - $process->run(); - $this->assertFalse($process->hasBeenSignaled()); - } - - public function testProcessWithoutTermSignalIsNotSignaled() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Windows does not support POSIX signals'); - } - - $process = $this->getProcess(self::$phpBin.' -v'); - $process->run(); - $this->assertFalse($process->hasBeenSignaled()); - } - - public function testProcessWithoutTermSignal() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Windows does not support POSIX signals'); - } - - $process = $this->getProcess(self::$phpBin.' -v'); - $process->run(); - $this->assertEquals(0, $process->getTermSignal()); - } - - public function testProcessIsSignaledIfStopped() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Windows does not support POSIX signals'); - } - - $process = $this->getProcess(self::$phpBin.' -r "sleep(4);"'); - $process->start(); - $process->stop(); - $this->assertTrue($process->hasBeenSignaled()); - } - - public function testProcessWithTermSignal() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Windows does not support POSIX signals'); - } - - // SIGTERM is only defined if pcntl extension is present - $termSignal = defined('SIGTERM') ? SIGTERM : 15; - - $process = $this->getProcess(self::$phpBin.' -r "sleep(4);"'); - $process->start(); - $process->stop(); - - $this->assertEquals($termSignal, $process->getTermSignal()); - } - - public function testProcessThrowsExceptionWhenExternallySignaled() - { - if (!function_exists('posix_kill')) { - $this->markTestSkipped('Function posix_kill is required.'); - } - - $termSignal = defined('SIGKILL') ? SIGKILL : 9; - - $process = $this->getProcess('exec '.self::$phpBin.' -r "while (true) {}"'); - $process->start(); - posix_kill($process->getPid(), $termSignal); - - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'The process has been signaled with signal "9".'); - $process->wait(); - } - - public function testRestart() - { - $process1 = $this->getProcess(self::$phpBin.' -r "echo getmypid();"'); - $process1->run(); - $process2 = $process1->restart(); - - $process2->wait(); // wait for output - - // Ensure that both processed finished and the output is numeric - $this->assertFalse($process1->isRunning()); - $this->assertFalse($process2->isRunning()); - $this->assertTrue(is_numeric($process1->getOutput())); - $this->assertTrue(is_numeric($process2->getOutput())); - - // Ensure that restart returned a new process by check that the output is different - $this->assertNotEquals($process1->getOutput(), $process2->getOutput()); - } - - public function testRunProcessWithTimeout() - { - $timeout = 0.5; - $process = $this->getProcess(self::$phpBin.' -r "usleep(600000);"'); - $process->setTimeout($timeout); - $start = microtime(true); - try { - $process->run(); - $this->fail('A RuntimeException should have been raised'); - } catch (RuntimeException $e) { - } - $duration = microtime(true) - $start; - - if ('\\' === DIRECTORY_SEPARATOR) { - // Windows is a bit slower as it read file handles, then allow twice the precision - $maxDuration = $timeout + 2 * Process::TIMEOUT_PRECISION; - } else { - $maxDuration = $timeout + Process::TIMEOUT_PRECISION; - } - - $this->assertLessThan($maxDuration, $duration); - } - - public function testCheckTimeoutOnNonStartedProcess() - { - $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"'); - $process->checkTimeout(); - } - - public function testCheckTimeoutOnTerminatedProcess() - { - $process = $this->getProcess(self::$phpBin.' -v'); - $process->run(); - $process->checkTimeout(); - } - - public function testCheckTimeoutOnStartedProcess() - { - $timeout = 0.5; - $precision = 100000; - $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"'); - $process->setTimeout($timeout); - $start = microtime(true); - - $process->start(); - - try { - while ($process->isRunning()) { - $process->checkTimeout(); - usleep($precision); - } - $this->fail('A RuntimeException should have been raised'); - } catch (RuntimeException $e) { - } - $duration = microtime(true) - $start; - - $this->assertLessThan($timeout + $precision, $duration); - $this->assertFalse($process->isSuccessful()); - } - - public function testIdleTimeout() - { - $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"'); - $process->setTimeout(10); - $process->setIdleTimeout(0.5); - - try { - $process->run(); - - $this->fail('A timeout exception was expected.'); - } catch (ProcessTimedOutException $ex) { - $this->assertTrue($ex->isIdleTimeout()); - $this->assertFalse($ex->isGeneralTimeout()); - $this->assertEquals(0.5, $ex->getExceededTimeout()); - } - } - - public function testIdleTimeoutNotExceededWhenOutputIsSent() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestIncomplete('This test fails with a timeout on Windows, can someone investigate please?'); - } - $process = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 30; while ($n--) {echo "foo\n"; usleep(100000); }'))); - $process->setTimeout(2); - $process->setIdleTimeout(1); - - try { - $process->run(); - $this->fail('A timeout exception was expected.'); - } catch (ProcessTimedOutException $ex) { - $this->assertTrue($ex->isGeneralTimeout(), 'A general timeout is expected.'); - $this->assertFalse($ex->isIdleTimeout(), 'No idle timeout is expected.'); - $this->assertEquals(2, $ex->getExceededTimeout()); - } - } - - public function testStartAfterATimeout() - { - $process = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('$n = 1000; while ($n--) {echo \'\'; usleep(1000); }'))); - $process->setTimeout(0.1); - - try { - $process->run(); - $this->fail('A RuntimeException should have been raised.'); - } catch (RuntimeException $e) { - } - $process->start(); - usleep(1000); - $process->stop(); - } - - public function testGetPid() - { - $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $process->start(); - $this->assertGreaterThan(0, $process->getPid()); - $process->wait(); - } - - public function testGetPidIsNullBeforeStart() - { - $process = $this->getProcess(self::$phpBin.' -r "sleep(1);"'); - $this->assertNull($process->getPid()); - } - - public function testGetPidIsNullAfterRun() - { - $process = $this->getProcess(self::$phpBin.' -v'); - $process->run(); - $this->assertNull($process->getPid()); - } - - public function testSignal() - { - if (!extension_loaded('pcntl')) { - $this->markTestSkipped('Extension pcntl is required.'); - } - - $process = $this->getProcess('exec php -f '.__DIR__.'/SignalListener.php'); - $process->start(); - usleep(500000); - $process->signal(SIGUSR1); - - while ($process->isRunning() && false === strpos($process->getOutput(), 'Caught SIGUSR1')) { - usleep(10000); - } - - $this->assertEquals('Caught SIGUSR1', $process->getOutput()); - } - - public function testExitCodeIsAvailableAfterSignal() - { - if (!extension_loaded('pcntl')) { - $this->markTestSkipped('Extension pcntl is required.'); - } - - $process = $this->getProcess('sleep 4'); - $process->start(); - $process->signal(SIGKILL); - - while ($process->isRunning()) { - usleep(10000); - } - - $this->assertFalse($process->isRunning()); - $this->assertTrue($process->hasBeenSignaled()); - $this->assertFalse($process->isSuccessful()); - $this->assertEquals(137, $process->getExitCode()); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\LogicException - */ - public function testSignalProcessNotRunning() - { - if (!extension_loaded('pcntl')) { - $this->markTestSkipped('Extension pcntl is required.'); - } - - $process = $this->getProcess(self::$phpBin.' -v'); - $process->signal(SIGHUP); - } - - /** - * @dataProvider provideMethodsThatNeedARunningProcess - */ - public function testMethodsThatNeedARunningProcess($method) - { - $process = $this->getProcess(self::$phpBin.' -v'); - $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', sprintf('Process must be started before calling %s.', $method)); - $process->{$method}(); - } - - public function provideMethodsThatNeedARunningProcess() - { - return array( - array('getOutput'), - array('getIncrementalOutput'), - array('getErrorOutput'), - array('getIncrementalErrorOutput'), - array('wait'), - ); - } - - /** - * @dataProvider provideMethodsThatNeedATerminatedProcess - */ - public function testMethodsThatNeedATerminatedProcess($method) - { - $process = $this->getProcess(self::$phpBin.' -r "sleep(1);"'); - $process->start(); - try { - $process->{$method}(); - $process->stop(0); - $this->fail('A LogicException must have been thrown'); - } catch (\Exception $e) { - $this->assertInstanceOf('Symfony\Component\Process\Exception\LogicException', $e); - $this->assertEquals(sprintf('Process must be terminated before calling %s.', $method), $e->getMessage()); - } - $process->stop(0); - } - - public function provideMethodsThatNeedATerminatedProcess() - { - return array( - array('hasBeenSignaled'), - array('getTermSignal'), - array('hasBeenStopped'), - array('getStopSignal'), - ); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - */ - public function testSignalWithWrongIntSignal() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('POSIX signals do not work on Windows'); - } - - $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"'); - $process->start(); - $process->signal(-4); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - */ - public function testSignalWithWrongNonIntSignal() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('POSIX signals do not work on Windows'); - } - - $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"'); - $process->start(); - $process->signal('Céphalopodes'); - } - - public function testDisableOutputDisablesTheOutput() - { - $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $this->assertFalse($p->isOutputDisabled()); - $p->disableOutput(); - $this->assertTrue($p->isOutputDisabled()); - $p->enableOutput(); - $this->assertFalse($p->isOutputDisabled()); - } - - public function testDisableOutputWhileRunningThrowsException() - { - $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $p->start(); - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Disabling output while the process is running is not possible.'); - $p->disableOutput(); - } - - public function testEnableOutputWhileRunningThrowsException() - { - $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $p->disableOutput(); - $p->start(); - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Enabling output while the process is running is not possible.'); - $p->enableOutput(); - } - - public function testEnableOrDisableOutputAfterRunDoesNotThrowException() - { - $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $p->disableOutput(); - $p->start(); - $p->wait(); - $p->enableOutput(); - $p->disableOutput(); - } - - public function testDisableOutputWhileIdleTimeoutIsSet() - { - $process = $this->getProcess('sleep 3'); - $process->setIdleTimeout(1); - $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Output can not be disabled while an idle timeout is set.'); - $process->disableOutput(); - } - - public function testSetIdleTimeoutWhileOutputIsDisabled() - { - $process = $this->getProcess('sleep 3'); - $process->disableOutput(); - $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Idle timeout can not be set while the output is disabled.'); - $process->setIdleTimeout(1); - } - - public function testSetNullIdleTimeoutWhileOutputIsDisabled() - { - $process = $this->getProcess('sleep 3'); - $process->disableOutput(); - $process->setIdleTimeout(null); - } - - /** - * @dataProvider provideStartMethods - */ - public function testStartWithACallbackAndDisabledOutput($startMethod, $exception, $exceptionMessage) - { - $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $p->disableOutput(); - $this->setExpectedException($exception, $exceptionMessage); - $p->{$startMethod}(function () {}); - } - - public function provideStartMethods() - { - return array( - array('start', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'), - array('run', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'), - array('mustRun', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'), - ); - } - - /** - * @dataProvider provideOutputFetchingMethods - */ - public function testGetOutputWhileDisabled($fetchMethod) - { - $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); - $p->disableOutput(); - $p->start(); - $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Output has been disabled.'); - $p->{$fetchMethod}(); - } - - public function provideOutputFetchingMethods() - { - return array( - array('getOutput'), - array('getIncrementalOutput'), - array('getErrorOutput'), - array('getIncrementalErrorOutput'), - ); - } - - public function responsesCodeProvider() - { - return array( - //expected output / getter / code to execute - //array(1,'getExitCode','exit(1);'), - //array(true,'isSuccessful','exit();'), - array('output', 'getOutput', 'echo \'output\';'), - ); - } - - public function pipesCodeProvider() - { - $variations = array( - 'fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);', - 'include \''.__DIR__.'/PipeStdinInStdoutStdErrStreamSelect.php\';', - ); - - if ('\\' === DIRECTORY_SEPARATOR) { - // Avoid XL buffers on Windows because of https://bugs.php.net/bug.php?id=65650 - $sizes = array(1, 2, 4, 8); - } else { - $sizes = array(1, 16, 64, 1024, 4096); - } - - $codes = array(); - foreach ($sizes as $size) { - foreach ($variations as $code) { - $codes[] = array($code, $size); - } - } - - return $codes; - } - - /** - * provides default method names for simple getter/setter. - */ - public function methodProvider() - { - $defaults = array( - array('CommandLine'), - array('Timeout'), - array('WorkingDirectory'), - array('Env'), - array('Stdin'), - array('Input'), - array('Options'), - ); - - return $defaults; - } - - /** - * @param string $commandline - * @param null|string $cwd - * @param null|array $env - * @param null|string $input - * @param int $timeout - * @param array $options - * - * @return Process - */ - abstract protected function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()); -} - -class Stringifiable -{ - public function __toString() - { - return 'stringifiable'; - } -} - -class NonStringifiable -{ -} diff --git a/library/symfony/process/Tests/ExecutableFinderTest.php b/library/symfony/process/Tests/ExecutableFinderTest.php deleted file mode 100644 index 812429e88..000000000 --- a/library/symfony/process/Tests/ExecutableFinderTest.php +++ /dev/null @@ -1,144 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\ExecutableFinder; - -/** - * @author Chris Smith <chris@cs278.org> - */ -class ExecutableFinderTest extends \PHPUnit_Framework_TestCase -{ - private $path; - - protected function tearDown() - { - if ($this->path) { - // Restore path if it was changed. - putenv('PATH='.$this->path); - } - } - - private function setPath($path) - { - $this->path = getenv('PATH'); - putenv('PATH='.$path); - } - - /** - * @requires PHP 5.4 - */ - public function testFind() - { - if (ini_get('open_basedir')) { - $this->markTestSkipped('Cannot test when open_basedir is set'); - } - - $this->setPath(dirname(PHP_BINARY)); - - $finder = new ExecutableFinder(); - $result = $finder->find($this->getPhpBinaryName()); - - $this->assertSamePath(PHP_BINARY, $result); - } - - public function testFindWithDefault() - { - if (ini_get('open_basedir')) { - $this->markTestSkipped('Cannot test when open_basedir is set'); - } - - $expected = 'defaultValue'; - - $this->setPath(''); - - $finder = new ExecutableFinder(); - $result = $finder->find('foo', $expected); - - $this->assertEquals($expected, $result); - } - - /** - * @requires PHP 5.4 - */ - public function testFindWithExtraDirs() - { - if (ini_get('open_basedir')) { - $this->markTestSkipped('Cannot test when open_basedir is set'); - } - - $this->setPath(''); - - $extraDirs = array(dirname(PHP_BINARY)); - - $finder = new ExecutableFinder(); - $result = $finder->find($this->getPhpBinaryName(), null, $extraDirs); - - $this->assertSamePath(PHP_BINARY, $result); - } - - /** - * @requires PHP 5.4 - */ - public function testFindWithOpenBaseDir() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Cannot run test on windows'); - } - - if (ini_get('open_basedir')) { - $this->markTestSkipped('Cannot test when open_basedir is set'); - } - - $this->iniSet('open_basedir', dirname(PHP_BINARY).(!defined('HHVM_VERSION') ? PATH_SEPARATOR.'/' : '')); - - $finder = new ExecutableFinder(); - $result = $finder->find($this->getPhpBinaryName()); - - $this->assertSamePath(PHP_BINARY, $result); - } - - /** - * @requires PHP 5.4 - */ - public function testFindProcessInOpenBasedir() - { - if (ini_get('open_basedir')) { - $this->markTestSkipped('Cannot test when open_basedir is set'); - } - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Cannot run test on windows'); - } - - $this->setPath(''); - $this->iniSet('open_basedir', PHP_BINARY.(!defined('HHVM_VERSION') ? PATH_SEPARATOR.'/' : '')); - - $finder = new ExecutableFinder(); - $result = $finder->find($this->getPhpBinaryName(), false); - - $this->assertSamePath(PHP_BINARY, $result); - } - - private function assertSamePath($expected, $tested) - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertEquals(strtolower($expected), strtolower($tested)); - } else { - $this->assertEquals($expected, $tested); - } - } - - private function getPhpBinaryName() - { - return basename(PHP_BINARY, '\\' === DIRECTORY_SEPARATOR ? '.exe' : ''); - } -} diff --git a/library/symfony/process/Tests/NonStopableProcess.php b/library/symfony/process/Tests/NonStopableProcess.php deleted file mode 100644 index 54510c16a..000000000 --- a/library/symfony/process/Tests/NonStopableProcess.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Runs a PHP script that can be stopped only with a SIGKILL (9) signal for 3 seconds. - * - * @args duration Run this script with a custom duration - * - * @example `php NonStopableProcess.php 42` will run the script for 42 seconds - */ -function handleSignal($signal) -{ - switch ($signal) { - case SIGTERM: - $name = 'SIGTERM'; - break; - case SIGINT: - $name = 'SIGINT'; - break; - default: - $name = $signal.' (unknown)'; - break; - } - - echo "received signal $name\n"; -} - -declare (ticks = 1); -pcntl_signal(SIGTERM, 'handleSignal'); -pcntl_signal(SIGINT, 'handleSignal'); - -$duration = isset($argv[1]) ? (int) $argv[1] : 3; -$start = microtime(true); - -while ($duration > (microtime(true) - $start)) { - usleep(1000); -} diff --git a/library/symfony/process/Tests/PhpExecutableFinderTest.php b/library/symfony/process/Tests/PhpExecutableFinderTest.php deleted file mode 100644 index 87d0efe9e..000000000 --- a/library/symfony/process/Tests/PhpExecutableFinderTest.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\PhpExecutableFinder; - -/** - * @author Robert Schönthal <seroscho@googlemail.com> - */ -class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase -{ - /** - * tests find() with the env var PHP_PATH. - */ - public function testFindWithPhpPath() - { - if (defined('PHP_BINARY')) { - $this->markTestSkipped('The PHP binary is easily available as of PHP 5.4'); - } - - $f = new PhpExecutableFinder(); - - $current = $f->find(); - - //not executable PHP_PATH - putenv('PHP_PATH=/not/executable/php'); - $this->assertFalse($f->find(), '::find() returns false for not executable PHP'); - $this->assertFalse($f->find(false), '::find() returns false for not executable PHP'); - - //executable PHP_PATH - putenv('PHP_PATH='.$current); - $this->assertEquals($f->find(), $current, '::find() returns the executable PHP'); - $this->assertEquals($f->find(false), $current, '::find() returns the executable PHP'); - } - - /** - * tests find() with the constant PHP_BINARY. - * - * @requires PHP 5.4 - */ - public function testFind() - { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('Should not be executed in HHVM context.'); - } - - $f = new PhpExecutableFinder(); - - $current = PHP_BINARY; - $args = 'phpdbg' === PHP_SAPI ? ' -qrr' : ''; - - $this->assertEquals($current.$args, $f->find(), '::find() returns the executable PHP'); - $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP'); - } - - /** - * tests find() with the env var / constant PHP_BINARY with HHVM. - */ - public function testFindWithHHVM() - { - if (!defined('HHVM_VERSION')) { - $this->markTestSkipped('Should be executed in HHVM context.'); - } - - $f = new PhpExecutableFinder(); - - $current = getenv('PHP_BINARY') ?: PHP_BINARY; - - $this->assertEquals($current.' --php', $f->find(), '::find() returns the executable PHP'); - $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP'); - } - - /** - * tests find() with the env var PHP_PATH. - */ - public function testFindArguments() - { - $f = new PhpExecutableFinder(); - - if (defined('HHVM_VERSION')) { - $this->assertEquals($f->findArguments(), array('--php'), '::findArguments() returns HHVM arguments'); - } elseif ('phpdbg' === PHP_SAPI) { - $this->assertEquals($f->findArguments(), array('-qrr'), '::findArguments() returns phpdbg arguments'); - } else { - $this->assertEquals($f->findArguments(), array(), '::findArguments() returns no arguments'); - } - } - - /** - * tests find() with default executable. - */ - public function testFindWithSuffix() - { - if (defined('PHP_BINARY')) { - $this->markTestSkipped('The PHP binary is easily available as of PHP 5.4'); - } - - putenv('PHP_PATH='); - putenv('PHP_PEAR_PHP_BIN='); - $f = new PhpExecutableFinder(); - - $current = $f->find(); - - //TODO maybe php executable is custom or even Windows - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertTrue(is_executable($current)); - $this->assertTrue((bool) preg_match('/'.addslashes(DIRECTORY_SEPARATOR).'php\.(exe|bat|cmd|com)$/i', $current), '::find() returns the executable PHP with suffixes'); - } - } -} diff --git a/library/symfony/process/Tests/PhpProcessTest.php b/library/symfony/process/Tests/PhpProcessTest.php deleted file mode 100644 index 2cf79aa1a..000000000 --- a/library/symfony/process/Tests/PhpProcessTest.php +++ /dev/null @@ -1,53 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\PhpExecutableFinder; -use Symfony\Component\Process\PhpProcess; - -class PhpProcessTest extends \PHPUnit_Framework_TestCase -{ - public function testNonBlockingWorks() - { - $expected = 'hello world!'; - $process = new PhpProcess(<<<PHP -<?php echo '$expected'; -PHP - ); - $process->start(); - $process->wait(); - $this->assertEquals($expected, $process->getOutput()); - } - - public function testCommandLine() - { - if ('phpdbg' === PHP_SAPI) { - $this->markTestSkipped('phpdbg SAPI is not supported by this test.'); - } - - $process = new PhpProcess(<<<PHP -<?php echo 'foobar'; -PHP - ); - - $f = new PhpExecutableFinder(); - $commandLine = $f->find(); - - $this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP before start'); - - $process->start(); - $this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start'); - - $process->wait(); - $this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait'); - } -} diff --git a/library/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php b/library/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php deleted file mode 100644 index bbd7ddfeb..000000000 --- a/library/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -define('ERR_SELECT_FAILED', 1); -define('ERR_TIMEOUT', 2); -define('ERR_READ_FAILED', 3); -define('ERR_WRITE_FAILED', 4); - -$read = array(STDIN); -$write = array(STDOUT, STDERR); - -stream_set_blocking(STDIN, 0); -stream_set_blocking(STDOUT, 0); -stream_set_blocking(STDERR, 0); - -$out = $err = ''; -while ($read || $write) { - $r = $read; - $w = $write; - $e = null; - $n = stream_select($r, $w, $e, 5); - - if (false === $n) { - die(ERR_SELECT_FAILED); - } elseif ($n < 1) { - die(ERR_TIMEOUT); - } - - if (in_array(STDOUT, $w) && strlen($out) > 0) { - $written = fwrite(STDOUT, (binary) $out, 32768); - if (false === $written) { - die(ERR_WRITE_FAILED); - } - $out = (binary) substr($out, $written); - } - if (null === $read && '' === $out) { - $write = array_diff($write, array(STDOUT)); - } - - if (in_array(STDERR, $w) && strlen($err) > 0) { - $written = fwrite(STDERR, (binary) $err, 32768); - if (false === $written) { - die(ERR_WRITE_FAILED); - } - $err = (binary) substr($err, $written); - } - if (null === $read && '' === $err) { - $write = array_diff($write, array(STDERR)); - } - - if ($r) { - $str = fread(STDIN, 32768); - if (false !== $str) { - $out .= $str; - $err .= $str; - } - if (false === $str || feof(STDIN)) { - $read = null; - if (!feof(STDIN)) { - die(ERR_READ_FAILED); - } - } - } -} diff --git a/library/symfony/process/Tests/ProcessBuilderTest.php b/library/symfony/process/Tests/ProcessBuilderTest.php deleted file mode 100644 index 1b5056d1b..000000000 --- a/library/symfony/process/Tests/ProcessBuilderTest.php +++ /dev/null @@ -1,225 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\ProcessBuilder; - -class ProcessBuilderTest extends \PHPUnit_Framework_TestCase -{ - public function testInheritEnvironmentVars() - { - $_ENV['MY_VAR_1'] = 'foo'; - - $proc = ProcessBuilder::create() - ->add('foo') - ->getProcess(); - - unset($_ENV['MY_VAR_1']); - - $env = $proc->getEnv(); - $this->assertArrayHasKey('MY_VAR_1', $env); - $this->assertEquals('foo', $env['MY_VAR_1']); - } - - public function testAddEnvironmentVariables() - { - $pb = new ProcessBuilder(); - $env = array( - 'foo' => 'bar', - 'foo2' => 'bar2', - ); - $proc = $pb - ->add('command') - ->setEnv('foo', 'bar2') - ->addEnvironmentVariables($env) - ->inheritEnvironmentVariables(false) - ->getProcess() - ; - - $this->assertSame($env, $proc->getEnv()); - } - - public function testProcessShouldInheritAndOverrideEnvironmentVars() - { - $_ENV['MY_VAR_1'] = 'foo'; - - $proc = ProcessBuilder::create() - ->setEnv('MY_VAR_1', 'bar') - ->add('foo') - ->getProcess(); - - unset($_ENV['MY_VAR_1']); - - $env = $proc->getEnv(); - $this->assertArrayHasKey('MY_VAR_1', $env); - $this->assertEquals('bar', $env['MY_VAR_1']); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException - */ - public function testNegativeTimeoutFromSetter() - { - $pb = new ProcessBuilder(); - $pb->setTimeout(-1); - } - - public function testNullTimeout() - { - $pb = new ProcessBuilder(); - $pb->setTimeout(10); - $pb->setTimeout(null); - - $r = new \ReflectionObject($pb); - $p = $r->getProperty('timeout'); - $p->setAccessible(true); - - $this->assertNull($p->getValue($pb)); - } - - public function testShouldSetArguments() - { - $pb = new ProcessBuilder(array('initial')); - $pb->setArguments(array('second')); - - $proc = $pb->getProcess(); - - $this->assertContains('second', $proc->getCommandLine()); - } - - public function testPrefixIsPrependedToAllGeneratedProcess() - { - $pb = new ProcessBuilder(); - $pb->setPrefix('/usr/bin/php'); - - $proc = $pb->setArguments(array('-v'))->getProcess(); - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertEquals('"/usr/bin/php" "-v"', $proc->getCommandLine()); - } else { - $this->assertEquals("'/usr/bin/php' '-v'", $proc->getCommandLine()); - } - - $proc = $pb->setArguments(array('-i'))->getProcess(); - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertEquals('"/usr/bin/php" "-i"', $proc->getCommandLine()); - } else { - $this->assertEquals("'/usr/bin/php' '-i'", $proc->getCommandLine()); - } - } - - public function testArrayPrefixesArePrependedToAllGeneratedProcess() - { - $pb = new ProcessBuilder(); - $pb->setPrefix(array('/usr/bin/php', 'composer.phar')); - - $proc = $pb->setArguments(array('-v'))->getProcess(); - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertEquals('"/usr/bin/php" "composer.phar" "-v"', $proc->getCommandLine()); - } else { - $this->assertEquals("'/usr/bin/php' 'composer.phar' '-v'", $proc->getCommandLine()); - } - - $proc = $pb->setArguments(array('-i'))->getProcess(); - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertEquals('"/usr/bin/php" "composer.phar" "-i"', $proc->getCommandLine()); - } else { - $this->assertEquals("'/usr/bin/php' 'composer.phar' '-i'", $proc->getCommandLine()); - } - } - - public function testShouldEscapeArguments() - { - $pb = new ProcessBuilder(array('%path%', 'foo " bar', '%baz%baz')); - $proc = $pb->getProcess(); - - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertSame('^%"path"^% "foo \\" bar" "%baz%baz"', $proc->getCommandLine()); - } else { - $this->assertSame("'%path%' 'foo \" bar' '%baz%baz'", $proc->getCommandLine()); - } - } - - public function testShouldEscapeArgumentsAndPrefix() - { - $pb = new ProcessBuilder(array('arg')); - $pb->setPrefix('%prefix%'); - $proc = $pb->getProcess(); - - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertSame('^%"prefix"^% "arg"', $proc->getCommandLine()); - } else { - $this->assertSame("'%prefix%' 'arg'", $proc->getCommandLine()); - } - } - - /** - * @expectedException \Symfony\Component\Process\Exception\LogicException - */ - public function testShouldThrowALogicExceptionIfNoPrefixAndNoArgument() - { - ProcessBuilder::create()->getProcess(); - } - - public function testShouldNotThrowALogicExceptionIfNoArgument() - { - $process = ProcessBuilder::create() - ->setPrefix('/usr/bin/php') - ->getProcess(); - - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertEquals('"/usr/bin/php"', $process->getCommandLine()); - } else { - $this->assertEquals("'/usr/bin/php'", $process->getCommandLine()); - } - } - - public function testShouldNotThrowALogicExceptionIfNoPrefix() - { - $process = ProcessBuilder::create(array('/usr/bin/php')) - ->getProcess(); - - if ('\\' === DIRECTORY_SEPARATOR) { - $this->assertEquals('"/usr/bin/php"', $process->getCommandLine()); - } else { - $this->assertEquals("'/usr/bin/php'", $process->getCommandLine()); - } - } - - public function testShouldReturnProcessWithDisabledOutput() - { - $process = ProcessBuilder::create(array('/usr/bin/php')) - ->disableOutput() - ->getProcess(); - - $this->assertTrue($process->isOutputDisabled()); - } - - public function testShouldReturnProcessWithEnabledOutput() - { - $process = ProcessBuilder::create(array('/usr/bin/php')) - ->disableOutput() - ->enableOutput() - ->getProcess(); - - $this->assertFalse($process->isOutputDisabled()); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException - * @expectedExceptionMessage Symfony\Component\Process\ProcessBuilder::setInput only accepts strings or stream resources. - */ - public function testInvalidInput() - { - $builder = ProcessBuilder::create(); - $builder->setInput(array()); - } -} diff --git a/library/symfony/process/Tests/ProcessFailedExceptionTest.php b/library/symfony/process/Tests/ProcessFailedExceptionTest.php deleted file mode 100644 index 0d763a470..000000000 --- a/library/symfony/process/Tests/ProcessFailedExceptionTest.php +++ /dev/null @@ -1,146 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\Exception\ProcessFailedException; - -/** - * @author Sebastian Marek <proofek@gmail.com> - */ -class ProcessFailedExceptionTest extends \PHPUnit_Framework_TestCase -{ - /** - * tests ProcessFailedException throws exception if the process was successful. - */ - public function testProcessFailedExceptionThrowsException() - { - $process = $this->getMock( - 'Symfony\Component\Process\Process', - array('isSuccessful'), - array('php') - ); - $process->expects($this->once()) - ->method('isSuccessful') - ->will($this->returnValue(true)); - - $this->setExpectedException( - '\InvalidArgumentException', - 'Expected a failed process, but the given process was successful.' - ); - - new ProcessFailedException($process); - } - - /** - * tests ProcessFailedException uses information from process output - * to generate exception message. - */ - public function testProcessFailedExceptionPopulatesInformationFromProcessOutput() - { - $cmd = 'php'; - $exitCode = 1; - $exitText = 'General error'; - $output = 'Command output'; - $errorOutput = 'FATAL: Unexpected error'; - $workingDirectory = getcwd(); - - $process = $this->getMock( - 'Symfony\Component\Process\Process', - array('isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'), - array($cmd) - ); - $process->expects($this->once()) - ->method('isSuccessful') - ->will($this->returnValue(false)); - - $process->expects($this->once()) - ->method('getOutput') - ->will($this->returnValue($output)); - - $process->expects($this->once()) - ->method('getErrorOutput') - ->will($this->returnValue($errorOutput)); - - $process->expects($this->once()) - ->method('getExitCode') - ->will($this->returnValue($exitCode)); - - $process->expects($this->once()) - ->method('getExitCodeText') - ->will($this->returnValue($exitText)); - - $process->expects($this->once()) - ->method('isOutputDisabled') - ->will($this->returnValue(false)); - - $process->expects($this->once()) - ->method('getWorkingDirectory') - ->will($this->returnValue($workingDirectory)); - - $exception = new ProcessFailedException($process); - - $this->assertEquals( - "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}", - $exception->getMessage() - ); - } - - /** - * Tests that ProcessFailedException does not extract information from - * process output if it was previously disabled. - */ - public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput() - { - $cmd = 'php'; - $exitCode = 1; - $exitText = 'General error'; - $workingDirectory = getcwd(); - - $process = $this->getMock( - 'Symfony\Component\Process\Process', - array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'), - array($cmd) - ); - $process->expects($this->once()) - ->method('isSuccessful') - ->will($this->returnValue(false)); - - $process->expects($this->never()) - ->method('getOutput'); - - $process->expects($this->never()) - ->method('getErrorOutput'); - - $process->expects($this->once()) - ->method('getExitCode') - ->will($this->returnValue($exitCode)); - - $process->expects($this->once()) - ->method('getExitCodeText') - ->will($this->returnValue($exitText)); - - $process->expects($this->once()) - ->method('isOutputDisabled') - ->will($this->returnValue(true)); - - $process->expects($this->once()) - ->method('getWorkingDirectory') - ->will($this->returnValue($workingDirectory)); - - $exception = new ProcessFailedException($process); - - $this->assertEquals( - "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}", - $exception->getMessage() - ); - } -} diff --git a/library/symfony/process/Tests/ProcessInSigchildEnvironment.php b/library/symfony/process/Tests/ProcessInSigchildEnvironment.php deleted file mode 100644 index 3977bcdcf..000000000 --- a/library/symfony/process/Tests/ProcessInSigchildEnvironment.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\Process; - -class ProcessInSigchildEnvironment extends Process -{ - protected function isSigchildEnabled() - { - return true; - } -} diff --git a/library/symfony/process/Tests/ProcessUtilsTest.php b/library/symfony/process/Tests/ProcessUtilsTest.php deleted file mode 100644 index e6564cde5..000000000 --- a/library/symfony/process/Tests/ProcessUtilsTest.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\ProcessUtils; - -class ProcessUtilsTest extends \PHPUnit_Framework_TestCase -{ - /** - * @dataProvider dataArguments - */ - public function testEscapeArgument($result, $argument) - { - $this->assertSame($result, ProcessUtils::escapeArgument($argument)); - } - - public function dataArguments() - { - if ('\\' === DIRECTORY_SEPARATOR) { - return array( - array('"\"php\" \"-v\""', '"php" "-v"'), - array('"foo bar"', 'foo bar'), - array('^%"path"^%', '%path%'), - array('"<|>\\" \\"\'f"', '<|>" "\'f'), - array('""', ''), - array('"with\trailingbs\\\\"', 'with\trailingbs\\'), - ); - } - - return array( - array("'\"php\" \"-v\"'", '"php" "-v"'), - array("'foo bar'", 'foo bar'), - array("'%path%'", '%path%'), - array("'<|>\" \"'\\''f'", '<|>" "\'f'), - array("''", ''), - array("'with\\trailingbs\\'", 'with\trailingbs\\'), - ); - } -} diff --git a/library/symfony/process/Tests/SigchildDisabledProcessTest.php b/library/symfony/process/Tests/SigchildDisabledProcessTest.php deleted file mode 100644 index fdae5ec25..000000000 --- a/library/symfony/process/Tests/SigchildDisabledProcessTest.php +++ /dev/null @@ -1,263 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -class SigchildDisabledProcessTest extends AbstractProcessTest -{ - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testGetExitCode() - { - parent::testGetExitCode(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testGetExitCodeIsNullOnStart() - { - parent::testGetExitCodeIsNullOnStart(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testGetExitCodeIsNullOnWhenStartingAgain() - { - parent::testGetExitCodeIsNullOnWhenStartingAgain(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testExitCodeCommandFailed() - { - parent::testExitCodeCommandFailed(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testMustRun() - { - parent::testMustRun(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testSuccessfulMustRunHasCorrectExitCode() - { - parent::testSuccessfulMustRunHasCorrectExitCode(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - */ - public function testMustRunThrowsException() - { - parent::testMustRunThrowsException(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - */ - public function testProcessIsSignaledIfStopped() - { - parent::testProcessIsSignaledIfStopped(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithTermSignal() - { - parent::testProcessWithTermSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessIsNotSignaled() - { - parent::testProcessIsNotSignaled(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithoutTermSignal() - { - parent::testProcessWithoutTermSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testCheckTimeoutOnStartedProcess() - { - parent::testCheckTimeoutOnStartedProcess(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPid() - { - parent::testGetPid(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPidIsNullBeforeStart() - { - parent::testGetPidIsNullBeforeStart(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPidIsNullAfterRun() - { - parent::testGetPidIsNullAfterRun(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testExitCodeText() - { - $process = $this->getProcess('qdfsmfkqsdfmqmsd'); - $process->run(); - - $process->getExitCodeText(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testExitCodeTextIsNullWhenExitCodeIsNull() - { - parent::testExitCodeTextIsNullWhenExitCodeIsNull(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testIsSuccessful() - { - parent::testIsSuccessful(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testIsSuccessfulOnlyAfterTerminated() - { - parent::testIsSuccessfulOnlyAfterTerminated(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testIsNotSuccessful() - { - parent::testIsNotSuccessful(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testTTYCommandExitCode() - { - parent::testTTYCommandExitCode(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process can not be signaled. - */ - public function testSignal() - { - parent::testSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithoutTermSignalIsNotSignaled() - { - parent::testProcessWithoutTermSignalIsNotSignaled(); - } - - public function testStopWithTimeoutIsActuallyWorking() - { - $this->markTestSkipped('Stopping with signal is not supported in sigchild environment'); - } - - public function testProcessThrowsExceptionWhenExternallySignaled() - { - $this->markTestSkipped('Retrieving Pid is not supported in sigchild environment'); - } - - public function testExitCodeIsAvailableAfterSignal() - { - $this->markTestSkipped('Signal is not supported in sigchild environment'); - } - - public function testRunProcessWithTimeout() - { - $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); - } - - public function provideStartMethods() - { - return array( - array('start', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'), - array('run', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'), - array('mustRun', 'Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'), - ); - } - - /** - * {@inheritdoc} - */ - protected function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()) - { - $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $input, $timeout, $options); - $process->setEnhanceSigchildCompatibility(false); - - return $process; - } -} diff --git a/library/symfony/process/Tests/SigchildEnabledProcessTest.php b/library/symfony/process/Tests/SigchildEnabledProcessTest.php deleted file mode 100644 index 2668a9b4b..000000000 --- a/library/symfony/process/Tests/SigchildEnabledProcessTest.php +++ /dev/null @@ -1,148 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -class SigchildEnabledProcessTest extends AbstractProcessTest -{ - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessIsSignaledIfStopped() - { - parent::testProcessIsSignaledIfStopped(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithTermSignal() - { - parent::testProcessWithTermSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessIsNotSignaled() - { - parent::testProcessIsNotSignaled(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithoutTermSignal() - { - parent::testProcessWithoutTermSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPid() - { - parent::testGetPid(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPidIsNullBeforeStart() - { - parent::testGetPidIsNullBeforeStart(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPidIsNullAfterRun() - { - parent::testGetPidIsNullAfterRun(); - } - - public function testExitCodeText() - { - $process = $this->getProcess('qdfsmfkqsdfmqmsd'); - $process->run(); - - $this->assertInternalType('string', $process->getExitCodeText()); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process can not be signaled. - */ - public function testSignal() - { - parent::testSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithoutTermSignalIsNotSignaled() - { - parent::testProcessWithoutTermSignalIsNotSignaled(); - } - - public function testProcessThrowsExceptionWhenExternallySignaled() - { - $this->markTestSkipped('Retrieving Pid is not supported in sigchild environment'); - } - - public function testExitCodeIsAvailableAfterSignal() - { - $this->markTestSkipped('Signal is not supported in sigchild environment'); - } - - public function testStartAfterATimeout() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Restarting a timed-out process on Windows is not supported in sigchild environment'); - } - parent::testStartAfterATimeout(); - } - - public function testStopWithTimeoutIsActuallyWorking() - { - $this->markTestSkipped('Stopping with signal is not supported in sigchild environment'); - } - - public function testRunProcessWithTimeout() - { - $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); - } - - public function testCheckTimeoutOnStartedProcess() - { - $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); - } - - /** - * {@inheritdoc} - */ - protected function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()) - { - $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $input, $timeout, $options); - $process->setEnhanceSigchildCompatibility(true); - - return $process; - } -} diff --git a/library/symfony/process/Tests/SignalListener.php b/library/symfony/process/Tests/SignalListener.php deleted file mode 100644 index 4206550f5..000000000 --- a/library/symfony/process/Tests/SignalListener.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -// required for signal handling -declare (ticks = 1); - -pcntl_signal(SIGUSR1, function () {echo 'Caught SIGUSR1'; exit;}); - -$n = 0; - -// ticks require activity to work - sleep(4); does not work -while ($n < 400) { - usleep(10000); - ++$n; -} - -return; diff --git a/library/symfony/process/Tests/SimpleProcessTest.php b/library/symfony/process/Tests/SimpleProcessTest.php deleted file mode 100644 index 78f20eb10..000000000 --- a/library/symfony/process/Tests/SimpleProcessTest.php +++ /dev/null @@ -1,216 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\Process; - -class SimpleProcessTest extends AbstractProcessTest -{ - private $enabledSigchild = false; - - protected function setUp() - { - ob_start(); - phpinfo(INFO_GENERAL); - - $this->enabledSigchild = false !== strpos(ob_get_clean(), '--enable-sigchild'); - } - - public function testGetExitCode() - { - $this->skipIfPHPSigchild(); // This test use exitcode that is not available in this case - parent::testGetExitCode(); - } - - public function testExitCodeCommandFailed() - { - $this->skipIfPHPSigchild(); // This test use exitcode that is not available in this case - parent::testExitCodeCommandFailed(); - } - - public function testProcessIsSignaledIfStopped() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessIsSignaledIfStopped(); - } - - public function testProcessWithTermSignal() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessWithTermSignal(); - } - - public function testProcessIsNotSignaled() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessIsNotSignaled(); - } - - public function testProcessWithoutTermSignal() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessWithoutTermSignal(); - } - - public function testExitCodeText() - { - $this->skipIfPHPSigchild(); // This test use exitcode that is not available in this case - parent::testExitCodeText(); - } - - public function testIsSuccessful() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testIsSuccessful(); - } - - public function testIsNotSuccessful() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testIsNotSuccessful(); - } - - public function testGetPid() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testGetPid(); - } - - public function testGetPidIsNullBeforeStart() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testGetPidIsNullBeforeStart(); - } - - public function testGetPidIsNullAfterRun() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testGetPidIsNullAfterRun(); - } - - public function testSignal() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - parent::testSignal(); - } - - public function testProcessWithoutTermSignalIsNotSignaled() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessWithoutTermSignalIsNotSignaled(); - } - - public function testProcessThrowsExceptionWhenExternallySignaled() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testProcessThrowsExceptionWhenExternallySignaled(); - } - - public function testExitCodeIsAvailableAfterSignal() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - parent::testExitCodeIsAvailableAfterSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\LogicException - * @expectedExceptionMessage Can not send signal on a non running process. - */ - public function testSignalProcessNotRunning() - { - parent::testSignalProcessNotRunning(); - } - - public function testSignalWithWrongIntSignal() - { - if ($this->enabledSigchild) { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - } else { - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Error while sending signal `-4`.'); - } - parent::testSignalWithWrongIntSignal(); - } - - public function testSignalWithWrongNonIntSignal() - { - if ($this->enabledSigchild) { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - } else { - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Error while sending signal `Céphalopodes`.'); - } - parent::testSignalWithWrongNonIntSignal(); - } - - public function testStopTerminatesProcessCleanly() - { - $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); - $process->run(function () use ($process) { - $process->stop(); - }); - $this->assertTrue(true, 'A call to stop() is not expected to cause wait() to throw a RuntimeException'); - } - - public function testKillSignalTerminatesProcessCleanly() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - - $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); - $process->run(function () use ($process) { - if ($process->isRunning()) { - $process->signal(defined('SIGKILL') ? SIGKILL : 9); - } - }); - $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException'); - } - - public function testTermSignalTerminatesProcessCleanly() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - - $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); - $process->run(function () use ($process) { - if ($process->isRunning()) { - $process->signal(defined('SIGTERM') ? SIGTERM : 15); - } - }); - $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException'); - } - - public function testStopWithTimeoutIsActuallyWorking() - { - $this->skipIfPHPSigchild(); - - parent::testStopWithTimeoutIsActuallyWorking(); - } - - /** - * {@inheritdoc} - */ - protected function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()) - { - return new Process($commandline, $cwd, $env, $input, $timeout, $options); - } - - private function skipIfPHPSigchild() - { - if ($this->enabledSigchild) { - $this->markTestSkipped('Your PHP has been compiled with --enable-sigchild, this test can not be executed'); - } - } - - private function expectExceptionIfPHPSigchild($classname, $message) - { - if ($this->enabledSigchild) { - $this->setExpectedException($classname, $message); - } - } -} diff --git a/library/symfony/process/phpunit.xml.dist b/library/symfony/process/phpunit.xml.dist deleted file mode 100644 index 788500084..000000000 --- a/library/symfony/process/phpunit.xml.dist +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd" - backupGlobals="false" - colors="true" - bootstrap="vendor/autoload.php" -> - <php> - <ini name="error_reporting" value="-1" /> - </php> - - <testsuites> - <testsuite name="Symfony Process Component Test Suite"> - <directory>./Tests/</directory> - </testsuite> - </testsuites> - - <filter> - <whitelist> - <directory>./</directory> - <exclude> - <directory>./Tests</directory> - <directory>./vendor</directory> - </exclude> - </whitelist> - </filter> -</phpunit> diff --git a/library/tiptip/README b/library/tiptip/README deleted file mode 100644 index a83cfba3e..000000000 --- a/library/tiptip/README +++ /dev/null @@ -1,30 +0,0 @@ -http://code.drewwilson.com/entry/tiptip-jquery-plugin - -License -This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses. - - -ChangeLog -Version 1.3 (Mar. 23, 2010) - - Added defaultPoistion option that enables you to set the default orientation TipTip should show up as. - Added attribute option that enables you to set the HTML attribute that TipTip should pull it's content from. - Added content option. This will be used as the content for the TipTip and will overwrite any content pulled form any HTML attribute. - Added activation option enables you to specify the jQuery method TipTip is activated with: hover, focus or click. Now you can use TipTip on forms and for validation! - Added keepAlive option that when set to true the TipTip will only fadeout when you hover over the actual TipTip and then hover off of it. Allowing for hyperlinks inside your TipTip content to be accessible. - -Version 1.2 (Jan. 13, 2010) - - Added HTML support with Tip Tip. You can now add HTML into the Title attribute (though this is not recommended if you want strictly valid code). - Tightened up spacing margins in JS. - Updated margins in CSS file. - -Version 1.1 (Jan. 03, 2010) - - Swapped dynamically added orientation CSS class names ('_left' & '_right') to make better sense. - Added in some tighter spacing for the tooltip in JS. - -Version 1.0 (Jan. 02, 2010) - - Initial release. - diff --git a/library/tiptip/README.txt b/library/tiptip/README.txt deleted file mode 100644 index 740d11a50..000000000 --- a/library/tiptip/README.txt +++ /dev/null @@ -1,25 +0,0 @@ -TipTip - -******* -small modification to work with jQuery 1.6.4 -(works also with jQuery 1.7b1) -******* - -Copyright 2010 Drew Wilson - -http://www.drewwilson.com -http://code.drewwilson.com/entry/tiptip-jquery-plugin - -Version 1.3 - Updated: Mar. 23, 2010 - -This Plug-In will create a custom tooltip to replace the default -browser tooltip. It is extremely lightweight and very smart in -that it detects the edges of the browser window and will make sure -the tooltip stays within the current window size. As a result the -tooltip will adjust itself to be displayed above, below, to the left -or to the right depending on what is necessary to stay within the -browser window. It is completely customizable as well via CSS. - -This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses: -http://www.opensource.org/licenses/mit-license.php -http://www.gnu.org/licenses/gpl.html
\ No newline at end of file diff --git a/library/tiptip/jquery.tipTip.js b/library/tiptip/jquery.tipTip.js deleted file mode 100644 index a05315dd7..000000000 --- a/library/tiptip/jquery.tipTip.js +++ /dev/null @@ -1,191 +0,0 @@ -/*! - * TipTip - * Copyright 2010 Drew Wilson - * www.drewwilson.com - * code.drewwilson.com/entry/tiptip-jquery-plugin - * - * Version 1.3 - Updated: Mar. 23, 2010 - * - * This Plug-In will create a custom tooltip to replace the default - * browser tooltip. It is extremely lightweight and very smart in - * that it detects the edges of the browser window and will make sure - * the tooltip stays within the current window size. As a result the - * tooltip will adjust itself to be displayed above, below, to the left - * or to the right depending on what is necessary to stay within the - * browser window. It is completely customizable as well via CSS. - * - * This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ - -(function($){ - $.fn.tipTip = function(options) { - var defaults = { - activation: "hover", - keepAlive: false, - maxWidth: "200px", - edgeOffset: 3, - defaultPosition: "bottom", - delay: 400, - fadeIn: 200, - fadeOut: 200, - attribute: "title", - content: false, // HTML or String to fill TipTIp with - enter: function(){}, - exit: function(){} - }; - var opts = $.extend(defaults, options); - - // Setup tip tip elements and render them to the DOM - if($("#tiptip_holder").length <= 0){ - var tiptip_holder = $('<div id="tiptip_holder" style="max-width:'+ opts.maxWidth +';"></div>'); - var tiptip_content = $('<div id="tiptip_content"></div>'); - var tiptip_arrow = $('<div id="tiptip_arrow"></div>'); - $("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('<div id="tiptip_arrow_inner"></div>'))); - } else { - var tiptip_holder = $("#tiptip_holder"); - var tiptip_content = $("#tiptip_content"); - var tiptip_arrow = $("#tiptip_arrow"); - } - - return this.each(function(){ - var org_elem = $(this); - if(opts.content){ - var org_title = opts.content; - } else { - var org_title = org_elem.attr(opts.attribute); - } - if(org_title && org_title != ""){ - if(!opts.content){ - org_elem.removeAttr(opts.attribute); //remove original Attribute - } - var timeout = false; - - if(opts.activation == "hover"){ - org_elem.hover(function(){ - active_tiptip(); - }, function(){ - if(!opts.keepAlive){ - deactive_tiptip(); - } - }); - if(opts.keepAlive){ - tiptip_holder.hover(function(){}, function(){ - deactive_tiptip(); - }); - } - } else if(opts.activation == "focus"){ - org_elem.focus(function(){ - active_tiptip(); - }).blur(function(){ - deactive_tiptip(); - }); - } else if(opts.activation == "click"){ - org_elem.click(function(){ - active_tiptip(); - return false; - }).hover(function(){},function(){ - if(!opts.keepAlive){ - deactive_tiptip(); - } - }); - if(opts.keepAlive){ - tiptip_holder.hover(function(){}, function(){ - deactive_tiptip(); - }); - } - } - - function active_tiptip(){ - opts.enter.call(this); - tiptip_content.html(org_title); - tiptip_holder.hide().removeAttr("class").css("margin","0"); - tiptip_arrow.removeAttr("style"); - - var top = parseInt(org_elem.offset()['top']); - var left = parseInt(org_elem.offset()['left']); - var org_width = parseInt(org_elem.outerWidth()); - var org_height = parseInt(org_elem.outerHeight()); - var tip_w = tiptip_holder.outerWidth(); - var tip_h = tiptip_holder.outerHeight(); - var w_compare = Math.round((org_width - tip_w) / 2); - var h_compare = Math.round((org_height - tip_h) / 2); - var marg_left = Math.round(left + w_compare); - var marg_top = Math.round(top + org_height + opts.edgeOffset); - var t_class = ""; - var arrow_top = ""; - var arrow_left = Math.round(tip_w - 12) / 2; - - if(opts.defaultPosition == "bottom"){ - t_class = "_bottom"; - } else if(opts.defaultPosition == "top"){ - t_class = "_top"; - } else if(opts.defaultPosition == "left"){ - t_class = "_left"; - } else if(opts.defaultPosition == "right"){ - t_class = "_right"; - } - - var right_compare = (w_compare + left) < parseInt($(window).scrollLeft()); - var left_compare = (tip_w + left) > parseInt($(window).width()); - - if((right_compare && w_compare < 0) || (t_class == "_right" && !left_compare) || (t_class == "_left" && left < (tip_w + opts.edgeOffset + 5))){ - t_class = "_right"; - arrow_top = Math.round(tip_h - 13) / 2; - arrow_left = -12; - marg_left = Math.round(left + org_width + opts.edgeOffset); - marg_top = Math.round(top + h_compare); - } else if((left_compare && w_compare < 0) || (t_class == "_left" && !right_compare)){ - t_class = "_left"; - arrow_top = Math.round(tip_h - 13) / 2; - arrow_left = Math.round(tip_w); - marg_left = Math.round(left - (tip_w + opts.edgeOffset + 5)); - marg_top = Math.round(top + h_compare); - } - - var top_compare = (top + org_height + opts.edgeOffset + tip_h + 8) > parseInt($(window).height() + $(window).scrollTop()); - var bottom_compare = ((top + org_height) - (opts.edgeOffset + tip_h + 8)) < 0; - - if(top_compare || (t_class == "_bottom" && top_compare) || (t_class == "_top" && !bottom_compare)){ - if(t_class == "_top" || t_class == "_bottom"){ - t_class = "_top"; - } else { - t_class = t_class+"_top"; - } - arrow_top = tip_h; - marg_top = Math.round(top - (tip_h + 5 + opts.edgeOffset)); - } else if(bottom_compare | (t_class == "_top" && bottom_compare) || (t_class == "_bottom" && !top_compare)){ - if(t_class == "_top" || t_class == "_bottom"){ - t_class = "_bottom"; - } else { - t_class = t_class+"_bottom"; - } - arrow_top = -12; - marg_top = Math.round(top + org_height + opts.edgeOffset); - } - - if(t_class == "_right_top" || t_class == "_left_top"){ - marg_top = marg_top + 5; - } else if(t_class == "_right_bottom" || t_class == "_left_bottom"){ - marg_top = marg_top - 5; - } - if(t_class == "_left_top" || t_class == "_left_bottom"){ - marg_left = marg_left + 5; - } - tiptip_arrow.css({"margin-left": arrow_left+"px", "margin-top": arrow_top+"px"}); - tiptip_holder.css({"margin-left": marg_left+"px", "margin-top": marg_top+"px"}).attr("class","tip"+t_class); - - if (timeout){ clearTimeout(timeout); } - timeout = setTimeout(function(){ tiptip_holder.stop(true,true).fadeIn(opts.fadeIn); }, opts.delay); - } - - function deactive_tiptip(){ - opts.exit.call(this); - if (timeout){ clearTimeout(timeout); } - tiptip_holder.fadeOut(opts.fadeOut); - } - } - }); - } -})(jQuery);
\ No newline at end of file diff --git a/library/tiptip/jquery.tipTip.minified.js b/library/tiptip/jquery.tipTip.minified.js deleted file mode 100644 index 79e58f7ad..000000000 --- a/library/tiptip/jquery.tipTip.minified.js +++ /dev/null @@ -1,21 +0,0 @@ -/*! - * TipTip - * Copyright 2010 Drew Wilson - * www.drewwilson.com - * code.drewwilson.com/entry/tiptip-jquery-plugin - * - * Version 1.3 - Updated: Mar. 23, 2010 - * - * This Plug-In will create a custom tooltip to replace the default - * browser tooltip. It is extremely lightweight and very smart in - * that it detects the edges of the browser window and will make sure - * the tooltip stays within the current window size. As a result the - * tooltip will adjust itself to be displayed above, below, to the left - * or to the right depending on what is necessary to stay within the - * browser window. It is completely customizable as well via CSS. - * - * This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ -(function(a){a.fn.tipTip=function(c){var g={activation:"hover",keepAlive:false,maxWidth:"200px",edgeOffset:3,defaultPosition:"bottom",delay:400,fadeIn:200,fadeOut:200,attribute:"title",content:false,enter:function(){},exit:function(){}};var e=a.extend(g,c);if(a("#tiptip_holder").length<=0){var b=a('<div id="tiptip_holder" style="max-width:'+e.maxWidth+';"></div>');var d=a('<div id="tiptip_content"></div>');var f=a('<div id="tiptip_arrow"></div>');a("body").append(b.html(d).prepend(f.html('<div id="tiptip_arrow_inner"></div>')))}else{var b=a("#tiptip_holder");var d=a("#tiptip_content");var f=a("#tiptip_arrow")}return this.each(function(){var i=a(this);if(e.content){var l=e.content}else{var l=i.attr(e.attribute)}if(l&&l!=""){if(!e.content){i.removeAttr(e.attribute)}var h=false;if(e.activation=="hover"){i.hover(function(){k()},function(){if(!e.keepAlive){j()}});if(e.keepAlive){b.hover(function(){},function(){j()})}}else{if(e.activation=="focus"){i.focus(function(){k()}).blur(function(){j()})}else{if(e.activation=="click"){i.click(function(){k();return false}).hover(function(){},function(){if(!e.keepAlive){j()}});if(e.keepAlive){b.hover(function(){},function(){j()})}}}}function k(){e.enter.call(this);d.html(l);b.hide().removeAttr("class").css("margin","0");f.removeAttr("style");var y=parseInt(i.offset()["top"]);var p=parseInt(i.offset()["left"]);var v=parseInt(i.outerWidth());var A=parseInt(i.outerHeight());var x=b.outerWidth();var s=b.outerHeight();var w=Math.round((v-x)/2);var o=Math.round((A-s)/2);var n=Math.round(p+w);var m=Math.round(y+A+e.edgeOffset);var t="";var C="";var u=Math.round(x-12)/2;if(e.defaultPosition=="bottom"){t="_bottom"}else{if(e.defaultPosition=="top"){t="_top"}else{if(e.defaultPosition=="left"){t="_left"}else{if(e.defaultPosition=="right"){t="_right"}}}}var r=(w+p)<parseInt(a(window).scrollLeft());var q=(x+p)>parseInt(a(window).width());if((r&&w<0)||(t=="_right"&&!q)||(t=="_left"&&p<(x+e.edgeOffset+5))){t="_right";C=Math.round(s-13)/2;u=-12;n=Math.round(p+v+e.edgeOffset);m=Math.round(y+o)}else{if((q&&w<0)||(t=="_left"&&!r)){t="_left";C=Math.round(s-13)/2;u=Math.round(x);n=Math.round(p-(x+e.edgeOffset+5));m=Math.round(y+o)}}var z=(y+A+e.edgeOffset+s+8)>parseInt(a(window).height()+a(window).scrollTop());var B=((y+A)-(e.edgeOffset+s+8))<0;if(z||(t=="_bottom"&&z)||(t=="_top"&&!B)){if(t=="_top"||t=="_bottom"){t="_top"}else{t=t+"_top"}C=s;m=Math.round(y-(s+5+e.edgeOffset))}else{if(B|(t=="_top"&&B)||(t=="_bottom"&&!z)){if(t=="_top"||t=="_bottom"){t="_bottom"}else{t=t+"_bottom"}C=-12;m=Math.round(y+A+e.edgeOffset)}}if(t=="_right_top"||t=="_left_top"){m=m+5}else{if(t=="_right_bottom"||t=="_left_bottom"){m=m-5}}if(t=="_left_top"||t=="_left_bottom"){n=n+5}f.css({"margin-left":u+"px","margin-top":C+"px"});b.css({"margin-left":n+"px","margin-top":m+"px"}).attr("class","tip"+t);if(h){clearTimeout(h)}h=setTimeout(function(){b.stop(true,true).fadeIn(e.fadeIn)},e.delay)}function j(){e.exit.call(this);if(h){clearTimeout(h)}b.fadeOut(e.fadeOut)}}})}})(jQuery); diff --git a/library/tiptip/tipTip.css b/library/tiptip/tipTip.css deleted file mode 100644 index 4fb95d376..000000000 --- a/library/tiptip/tipTip.css +++ /dev/null @@ -1,113 +0,0 @@ -/* TipTip CSS - Version 1.2 */ - -#tiptip_holder { - display: none; - position: absolute; - top: 0; - left: 0; - z-index: 99999; -} - -#tiptip_holder.tip_top { - padding-bottom: 5px; -} - -#tiptip_holder.tip_bottom { - padding-top: 5px; -} - -#tiptip_holder.tip_right { - padding-left: 5px; -} - -#tiptip_holder.tip_left { - padding-right: 5px; -} - -#tiptip_content { - font-size: 11px; - color: #fff; - text-shadow: 0 0 2px #000; - padding: 4px 8px; - border: 1px solid rgba(255,255,255,0.25); - background-color: rgb(25,25,25); - background-color: rgba(25,25,25,0.92); - background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(transparent), to(#000)); - border-radius: 3px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - box-shadow: 0 0 3px #555; - -webkit-box-shadow: 0 0 3px #555; - -moz-box-shadow: 0 0 3px #555; -} - -#tiptip_arrow, #tiptip_arrow_inner { - position: absolute; - border-color: transparent; - border-style: solid; - border-width: 6px; - height: 0; - width: 0; -} - -#tiptip_holder.tip_top #tiptip_arrow { - border-top-color: #fff; - border-top-color: rgba(255,255,255,0.35); -} - -#tiptip_holder.tip_bottom #tiptip_arrow { - border-bottom-color: #fff; - border-bottom-color: rgba(255,255,255,0.35); -} - -#tiptip_holder.tip_right #tiptip_arrow { - border-right-color: #fff; - border-right-color: rgba(255,255,255,0.35); -} - -#tiptip_holder.tip_left #tiptip_arrow { - border-left-color: #fff; - border-left-color: rgba(255,255,255,0.35); -} - -#tiptip_holder.tip_top #tiptip_arrow_inner { - margin-top: -7px; - margin-left: -6px; - border-top-color: rgb(25,25,25); - border-top-color: rgba(25,25,25,0.92); -} - -#tiptip_holder.tip_bottom #tiptip_arrow_inner { - margin-top: -5px; - margin-left: -6px; - border-bottom-color: rgb(25,25,25); - border-bottom-color: rgba(25,25,25,0.92); -} - -#tiptip_holder.tip_right #tiptip_arrow_inner { - margin-top: -6px; - margin-left: -5px; - border-right-color: rgb(25,25,25); - border-right-color: rgba(25,25,25,0.92); -} - -#tiptip_holder.tip_left #tiptip_arrow_inner { - margin-top: -6px; - margin-left: -7px; - border-left-color: rgb(25,25,25); - border-left-color: rgba(25,25,25,0.92); -} - -/* Webkit Hacks */ -@media screen and (-webkit-min-device-pixel-ratio:0) { - #tiptip_content { - padding: 4px 8px 5px 8px; - background-color: rgba(45,45,45,0.88); - } - #tiptip_holder.tip_bottom #tiptip_arrow_inner { - border-bottom-color: rgba(45,45,45,0.88); - } - #tiptip_holder.tip_top #tiptip_arrow_inner { - border-top-color: rgba(20,20,20,0.92); - } -}
\ No newline at end of file |