From bd2462170b2c5ba7f9e304e032097229b3e4584a Mon Sep 17 00:00:00 2001 From: Naomi Date: Mon, 13 May 2013 11:42:11 -0400 Subject: [PATCH 1/8] CC-5121 : fix some SQL statements not being escaped/prepared --- airtime_mvc/application/models/Preference.php | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 6cba9814c..b20aacd26 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -106,43 +106,44 @@ class Application_Model_Preference private static function getValue($key, $isUserValue = false) { try { - $con = Propel::getConnection(); - + //Check if key already exists $sql = "SELECT COUNT(*) FROM cc_pref" - ." WHERE keystr = '$key'"; - /*." WHERE keystr = :key"; + ." WHERE keystr = :key"; + $paramMap = array(); - $paramMap[':key'] = $key;*/ + $paramMap[':key'] = $key; + //For user specific preference, check if id matches as well if ($isUserValue) { $auth = Zend_Auth::getInstance(); if ($auth->hasIdentity()) { $id = $auth->getIdentity()->id; - $sql .= " AND subjid = '$id'"; - /*$sql .= " AND subjid = :id"; - $paramMap[':id'] = $id;*/ + + $sql .= " AND subjid = :id"; + $paramMap[':id'] = $id; } } - $result = $con->query($sql)->fetchColumn(0); - //$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, 'column'); + + $result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN); + if ($result == 0) { return ""; - } else { + } + else { $sql = "SELECT valstr FROM cc_pref" - ." WHERE keystr = '$key'"; - /*." WHERE keystr = :key"; + ." WHERE keystr = :key"; + $paramMap = array(); - $paramMap[':key'] = $key;*/ + $paramMap[':key'] = $key; //For user specific preference, check if id matches as well if ($isUserValue && $auth->hasIdentity()) { - $sql .= " AND subjid = '$id'"; - /*$sql .= " AND subjid = :id"; - $paramMap[':id'] = $id;*/ + $sql .= " AND subjid = :id"; + $paramMap[':id'] = $id; } - $result = $con->query($sql)->fetchColumn(0); - //$result = Application_Common_Database::prepareAndExecute($sql, $paramMap, 'column'); + + $result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN); return ($result !== false) ? $result : ""; } @@ -609,9 +610,10 @@ class Application_Model_Preference public static function GetCountryList() { - $con = Propel::getConnection(); $sql = "SELECT * FROM cc_country"; - $res = $con->query($sql)->fetchAll(); + + $res = Application_Common_Database::prepareAndExecute($sql, array()); + $out = array(); $out[""] = _("Select Country"); foreach ($res as $r) { From 2ba743a436b24ca6dd78e981e87269db5830997a Mon Sep 17 00:00:00 2001 From: Naomi Date: Mon, 13 May 2013 12:23:05 -0400 Subject: [PATCH 2/8] CC-5132 : Playlist Editor: Add file before Smart Block will cause exception --- .../views/scripts/playlist/set-fade.phtml | 2 +- .../views/scripts/playlist/update.phtml | 35 +++++++++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/airtime_mvc/application/views/scripts/playlist/set-fade.phtml b/airtime_mvc/application/views/scripts/playlist/set-fade.phtml index 510ed441e..1bd1a74f6 100644 --- a/airtime_mvc/application/views/scripts/playlist/set-fade.phtml +++ b/airtime_mvc/application/views/scripts/playlist/set-fade.phtml @@ -11,7 +11,7 @@
item2Type == 0) {?> + if (isset($this->item2Url)) {?>
isStatic(); @@ -87,21 +88,33 @@ if (($i < count($items) -1) && ($items[$i+1]['type'] == 0)) { if(($i < count($items) -1) && !($items[$i]['type'] == 2 && $items[$i+1]['type'])): ?> From 85afe53c899263619c069524ca81292d85a79886 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 13 May 2013 15:45:56 -0400 Subject: [PATCH 3/8] CC-5133: Make sure Liquidsoap 1.1.1 is used fixed --- python_apps/pypo/pypocli.py | 50 +++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/python_apps/pypo/pypocli.py b/python_apps/pypo/pypocli.py index 49582bfec..42d3205b4 100644 --- a/python_apps/pypo/pypocli.py +++ b/python_apps/pypo/pypocli.py @@ -13,6 +13,7 @@ import signal import logging import locale import os +import re from Queue import Queue from threading import Lock @@ -33,6 +34,7 @@ from configobj import ConfigObj # custom imports from api_clients import api_client from std_err_override import LogWriter +import pure # Set up command-line options parser = OptionParser() @@ -71,6 +73,8 @@ parser.add_option("-c", # parse options (options, args) = parser.parse_args() +LIQUIDSOAP_MIN_VERSION = "1.1.1" + #need to wait for Python 2.7 for this.. #logging.captureWarnings(True) @@ -152,7 +156,7 @@ def keyboardInterruptHandler(signum, frame): logger.info('\nKeyboard Interrupt\n') sys.exit(0) -def liquidsoap_running_test(telnet_lock, host, port, logger): +def liquidsoap_get_info(telnet_lock, host, port, logger): logger.debug("Checking to see if Liquidsoap is running") try: telnet_lock.acquire() @@ -161,14 +165,47 @@ def liquidsoap_running_test(telnet_lock, host, port, logger): tn.write(msg) tn.write("exit\n") response = tn.read_all() - logger.info("Found: %s", response) except Exception, e: logger.error(str(e)) - return False + return None finally: telnet_lock.release() - return "Liquidsoap" in response + return get_liquidsoap_version(response) + +def get_liquidsoap_version(version_string): + m = re.match(r"Liquidsoap (\d+.\d+.\d+)", "Liquidsoap 1.1.1") + + if m: + return m.group(1) + else: + return None + + + if m: + current_version = m.group(1) + return pure.version_cmp(current_version, LIQUIDSOAP_MIN_VERSION) >= 0 + return False + +def liquidsoap_startup_test(): + + liquidsoap_version_string = \ + liquidsoap_get_info(telnet_lock, ls_host, ls_port, logger) + while not liquidsoap_version_string: + logger.warning("Liquidsoap doesn't appear to be running!, " + \ + "Sleeping and trying again") + time.sleep(1) + liquidsoap_version_string = \ + liquidsoap_get_info(telnet_lock, ls_host, ls_port, logger) + + while pure.version_cmp(liquidsoap_version_string, LIQUIDSOAP_MIN_VERSION) < 0: + logger.warning("Liquidsoap is running but in incorrect version! " + \ + "Make sure you have at least Liquidsoap %s installed" % LIQUIDSOAP_MIN_VERSION) + time.sleep(1) + liquidsoap_version_string = \ + liquidsoap_get_info(telnet_lock, ls_host, ls_port, logger) + + logger.info("Liquidsoap version string found %s" % liquidsoap_version_string) if __name__ == '__main__': @@ -204,9 +241,8 @@ if __name__ == '__main__': ls_host = config['ls_host'] ls_port = config['ls_port'] - while not liquidsoap_running_test(telnet_lock, ls_host, ls_port, logger): - logger.warning("Liquidsoap not started yet. Sleeping one second and trying again") - time.sleep(1) + + liquidsoap_startup_test() if options.test: g.test_api() From 872f68505b5854f7d891f10c717117c1e6f354fb Mon Sep 17 00:00:00 2001 From: Naomi Date: Mon, 13 May 2013 16:01:06 -0400 Subject: [PATCH 4/8] CC-5108 Waveform Editor UI --- .../controllers/LibraryController.php | 1 + .../application/layouts/scripts/layout.phtml | 40 +++++----- airtime_mvc/public/css/bootstrap.css | 12 +-- airtime_mvc/public/css/playlist_builder.css | 25 ------- airtime_mvc/public/css/waveform.css | 74 +++++++++++++++++++ airtime_mvc/public/js/airtime/library/spl.js | 20 ++--- .../public/js/waveformplaylist/controls.js | 2 +- 7 files changed, 113 insertions(+), 61 deletions(-) create mode 100644 airtime_mvc/public/css/waveform.css diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index d258bd766..afa4baa7a 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -49,6 +49,7 @@ class LibraryController extends Zend_Controller_Action $this->view->headLink()->appendStylesheet($baseUrl.'css/jquery.contextMenu.css?'.$CC_CONFIG['airtime_version']); $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColVis.css?'.$CC_CONFIG['airtime_version']); $this->view->headLink()->appendStylesheet($baseUrl.'css/datatables/css/ColReorder.css?'.$CC_CONFIG['airtime_version']); + $this->view->headLink()->appendStylesheet($baseUrl.'css/waveform.css?'.$CC_CONFIG['airtime_version']); $this->view->headScript()->appendFile($baseUrl.'js/airtime/library/spl.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); $this->view->headScript()->appendFile($baseUrl.'js/airtime/playlist/smart_blockbuilder.js?'.$CC_CONFIG['airtime_version'], 'text/javascript'); diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index e67e429d6..1a050d3f2 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -38,22 +38,22 @@
- Play - Stop + Play + Stop +
-
- - - - - -
-
+
- - + + + + +
+
- + + +
@@ -62,14 +62,14 @@ diff --git a/airtime_mvc/public/css/bootstrap.css b/airtime_mvc/public/css/bootstrap.css index 97fa6b159..efe9abff7 100644 --- a/airtime_mvc/public/css/bootstrap.css +++ b/airtime_mvc/public/css/bootstrap.css @@ -190,13 +190,15 @@ a.badge:hover { } .btn.active, .btn:active { - background-color: #494949; - background-color: #494949 \9; + background-color: #434343; + background-color: #434343 \9; background-image: none; outline: 0; - -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); - -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); - box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05); + -webkit-box-shadow: inset 0 2px 3px rgba(0,0,0,.25), 0 1px 0 rgba(200,200,200,1); + -moz-box-shadow: inset 0 2px 3px rgba(0,0,0,.25), 0 1px 0 rgba(200,200,200,1); + box-shadow: inset 0 2px 3px rgba(0,0,0,.25), 0 1px 0 rgba(220,220,220,1); + border: 1px solid #131313; + color: #a5a5a5 !important ; } .btn.disabled, .btn[disabled], diff --git a/airtime_mvc/public/css/playlist_builder.css b/airtime_mvc/public/css/playlist_builder.css index 7d828bd31..20da9dafa 100644 --- a/airtime_mvc/public/css/playlist_builder.css +++ b/airtime_mvc/public/css/playlist_builder.css @@ -584,29 +584,4 @@ li.spl_empty { } .expand-block-separate { border-top: 1px solid #5B5B5B; -} - -.channel-wrapper { - position: relative; -} - -.channel { - position: absolute; - margin: 0; - padding: 0; -} - -.state-select { - cursor: text; -} - -.playlist-tracks { - overflow-x: auto; - overflow-y: hidden; -} - -.playlist-fade { - position: absolute; - background-color: rgba(0,0,0,0.1); - z-index: 1000; } \ No newline at end of file diff --git a/airtime_mvc/public/css/waveform.css b/airtime_mvc/public/css/waveform.css new file mode 100644 index 000000000..fd4c9bd57 --- /dev/null +++ b/airtime_mvc/public/css/waveform.css @@ -0,0 +1,74 @@ +.ui-dialog .ui-dialog-content { + padding: 0px; +} +.ui-dialog .ui-dialog-buttonpane { + padding: 0.3em 0.2em 0 0.4em; + margin: 0 -0.4em 0; +} +.btn-small [class^="icon-"] { + margin: 1px 5px 0 -3px; +} +.btn { + margin-right: 3px; +} +.btn-small { + /*line-height: 20px;*/ +} +.playlist-tracks { + margin: 8px 0; +} +.playlist-controls { + margin: 0 0 16px 0; +} + +.channel-wrapper { + position: relative; +} + +.channel { + position: absolute; + margin: 0; + padding: 0; + background: #3e3e3e; +} + +.state-select { + cursor: text; +} + +.playlist-tracks { + overflow-x: auto; + overflow-y: hidden; +} + +.playlist-fade { + position: absolute; + background-color: rgba(0,0,0,0.1); + z-index: 1000; +} +.set-cue { + margin: 12px 0 16px 0; +} +.set-fade { + margin: 0 0 0 30px; +} +.set-cue input[type="text"] { + vertical-align: middle; + padding: 5px 3px 4px 3px; +} +.set-cue input[type="button"] { + min-width: 100px; + margin-top: 0px; + margin-left: 4px; +} +label { + color:#333; + padding: 0 5px 0 6px; + display: inline-block; + min-width: 50px; + text-align: right; +} +label.audio { + font-weight:bold; + vertical-align: middle; +} \ No newline at end of file diff --git a/airtime_mvc/public/js/airtime/library/spl.js b/airtime_mvc/public/js/airtime/library/spl.js index 18d10ba0e..403c0d230 100644 --- a/airtime_mvc/public/js/airtime/library/spl.js +++ b/airtime_mvc/public/js/airtime/library/spl.js @@ -1223,8 +1223,8 @@ var AIRTIME = (function(AIRTIME){ width: dim.width - 100, height: dim.height - 100, buttons: [ - {text: "Cancel", click: removeDialog}, - {text: "Save", click: function() { + {text: "Cancel", class: "btn btn-small", click: removeDialog}, + {text: "Save", class: "btn btn-small btn-inverse", click: function() { var json = playlistEditor.getJson(), offset, fadeIn, fadeOut, @@ -1305,19 +1305,19 @@ var AIRTIME = (function(AIRTIME){ $html.remove(); } - $html.find('.editor-cue-in').val(cueIn); - $html.find('.editor-cue-out').val(cueOut); + $html.find('.editor-cue-in').html(cueIn); + $html.find('.editor-cue-out').html(cueOut); $html.on("click", ".set-cue-in", function(e) { var cueIn = $html.find('.audio_start').val(); - $html.find('.editor-cue-in').val(cueIn); + $html.find('.editor-cue-in').html(cueIn); }); $html.on("click", ".set-cue-out", function(e) { var cueOut = $html.find('.audio_end').val(); - $html.find('.editor-cue-out').val(cueOut); + $html.find('.editor-cue-out').html(cueOut); }); $html.dialog({ @@ -1328,10 +1328,10 @@ var AIRTIME = (function(AIRTIME){ width: dim.width - 100, height: dim.height - 100, buttons: [ - {text: "Cancel", click: removeDialog}, - {text: "Save", click: function() { - var cueIn = $html.find('.editor-cue-in').val(), - cueOut = $html.find('.editor-cue-out').val(); + {text: "Cancel", class: "btn btn-small", click: removeDialog}, + {text: "Save", class: "btn btn-small btn-inverse", click: function() { + var cueIn = $html.find('.editor-cue-in').html(), + cueOut = $html.find('.editor-cue-out').html(); playlistEditor.stop(); diff --git a/airtime_mvc/public/js/waveformplaylist/controls.js b/airtime_mvc/public/js/waveformplaylist/controls.js index d83af02f0..1a41aa23e 100644 --- a/airtime_mvc/public/js/waveformplaylist/controls.js +++ b/airtime_mvc/public/js/waveformplaylist/controls.js @@ -556,7 +556,7 @@ AudioControls.prototype.onCursorSelection = function(args) { */ AudioControls.prototype.onAudioUpdate = function(args) { if (this.ctrls["audio_pos"]) { - this.ctrls["audio_pos"].value = this.cueFormatters(this.timeFormat)(args.seconds); + this.ctrls["audio_pos"].innerHTML = this.cueFormatters(this.timeFormat)(args.seconds); } }; From be465be9b2224eadb93203f10ad4972d1d6e5dc4 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 13 May 2013 16:10:21 -0400 Subject: [PATCH 5/8] CC-5133: Make sure Liquidsoap 1.1.1 is used add missing file --- python_apps/pypo/pure.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 python_apps/pypo/pure.py diff --git a/python_apps/pypo/pure.py b/python_apps/pypo/pure.py new file mode 100644 index 000000000..8b004ae6d --- /dev/null +++ b/python_apps/pypo/pure.py @@ -0,0 +1,7 @@ +import re + + +def version_cmp(version1, version2): + def normalize(v): + return [int(x) for x in re.sub(r'(\.0+)*$','', v).split(".")] + return cmp(normalize(version1), normalize(version2)) From f5a0d0a9a4cae31c3a08e437e17cb69e46d023c7 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 13 May 2013 17:52:22 -0400 Subject: [PATCH 6/8] CC-5123: Pypo: Redundant Pypopush happens after restart pypo service -was clearing the queue after fetching the schedule :S --- python_apps/pypo/pypofetch.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index 38a72f363..d5959e502 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -528,10 +528,6 @@ class PypoFetch(Thread): def main(self): - # Bootstrap: since we are just starting up, we need to grab the - # most recent schedule. After that we can just wait for updates. - success = self.persistent_manual_schedule_fetch(max_attempts=5) - #Make sure all Liquidsoap queues are empty. This is important in the #case where we've just restarted the pypo scheduler, but Liquidsoap still #is playing tracks. In this case let's just restart everything from scratch @@ -539,6 +535,10 @@ class PypoFetch(Thread): #Liquidsoap is playing much more easily. self.pypo_liquidsoap.clear_all_queues() + # Bootstrap: since we are just starting up, we need to grab the + # most recent schedule. After that we can just wait for updates. + success = self.persistent_manual_schedule_fetch(max_attempts=5) + if success: self.logger.info("Bootstrap schedule received: %s", self.schedule_data) self.set_bootstrap_variables() From 298e5a9b77d14575b98a2ff486395e7517dcf763 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 13 May 2013 17:52:43 -0400 Subject: [PATCH 7/8] better idenfication of which mksafe is being applied --- .../pypo/liquidsoap_scripts/ls_script.liq | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/python_apps/pypo/liquidsoap_scripts/ls_script.liq b/python_apps/pypo/liquidsoap_scripts/ls_script.liq index 58a91909b..97dc544c5 100644 --- a/python_apps/pypo/liquidsoap_scripts/ls_script.liq +++ b/python_apps/pypo/liquidsoap_scripts/ls_script.liq @@ -231,6 +231,7 @@ s = switch(id="schedule_noise_switch", s = if dj_live_stream_port != 0 and dj_live_stream_mp != "" then dj_live = mksafe( + id="dj_live_mksafe", audio_to_stereo( input.harbor(id="live_dj_harbor", dj_live_stream_mp, @@ -253,14 +254,15 @@ end s = if master_live_stream_port != 0 and master_live_stream_mp != "" then master_dj = mksafe( - audio_to_stereo( - input.harbor(id="master_harbor", - master_live_stream_mp, - port=master_live_stream_port, - auth=check_master_dj_client, - max=40., - on_connect=master_dj_connect, - on_disconnect=master_dj_disconnect))) + id="master_dj_mksafe", + audio_to_stereo( + input.harbor(id="master_harbor", + master_live_stream_mp, + port=master_live_stream_port, + auth=check_master_dj_client, + max=40., + on_connect=master_dj_connect, + on_disconnect=master_dj_disconnect))) ignore(output.dummy(master_dj, fallible=true)) From d9b6a15fb6118deac2acec0b7cd6e835ed9cbd20 Mon Sep 17 00:00:00 2001 From: Naomi Date: Mon, 13 May 2013 18:21:24 -0400 Subject: [PATCH 8/8] CC-5139 : WaveForm: Click save will cause problem when setting crossfading between track and Smart block --- .../application/controllers/PlaylistController.php | 4 ++-- airtime_mvc/application/models/Block.php | 8 ++++++-- airtime_mvc/application/models/Playlist.php | 8 ++++++-- airtime_mvc/public/js/airtime/library/spl.js | 5 ++++- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/airtime_mvc/application/controllers/PlaylistController.php b/airtime_mvc/application/controllers/PlaylistController.php index 1134499ce..2b48b40b7 100644 --- a/airtime_mvc/application/controllers/PlaylistController.php +++ b/airtime_mvc/application/controllers/PlaylistController.php @@ -421,8 +421,8 @@ class PlaylistController extends Zend_Controller_Action public function setCrossfadeAction() { - $id1 = $this->_getParam('id1'); - $id2 = $this->_getParam('id2'); + $id1 = $this->_getParam('id1', null); + $id2 = $this->_getParam('id2', null); $type = $this->_getParam('type'); $fadeIn = $this->_getParam('fadeIn', 0); $fadeOut = $this->_getParam('fadeOut', 0); diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index bab3d3ed8..b1ac483a5 100644 --- a/airtime_mvc/application/models/Block.php +++ b/airtime_mvc/application/models/Block.php @@ -688,8 +688,12 @@ SQL; $this->con->beginTransaction(); try { - $this->changeFadeInfo($id1, null, $fadeOut); - $this->changeFadeInfo($id2, $fadeIn, null, $offset); + if (isset($id1)) { + $this->changeFadeInfo($id1, null, $fadeOut); + } + if (isset($id2)) { + $this->changeFadeInfo($id2, $fadeIn, null, $offset); + } $this->con->commit(); diff --git a/airtime_mvc/application/models/Playlist.php b/airtime_mvc/application/models/Playlist.php index 16e89c7d5..aa74c78c4 100644 --- a/airtime_mvc/application/models/Playlist.php +++ b/airtime_mvc/application/models/Playlist.php @@ -670,8 +670,12 @@ SQL; $this->con->beginTransaction(); try { - $this->changeFadeInfo($id1, null, $fadeOut); - $this->changeFadeInfo($id2, $fadeIn, null, $offset); + if (isset($id1)) { + $this->changeFadeInfo($id1, null, $fadeOut); + } + if (isset($id2)) { + $this->changeFadeInfo($id2, $fadeIn, null, $offset); + } $this->con->commit(); diff --git a/airtime_mvc/public/js/airtime/library/spl.js b/airtime_mvc/public/js/airtime/library/spl.js index 403c0d230..b15f56540 100644 --- a/airtime_mvc/public/js/airtime/library/spl.js +++ b/airtime_mvc/public/js/airtime/library/spl.js @@ -1254,7 +1254,10 @@ var AIRTIME = (function(AIRTIME){ fadeIn = fade["end"] - fade["start"]; } - changeCrossfade($html, id1, id2, fadeIn.toFixed(1), fadeOut.toFixed(1), offset); + fadeIn = (fadeIn === undefined) ? undefined : fadeIn.toFixed(1); + fadeOut = (fadeOut === undefined) ? undefined : fadeOut.toFixed(1); + + changeCrossfade($html, id1, id2, fadeIn, fadeOut, offset); }} ], open: function (event, ui) {