commit 22e59d6290e7103ce952c1650f8d0219b42480bf Author: Cyd Date: Wed Jul 1 10:59:51 2026 -0500 Initial commit of PQS Co-Authored-By: Claude Opus 4.8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..993527f --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# OS / editor cruft +.DS_Store +Thumbs.db +*.swp +*~ +.vscode/ +.idea/ + +# Logs +*.log diff --git a/callsign.php b/callsign.php new file mode 100644 index 0000000..2943a8e --- /dev/null +++ b/callsign.php @@ -0,0 +1,377 @@ + + +PQS - CallSign v2 + + + + + +"; + echo "

"; + echo ""; + echo "

Thank you $_GET[callsign]. You have been entered into the queue piloting a $mechname.

You are currently set for mission:

#$missionid

Please continue to check the queue displays for your position in the queue.

"; + echo ""; + exit; + } + + if($isLeader){ + + $sql = "SELECT MissionID, numplayers FROM pqs_mission WHERE Completed = 0 AND locked = 0 AND ($hm + numplayers) <= MissionSize ORDER BY MissionID ASC"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($getid); + $missionid = $rs[0]; + $numplayers = $rs[1]; + mysqli_close($link); + + if ($missionid == "") { + $missionsize = $_SESSION['mechpods']; + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "INSERT INTO pqs_mission (MissionDate, MissionSize, numplayers, MissionTime) VALUES ($tdate, $missionsize, $hm, $ttime)"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $sql = "SELECT MissionID, numplayers FROM pqs_mission WHERE Completed = 0 AND locked = 0 AND numplayers <= MissionSize ORDER BY MissionID DESC"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs1 = mysqli_fetch_array($getid); + $missionid = $rs1[0]; + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $i = 2; + while ($i <= $hm){ + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign-$i','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $i ++; + } + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + mysqli_close($link); + } else { + $newplayers = $numplayers + $hm; + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "UPDATE pqs_mission SET numplayers = $newplayers WHERE MissionID = $missionid"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $i = 2; + while ($i <= $hm){ + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign-$i','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $i ++; + } + + mysqli_close($link); + } + + $minToDeparture = $timePerGame*($missionid-$lastCommitedMissionID); + $d=strtotime("+$minToDeparture Minutes",$lastCommitTime); + $etd = date("h:i", $d); + + echo ""; + echo "


"; + echo ""; + echo "

Thank you $_GET[callsign]. You have been entered into the queue piloting a $mechname.

You are currently set for mission:
#$missionid
Your Estimated Departure time is: $etd

Please continue to check the queue displays for your position in the queue.

"; + echo ""; + + exit; + } + + $sql = "SELECT MissionID, numplayers FROM pqs_mission WHERE Completed = 0 AND locked = 0 AND numplayers < MissionSize ORDER BY MissionID ASC"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($getid); + $missionid = $rs[0]; + $numplayers = $rs[1]; + + mysqli_close($link); + + if ($missionid == "") { + $missionsize = $_SESSION['mechpods']; + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "INSERT INTO pqs_mission (MissionDate, MissionSize, numplayers, MissionTime) VALUES ($tdate, $missionsize, 1, $ttime)"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $sql = "SELECT MissionID, numplayers FROM pqs_mission WHERE Completed = 0 AND locked = 0 AND numplayers < MissionSize ORDER BY MissionID"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs1 = mysqli_fetch_array($getid); + $missionid = $rs1[0]; + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + mysqli_close($link); + } else { + $newplayers = $numplayers + 1; + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "UPDATE pqs_mission SET numplayers = $newplayers WHERE MissionID = $missionid"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + mysqli_close($link); + } + + $minToDeparture = $timePerGame*($missionid-$lastCommitedMissionID); + $d=strtotime("+$minToDeparture Minutes",$lastCommitTime); + $etd = date("h:i", $d); + + echo ""; + echo "


"; +// echo ""; + echo ""; + echo "

Thank you $_GET[callsign]. You have been entered into the queue piloting a $mechname.

You are currently set for mission:

#$missionid
Your Estimated Departure time is: $etd
Please continue to check the queue displays for your position in the queue.


Thank you $_GET[callsign]. You have been entered into the queue piloting a $mechname.

You are currently set for mission:

#$missionid
Your Estimated Departure time is: $etd
Please continue to check the queue displays for your position in the queue.


"; +// echo ""; + exit; +} +?> +
+
+ + +


+ + + + + + + + + + + "; + } else if ($isMember){ + echo " + + + + + + + + +
                        

            

+ +
        group +
        howmany
        who
        "; + } + ?> + +
         +
         +
 
+
+
+ + + + diff --git a/combinedqueue.php b/combinedqueue.php new file mode 100644 index 0000000..9a831f6 --- /dev/null +++ b/combinedqueue.php @@ -0,0 +1,80 @@ + + +PQS - Player Queue + + + + + +"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo "
 
 
 
 
 
"; +echo ""; +echo ""; +echo ""; +echo ""; +echo "
 
"; +?> + +
 
"; +?> + diff --git a/combinedqueue2.php b/combinedqueue2.php new file mode 100644 index 0000000..3c9268b --- /dev/null +++ b/combinedqueue2.php @@ -0,0 +1,83 @@ + + +PQS - Player Queue + + + + + +"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; + +echo "
 
 
 
 
 
"; +echo ""; +echo ""; +echo ""; +echo ""; +echo "
 
"; +?> + +
 
"; +?> + diff --git a/console.php b/console.php new file mode 100644 index 0000000..a45a5dc --- /dev/null +++ b/console.php @@ -0,0 +1,348 @@ + + +PQS - Game Console + + + + + +"; +echo "Clear Current Queue   |   "; +echo "Open History Window"; +echo ""; +echo ""; +echo ""; +if ($locked == 1) { + echo ""; +} else { ?> + "; +} +echo "
"; +echo "
 
"; +echo "
Total Pods: "; +echo "
# Mercs in Pods:


This mission is LOCKED!

"; +echo ""; +echo "
"; +echo "
"; +echo "Configuration

"; +echo "
"; + +$link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysql_error()); +mysqli_select_db($link, 'pqs') or die('Could not select database'); +$query = 'SELECT * FROM pqs_gameconfig'; +$result = mysqli_query($link, $query) or die('Query failed: ' . mysql_error()); +while ($line = mysqli_fetch_array($result)) { + $numpods = $line[1]; + $timepergame = $line[2]; + $timetoreset = $line[3]; + $visibility = $line[7]; + $weather = $line[8]; + $timeofday = $line[9]; + $timelimit = $line[10]; + $radar = $line[11]; + $heat = $line[12]; + $friendlyfire = $line[13]; + $splashdamage = $line[14]; + $limitedammo = $line[15]; + $noreturn = $line[16]; + $printdebriefing = $line[17]; + $missionreview = $line[18]; + $weaponjam = $line[19]; + $advancemode = $line[20]; + $armormode = $line[21]; + $cameraship = $line[22]; + $groupAvalible = $line[23]; + +} + +$query = 'SELECT * FROM pqs_pods'; +$result = mysqli_query($link, $query) or die('Query failed: ' . mysql_error()); +while ($line = mysqli_fetch_array($result)) { + $pod01 = $line[0]; + $pod02 = $line[1]; + $pod03 = $line[2]; + $pod04 = $line[3]; + $pod05 = $line[4]; + $pod06 = $line[5]; + $pod07 = $line[6]; + $pod08 = $line[7]; + $pod09 = $line[8]; + $pod10 = $line[9]; + $pod11 = $line[10]; + $pod12 = $line[11]; + $pod13 = $line[12]; + $pod14 = $line[13]; + $pod15 = $line[14]; + $pod16 = $line[15]; +} + +?> + + Time Limit : +
+ Reset Time : +
+Pod01 : ";} else {echo "Pod01 : ";} if ("$pod01" == 1) { echo "
"; } else { echo "
"; } +if ("$pod02" == 0) {echo "Pod02 : ";} else {echo "Pod02 : ";} if ("$pod02" == 1) { echo "
"; } else { echo "
"; } +if ("$pod03" == 0) {echo "Pod03 : ";} else {echo "Pod03 : ";} if ("$pod03" == 1) { echo "
"; } else { echo "
"; } +if ("$pod04" == 0) {echo "Pod04 : ";} else {echo "Pod04 : ";} if ("$pod04" == 1) { echo "
"; } else { echo "
"; } +if ("$pod05" == 0) {echo "Pod05 : ";} else {echo "Pod05 : ";} if ("$pod05" == 1) { echo "
"; } else { echo "
"; } +if ("$pod06" == 0) {echo "Pod06 : ";} else {echo "Pod06 : ";} if ("$pod06" == 1) { echo "
"; } else { echo "
"; } +if ("$pod07" == 0) {echo "Pod07 : ";} else {echo "Pod07 : ";} if ("$pod07" == 1) { echo "
"; } else { echo "
"; } +if ("$pod08" == 0) {echo "Pod08 : ";} else {echo "Pod08 : ";} if ("$pod08" == 1) { echo "
"; } else { echo "
"; } +if ("$pod09" == 0) {echo "Pod09 : ";} else {echo "Pod09 : ";} if ("$pod09" == 1) { echo "
"; } else { echo "
"; } +if ("$pod10" == 0) {echo "Pod10 : ";} else {echo "Pod10 : ";} if ("$pod10" == 1) { echo "
"; } else { echo "
"; } +if ("$pod11" == 0) {echo "Pod11 : ";} else {echo "Pod11 : ";} if ("$pod11" == 1) { echo "
"; } else { echo "
"; } +if ("$pod12" == 0) {echo "Pod12 : ";} else {echo "Pod12 : ";} if ("$pod12" == 1) { echo "
"; } else { echo "
"; } +if ("$pod13" == 0) {echo "Pod13 : ";} else {echo "Pod13 : ";} if ("$pod13" == 1) { echo "
"; } else { echo "
"; } +if ("$pod14" == 0) {echo "Pod14 : ";} else {echo "Pod14 : ";} if ("$pod14" == 1) { echo "
"; } else { echo "
"; } +if ("$pod15" == 0) {echo "Pod15 : ";} else {echo "Pod15 : ";} if ("$pod15" == 1) { echo "
"; } else { echo "
"; } +if ("$pod16" == 0) {echo "Pod16 : ";} else {echo "Pod16 : ";} if ("$pod16" == 1) { echo "
"; } else { echo "
"; } +?> + +             Visability      : +
+             Weather        : +
+             Time of Day : +
+             Radar            : +
+ +
"; } else { echo "
"; } + +echo "Friendly Fire : "; if ("$friendlyfire" == 1) { echo ""; } else { echo ""; } echo"          
"; + +echo "Splash Damage : "; if ("$splashdamage" == 1) { echo ""; } else { echo ""; } echo"              
"; + +echo "Limited Ammo : "; if ("$limitedammo" == 1) { echo ""; } else { echo ""; } echo"              
"; + +echo "No Return : "; if ("$noreturn" == 1) { echo ""; } else { echo ""; }echo"      
"; + +echo "Print Debriefing : "; if ("$printdebriefing" == 1) { echo ""; } else { echo ""; }echo"               
"; + +echo "Mission Review : "; if ("$missionreview" == 1) { echo ""; } else { echo ""; }echo"               
"; + +echo "Weapon Jam : "; if ("$weaponjam" == 1) { echo ""; } else { echo ""; }echo"          
"; + +echo "Advance Mode : "; if ("$advancemode" == 1) { echo ""; } else { echo ""; }echo"              
"; + +echo "Armor Mode : "; if ("$armormode" == 1) { echo ""; } else { echo ""; }echo"          
"; + +?> + +              Cameraship  : +
+ +"; } else { echo ""; }echo"          
"; + + +echo "
"; +echo "
"; +echo "
"; +echo "
"; +echo ""; +?> + diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..fc0f61f --- /dev/null +++ b/css/main.css @@ -0,0 +1,470 @@ +body { + color: #ffffff; + background-color: #000000; +} +input.main, select.main { + color: #FEAE01; + font-size: 36px; + border: 1px solid #FEAE01; + width: 350px; + background-color: #000000; + height: 50px; + text-align:center; +} + +select.main { + color: #FEAE01; + font-size: 36px; + border: 1px solid #FEAE01; + width: 350px; + background-color: #000000; + height: 50px; + text-align:center; +} + +input.callsign { + color: #FEAE01; + font-size: 36px; + border: 1px solid #FEAE01; + width: 350px; + background-color: #000000; + height: 50px; + text-align:center; +} + +input.editqueue, select { + color: #FFFFFF; + font-size: 22px; + border: 1px solid #FEAE01; + background-color: #000000; + height: 30px; + text-align:center; +} + +div.stats { + height: 205px; + border: 1px solid #FEAE01; + width: 328px; + background-color: #000000; + padding:10px; +} +* html div.stats { + width: 370px; + height: 225px; +} +div.queued { + width: 400px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + font-size: x-large; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +div.queuediv { + width: 650px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +div.queuedivspec { + width: 800px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +div.queuedivreg { + width: 800px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +div.consolehist { + width: 400px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +div.consolediv { + width: 400px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +div.queuediv2 { + height: 600px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +div.queuediv3 { + height: 550px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} +div.queuediv16 { + height: 600px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} +div.smallqueuediv3 { + height: 325px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} +div.queuediv4 { + height: 300px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} +div.smallqueuediv4 { + height: 350px; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} +div.dialog { + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} + +div.queuetime { + text-align: center; +} + +div.infopanel { + height: 370px; + background-color: #000000; + padding:10px; + text-align: center; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} +div.smallinfopanel { + height: 325px; + background-color: #000000; + padding:10px; + text-align: center; + border: 1px solid #FEAE01; + color: #FEAE01; + background-color: #000000; + padding:10px; + text-align: center; + + + /* css3 drop shadow */ + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 10px rgba(254, 174, 1, 2); + + /* css3 border radius */ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; +} +div.infopanel div { + height: 365px; + width: 98%; + background-color: #000000; + padding:10px; + color: #fff; + text-align: center; + font-size: 32px; + +} + +span.fsashadowtext { + text-align: center; + text-shadow: 2px 2px 2px #FEAE01; + color: #fff; +} + +td.queuedisplayhead { + text-align: center; + text-shadow: 2px 2px 2px #FEAE01; + font-weight: bold; + font-size: xx-large; + color: #fff; +} + +td.playermissions { + text-align: center; + text-shadow: 2px 2px 2px #FEAE01; + font-weight: bold; + font-size: large; + color: #fff; +} + +td.queuedisplay { + text-align: center; + font-size: x-large; + color: #fff; +} +td.queuedisplaysmall { + text-align: center; + font-size: 20pt; + color: #fff; +} + +td.consoledisplayhead { + text-align: center; + text-shadow: 2px 2px 2px #FEAE01; + font-weight: bold; + font-size: x-large; + color: #fff; +} + +td.consoledisplay { + text-align: center; + font-size: large; + color: #fff; +} + +a.queuedisplayhead { + text-align: center; + text-decoration: none; + text-shadow: 2px 2px 2px #FEAE01; + font-weight: bold; + font-size: xx-large; + color: #fff +} + +a.playermissions { + text-align: center; + text-decoration: none; + text-shadow: 2px 2px 2px #FEAE01; + font-weight: bold; + font-size: large; + color: #fff +} + +a.blink { + text-align: center; + text-decoration: blink; + text-shadow: 2px 2px 2px #FEAE01; + font-weight: bold; + color: #fff +} + +a.button { + /* styles for button */ + margin:10px auto 0 auto; + text-align:center; + display: block; + width:50px; + padding: 5px 10px 6px; + color: #fff; + text-decoration: none; + font-weight: bold; + line-height: 1; + + /* button color */ + background-color: #e33100; + + + /* css3 implementation :) */ + /* rounded corner */ + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + + /* drop shadow */ + -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.5); + -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.5); + + /* text shaow */ + text-shadow: 0 -1px 1px rgba(0,0,0,0.25); + border-bottom: 1px solid rgba(0,0,0,0.25); + position: relative; + cursor: pointer; + +} + +a.button:hover { + background-color: #c33100; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/css/tooltip.css b/css/tooltip.css new file mode 100644 index 0000000..488754f --- /dev/null +++ b/css/tooltip.css @@ -0,0 +1,117 @@ +.ui-tooltip, .qtip{ + position: absolute; + left: -28000px; + top: -28000px; + display: none; + + max-width: 400px; + min-width: 50px; + + font-size: 22px; + line-height: 24px; + + border-width: 1px; + border-style: solid; + +} + .ui-tooltip-content{ + position: relative; + padding: 5px 9px; + overflow: hidden; + + text-align: left; + word-wrap: break-word; + overflow: hidden; + } + +/*! Default tooltip style */ +.ui-tooltip-default{ + border: 1px solid #FEAE01; + color: #FFFFFF; + text-shadow: 2px 2px 2px #FEAE01; + background-color: #000000; + text-align: center; + +} + + +/* Modal plugin */ +#qtip-overlay{ + position: fixed; + left: -10000em; + top: -10000em; +} + + /* Applied to modals with show.modal.blur set to true */ + #qtip-overlay.blurs{ cursor: pointer; } + + /* Change opacity of overlay here */ + #qtip-overlay div{ + position: absolute; + left: 0; top: 0; + width: 100%; height: 100%; + + background-color: black; + + opacity: 0.7; + filter:alpha(opacity=70); + -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; + } + +/* Tips plugin */ +.ui-tooltip .ui-tooltip-tip{ + margin: 0 auto; + overflow: hidden; + z-index: 10; +} + + .ui-tooltip .ui-tooltip-tip, + .ui-tooltip .ui-tooltip-tip *{ + position: absolute; + + line-height: 0.1px !important; + font-size: 0.1px !important; + color: #123456; + + background: transparent; + border: 0px dashed transparent; + } + + .ui-tooltip .ui-tooltip-tip canvas{ top: 0; left: 0; } + +.ui-tooltip-pqs{ + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + border-radius: 10px; + + -webkit-box-shadow: 0px 0px 0px rgba(254, 174, 1, 2); + -moz-box-shadow: 0px 0px 5px rgba(254, 174, 1, 2); + box-shadow: 0px 0px 5px rgba(254, 174, 1, 2); + + color: white; + border: 1px solid #FEAE01; + + background: #202020; + background-image: -moz-linear-gradient(top,#202020 0,black 100%); + background-image: -ms-linear-gradient(top,#202020 0,black 100%); + background-image: -o-linear-gradient(top,#202020 0,black 100%); + background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#202020),color-stop(100%,black)); + background-image: -webkit-linear-gradient(top,#202020 0,black 100%); + background-image: linear-gradient(to bottom,#202020 0,black 100%); +} + + .ui-tooltip-youtube .ui-tooltip-titlebar{ + background-color: #202020; + background-color: rgba(0,0,0,0); + } + + .ui-tooltip-youtube .ui-tooltip-content{ + padding: .75em; + font: 22px arial,sans-serif; + + filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#202020,EndColorStr=#000000); + -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#202020,EndColorStr=#000000);"; + } + + + diff --git a/docs/7z1602.exe b/docs/7z1602.exe new file mode 100644 index 0000000..498de2a Binary files /dev/null and b/docs/7z1602.exe differ diff --git a/docs/BTFS_Barker.mp4 b/docs/BTFS_Barker.mp4 new file mode 100644 index 0000000..2db9fd3 Binary files /dev/null and b/docs/BTFS_Barker.mp4 differ diff --git a/docs/BTFS_VTS_01_1.mp4 b/docs/BTFS_VTS_01_1.mp4 new file mode 100644 index 0000000..d7e80b8 Binary files /dev/null and b/docs/BTFS_VTS_01_1.mp4 differ diff --git a/docs/BT_30_Dooley.mp4 b/docs/BT_30_Dooley.mp4 new file mode 100644 index 0000000..2939d1c Binary files /dev/null and b/docs/BT_30_Dooley.mp4 differ diff --git a/docs/BT_40.mp4 b/docs/BT_40.mp4 new file mode 100644 index 0000000..23bffb8 Binary files /dev/null and b/docs/BT_40.mp4 differ diff --git a/docs/BT_40_Dooley.mp4 b/docs/BT_40_Dooley.mp4 new file mode 100644 index 0000000..d2f1fcf Binary files /dev/null and b/docs/BT_40_Dooley.mp4 differ diff --git a/docs/Clear Code.txt b/docs/Clear Code.txt new file mode 100644 index 0000000..e8194ab --- /dev/null +++ b/docs/Clear Code.txt @@ -0,0 +1,4 @@ + truncate table pqs_currentmission; + truncate table pqs_mission; + truncate table pqs_pastmissions; + truncate table pqs_queue; \ No newline at end of file diff --git a/docs/Copy of images/add.png b/docs/Copy of images/add.png new file mode 100644 index 0000000..cc85423 Binary files /dev/null and b/docs/Copy of images/add.png differ diff --git a/docs/Copy of images/bdicon.jpg b/docs/Copy of images/bdicon.jpg new file mode 100644 index 0000000..0f1f4cb Binary files /dev/null and b/docs/Copy of images/bdicon.jpg differ diff --git a/docs/Copy of images/bdiconsmall.JPG b/docs/Copy of images/bdiconsmall.JPG new file mode 100644 index 0000000..dc2b641 Binary files /dev/null and b/docs/Copy of images/bdiconsmall.JPG differ diff --git a/docs/Copy of images/bsb.jpg b/docs/Copy of images/bsb.jpg new file mode 100644 index 0000000..e9267cd Binary files /dev/null and b/docs/Copy of images/bsb.jpg differ diff --git a/docs/Copy of images/callsign.gif b/docs/Copy of images/callsign.gif new file mode 100644 index 0000000..4e63e05 Binary files /dev/null and b/docs/Copy of images/callsign.gif differ diff --git a/docs/Copy of images/delete.png b/docs/Copy of images/delete.png new file mode 100644 index 0000000..511a033 Binary files /dev/null and b/docs/Copy of images/delete.png differ diff --git a/docs/Copy of images/edit.png b/docs/Copy of images/edit.png new file mode 100644 index 0000000..8bc5c66 Binary files /dev/null and b/docs/Copy of images/edit.png differ diff --git a/docs/Copy of images/grad.png b/docs/Copy of images/grad.png new file mode 100644 index 0000000..75be618 Binary files /dev/null and b/docs/Copy of images/grad.png differ diff --git a/docs/Copy of images/group.gif b/docs/Copy of images/group.gif new file mode 100644 index 0000000..80d6b2a Binary files /dev/null and b/docs/Copy of images/group.gif differ diff --git a/docs/Copy of images/howmany.gif b/docs/Copy of images/howmany.gif new file mode 100644 index 0000000..b811739 Binary files /dev/null and b/docs/Copy of images/howmany.gif differ diff --git a/docs/Copy of images/mech picts/arcticwolf.jpg b/docs/Copy of images/mech picts/arcticwolf.jpg new file mode 100644 index 0000000..ed36881 Binary files /dev/null and b/docs/Copy of images/mech picts/arcticwolf.jpg differ diff --git a/docs/Copy of images/mech picts/atlas.jpg b/docs/Copy of images/mech picts/atlas.jpg new file mode 100644 index 0000000..6e27179 Binary files /dev/null and b/docs/Copy of images/mech picts/atlas.jpg differ diff --git a/docs/Copy of images/mech picts/awesome.jpg b/docs/Copy of images/mech picts/awesome.jpg new file mode 100644 index 0000000..18278e1 Binary files /dev/null and b/docs/Copy of images/mech picts/awesome.jpg differ diff --git a/docs/Copy of images/mech picts/bdicon.jpg b/docs/Copy of images/mech picts/bdicon.jpg new file mode 100644 index 0000000..46dafb2 Binary files /dev/null and b/docs/Copy of images/mech picts/bdicon.jpg differ diff --git a/docs/Copy of images/mech picts/blackknight.jpg b/docs/Copy of images/mech picts/blackknight.jpg new file mode 100644 index 0000000..9bfbbae Binary files /dev/null and b/docs/Copy of images/mech picts/blackknight.jpg differ diff --git a/docs/Copy of images/mech picts/blacklanner.jpg b/docs/Copy of images/mech picts/blacklanner.jpg new file mode 100644 index 0000000..4d0cd63 Binary files /dev/null and b/docs/Copy of images/mech picts/blacklanner.jpg differ diff --git a/docs/Copy of images/mech picts/brigand.jpg b/docs/Copy of images/mech picts/brigand.jpg new file mode 100644 index 0000000..ba98d59 Binary files /dev/null and b/docs/Copy of images/mech picts/brigand.jpg differ diff --git a/docs/Copy of images/mech picts/bushwacker.jpg b/docs/Copy of images/mech picts/bushwacker.jpg new file mode 100644 index 0000000..d6b9941 Binary files /dev/null and b/docs/Copy of images/mech picts/bushwacker.jpg differ diff --git a/docs/Copy of images/mech picts/catapult.jpg b/docs/Copy of images/mech picts/catapult.jpg new file mode 100644 index 0000000..3412595 Binary files /dev/null and b/docs/Copy of images/mech picts/catapult.jpg differ diff --git a/docs/Copy of images/mech picts/cauldronborn.jpg b/docs/Copy of images/mech picts/cauldronborn.jpg new file mode 100644 index 0000000..e9cc847 Binary files /dev/null and b/docs/Copy of images/mech picts/cauldronborn.jpg differ diff --git a/docs/Copy of images/mech picts/chimera.jpg b/docs/Copy of images/mech picts/chimera.jpg new file mode 100644 index 0000000..dd9f6a5 Binary files /dev/null and b/docs/Copy of images/mech picts/chimera.jpg differ diff --git a/docs/Copy of images/mech picts/commando.jpg b/docs/Copy of images/mech picts/commando.jpg new file mode 100644 index 0000000..fbbe7e0 Binary files /dev/null and b/docs/Copy of images/mech picts/commando.jpg differ diff --git a/docs/Copy of images/mech picts/cougar.jpg b/docs/Copy of images/mech picts/cougar.jpg new file mode 100644 index 0000000..40cf464 Binary files /dev/null and b/docs/Copy of images/mech picts/cougar.jpg differ diff --git a/docs/Copy of images/mech picts/cyclops.jpg b/docs/Copy of images/mech picts/cyclops.jpg new file mode 100644 index 0000000..ef0e51c Binary files /dev/null and b/docs/Copy of images/mech picts/cyclops.jpg differ diff --git a/docs/Copy of images/mech picts/daishi.jpg b/docs/Copy of images/mech picts/daishi.jpg new file mode 100644 index 0000000..5f4102a Binary files /dev/null and b/docs/Copy of images/mech picts/daishi.jpg differ diff --git a/docs/Copy of images/mech picts/deimos.jpg b/docs/Copy of images/mech picts/deimos.jpg new file mode 100644 index 0000000..717d2c5 Binary files /dev/null and b/docs/Copy of images/mech picts/deimos.jpg differ diff --git a/docs/Copy of images/mech picts/dragon.jpg b/docs/Copy of images/mech picts/dragon.jpg new file mode 100644 index 0000000..8438bee Binary files /dev/null and b/docs/Copy of images/mech picts/dragon.jpg differ diff --git a/docs/Copy of images/mech picts/grizzly.jpg b/docs/Copy of images/mech picts/grizzly.jpg new file mode 100644 index 0000000..2739fca Binary files /dev/null and b/docs/Copy of images/mech picts/grizzly.jpg differ diff --git a/docs/Copy of images/mech picts/hauptmann.jpg b/docs/Copy of images/mech picts/hauptmann.jpg new file mode 100644 index 0000000..25d63ce Binary files /dev/null and b/docs/Copy of images/mech picts/hauptmann.jpg differ diff --git a/docs/Copy of images/mech picts/hellhound.jpg b/docs/Copy of images/mech picts/hellhound.jpg new file mode 100644 index 0000000..430b3a5 Binary files /dev/null and b/docs/Copy of images/mech picts/hellhound.jpg differ diff --git a/docs/Copy of images/mech picts/highlander.jpg b/docs/Copy of images/mech picts/highlander.jpg new file mode 100644 index 0000000..0d1eead Binary files /dev/null and b/docs/Copy of images/mech picts/highlander.jpg differ diff --git a/docs/Copy of images/mech picts/hollanderii.jpg b/docs/Copy of images/mech picts/hollanderii.jpg new file mode 100644 index 0000000..229a877 Binary files /dev/null and b/docs/Copy of images/mech picts/hollanderii.jpg differ diff --git a/docs/Copy of images/mech picts/hunchback.jpg b/docs/Copy of images/mech picts/hunchback.jpg new file mode 100644 index 0000000..6b9c855 Binary files /dev/null and b/docs/Copy of images/mech picts/hunchback.jpg differ diff --git a/docs/Copy of images/mech picts/loki.jpg b/docs/Copy of images/mech picts/loki.jpg new file mode 100644 index 0000000..76c8d7a Binary files /dev/null and b/docs/Copy of images/mech picts/loki.jpg differ diff --git a/docs/Copy of images/mech picts/madcat.jpg b/docs/Copy of images/mech picts/madcat.jpg new file mode 100644 index 0000000..3a17413 Binary files /dev/null and b/docs/Copy of images/mech picts/madcat.jpg differ diff --git a/docs/Copy of images/mech picts/madcatii.jpg b/docs/Copy of images/mech picts/madcatii.jpg new file mode 100644 index 0000000..31427c5 Binary files /dev/null and b/docs/Copy of images/mech picts/madcatii.jpg differ diff --git a/docs/Copy of images/mech picts/masakari.jpg b/docs/Copy of images/mech picts/masakari.jpg new file mode 100644 index 0000000..fa11721 Binary files /dev/null and b/docs/Copy of images/mech picts/masakari.jpg differ diff --git a/docs/Copy of images/mech picts/mauler.jpg b/docs/Copy of images/mech picts/mauler.jpg new file mode 100644 index 0000000..72d7091 Binary files /dev/null and b/docs/Copy of images/mech picts/mauler.jpg differ diff --git a/docs/Copy of images/mech picts/novacat.jpg b/docs/Copy of images/mech picts/novacat.jpg new file mode 100644 index 0000000..b586751 Binary files /dev/null and b/docs/Copy of images/mech picts/novacat.jpg differ diff --git a/docs/Copy of images/mech picts/osiris.jpg b/docs/Copy of images/mech picts/osiris.jpg new file mode 100644 index 0000000..d3db9c6 Binary files /dev/null and b/docs/Copy of images/mech picts/osiris.jpg differ diff --git a/docs/Copy of images/mech picts/owens.jpg b/docs/Copy of images/mech picts/owens.jpg new file mode 100644 index 0000000..f9f4738 Binary files /dev/null and b/docs/Copy of images/mech picts/owens.jpg differ diff --git a/docs/Copy of images/mech picts/puma.jpg b/docs/Copy of images/mech picts/puma.jpg new file mode 100644 index 0000000..141596f Binary files /dev/null and b/docs/Copy of images/mech picts/puma.jpg differ diff --git a/docs/Copy of images/mech picts/raven.jpg b/docs/Copy of images/mech picts/raven.jpg new file mode 100644 index 0000000..3f41800 Binary files /dev/null and b/docs/Copy of images/mech picts/raven.jpg differ diff --git a/docs/Copy of images/mech picts/ryoken.jpg b/docs/Copy of images/mech picts/ryoken.jpg new file mode 100644 index 0000000..3915b0e Binary files /dev/null and b/docs/Copy of images/mech picts/ryoken.jpg differ diff --git a/docs/Copy of images/mech picts/shadowcat.jpg b/docs/Copy of images/mech picts/shadowcat.jpg new file mode 100644 index 0000000..4c2568b Binary files /dev/null and b/docs/Copy of images/mech picts/shadowcat.jpg differ diff --git a/docs/Copy of images/mech picts/templar.jpg b/docs/Copy of images/mech picts/templar.jpg new file mode 100644 index 0000000..062632c Binary files /dev/null and b/docs/Copy of images/mech picts/templar.jpg differ diff --git a/docs/Copy of images/mech picts/thanatos.jpg b/docs/Copy of images/mech picts/thanatos.jpg new file mode 100644 index 0000000..c5ce91e Binary files /dev/null and b/docs/Copy of images/mech picts/thanatos.jpg differ diff --git a/docs/Copy of images/mech picts/thor.jpg b/docs/Copy of images/mech picts/thor.jpg new file mode 100644 index 0000000..80f2ecc Binary files /dev/null and b/docs/Copy of images/mech picts/thor.jpg differ diff --git a/docs/Copy of images/mech picts/uller.jpg b/docs/Copy of images/mech picts/uller.jpg new file mode 100644 index 0000000..672e894 Binary files /dev/null and b/docs/Copy of images/mech picts/uller.jpg differ diff --git a/docs/Copy of images/mech picts/uziel.jpg b/docs/Copy of images/mech picts/uziel.jpg new file mode 100644 index 0000000..f8c65ce Binary files /dev/null and b/docs/Copy of images/mech picts/uziel.jpg differ diff --git a/docs/Copy of images/mech picts/vulture.jpg b/docs/Copy of images/mech picts/vulture.jpg new file mode 100644 index 0000000..e4fe0e5 Binary files /dev/null and b/docs/Copy of images/mech picts/vulture.jpg differ diff --git a/docs/Copy of images/mech picts/wolfhound.jpg b/docs/Copy of images/mech picts/wolfhound.jpg new file mode 100644 index 0000000..3885bc4 Binary files /dev/null and b/docs/Copy of images/mech picts/wolfhound.jpg differ diff --git a/docs/Copy of images/mech picts/zeus.jpg b/docs/Copy of images/mech picts/zeus.jpg new file mode 100644 index 0000000..f151418 Binary files /dev/null and b/docs/Copy of images/mech picts/zeus.jpg differ diff --git a/docs/Copy of images/mech.gif b/docs/Copy of images/mech.gif new file mode 100644 index 0000000..a09c3b0 Binary files /dev/null and b/docs/Copy of images/mech.gif differ diff --git a/docs/Copy of images/mr-block.gif b/docs/Copy of images/mr-block.gif new file mode 100644 index 0000000..048d397 Binary files /dev/null and b/docs/Copy of images/mr-block.gif differ diff --git a/docs/Copy of images/mr.gif b/docs/Copy of images/mr.gif new file mode 100644 index 0000000..f97dbb1 Binary files /dev/null and b/docs/Copy of images/mr.gif differ diff --git a/docs/Copy of images/submit.gif b/docs/Copy of images/submit.gif new file mode 100644 index 0000000..983f6d9 Binary files /dev/null and b/docs/Copy of images/submit.gif differ diff --git a/docs/Copy of images/weight.gif b/docs/Copy of images/weight.gif new file mode 100644 index 0000000..f10422a Binary files /dev/null and b/docs/Copy of images/weight.gif differ diff --git a/docs/Copy of images/who.gif b/docs/Copy of images/who.gif new file mode 100644 index 0000000..671a73b Binary files /dev/null and b/docs/Copy of images/who.gif differ diff --git a/docs/New images/Galactic_Troopers_by_tetramegistus.ttf b/docs/New images/Galactic_Troopers_by_tetramegistus.ttf new file mode 100644 index 0000000..7b19804 Binary files /dev/null and b/docs/New images/Galactic_Troopers_by_tetramegistus.ttf differ diff --git a/docs/New images/callsign.gif b/docs/New images/callsign.gif new file mode 100644 index 0000000..5ef0fec Binary files /dev/null and b/docs/New images/callsign.gif differ diff --git a/docs/New images/class.gif b/docs/New images/class.gif new file mode 100644 index 0000000..bd1d607 Binary files /dev/null and b/docs/New images/class.gif differ diff --git a/docs/New images/group.gif b/docs/New images/group.gif new file mode 100644 index 0000000..bc3a3d0 Binary files /dev/null and b/docs/New images/group.gif differ diff --git a/docs/New images/howmany.gif b/docs/New images/howmany.gif new file mode 100644 index 0000000..07fc46b Binary files /dev/null and b/docs/New images/howmany.gif differ diff --git a/docs/New images/mech.gif b/docs/New images/mech.gif new file mode 100644 index 0000000..86e346b Binary files /dev/null and b/docs/New images/mech.gif differ diff --git a/docs/New images/mr.gif b/docs/New images/mr.gif new file mode 100644 index 0000000..2302cd1 Binary files /dev/null and b/docs/New images/mr.gif differ diff --git a/docs/New images/submit.gif b/docs/New images/submit.gif new file mode 100644 index 0000000..5f85469 Binary files /dev/null and b/docs/New images/submit.gif differ diff --git a/docs/New images/who.gif b/docs/New images/who.gif new file mode 100644 index 0000000..198d359 Binary files /dev/null and b/docs/New images/who.gif differ diff --git a/docs/RP_40.mp4 b/docs/RP_40.mp4 new file mode 100644 index 0000000..e94aaa2 Binary files /dev/null and b/docs/RP_40.mp4 differ diff --git a/docs/RP_Dooley_Tesla.mp4 b/docs/RP_Dooley_Tesla.mp4 new file mode 100644 index 0000000..7109548 Binary files /dev/null and b/docs/RP_Dooley_Tesla.mp4 differ diff --git a/docs/RP_Dooley_Tesla_boosted_audio_10.mp4 b/docs/RP_Dooley_Tesla_boosted_audio_10.mp4 new file mode 100644 index 0000000..b958d14 Binary files /dev/null and b/docs/RP_Dooley_Tesla_boosted_audio_10.mp4 differ diff --git a/docs/RP_Dooley_Tesla_boosted_audio_20.mp4 b/docs/RP_Dooley_Tesla_boosted_audio_20.mp4 new file mode 100644 index 0000000..126bcf6 Binary files /dev/null and b/docs/RP_Dooley_Tesla_boosted_audio_20.mp4 differ diff --git a/docs/RP_Dooley_Tesla_boosted_audio_20_10.mp4 b/docs/RP_Dooley_Tesla_boosted_audio_20_10.mp4 new file mode 100644 index 0000000..8e095e1 Binary files /dev/null and b/docs/RP_Dooley_Tesla_boosted_audio_20_10.mp4 differ diff --git a/docs/RP_Dooley_Tesla_boosted_audio_20_20.mp4 b/docs/RP_Dooley_Tesla_boosted_audio_20_20.mp4 new file mode 100644 index 0000000..ce6dc00 Binary files /dev/null and b/docs/RP_Dooley_Tesla_boosted_audio_20_20.mp4 differ diff --git a/docs/SQL_TCPip_Fixes.reg b/docs/SQL_TCPip_Fixes.reg new file mode 100644 index 0000000..eb9dbdb Binary files /dev/null and b/docs/SQL_TCPip_Fixes.reg differ diff --git a/docs/callsign.php.old b/docs/callsign.php.old new file mode 100644 index 0000000..146a06a --- /dev/null +++ b/docs/callsign.php.old @@ -0,0 +1,377 @@ + + +PQS - CallSign v2 + + + + + +"; + echo "

"; + echo ""; + echo "

Thank you $_GET[callsign]. You have been entered into the queue piloting a $mechname.

You are currently set for mission:

#$missionid

Please continue to check the queue displays for your position in the queue.

"; + echo ""; + exit; + } + + if($isLeader){ + + $sql = "SELECT MissionID, numplayers FROM pqs_mission WHERE Completed = 0 AND locked = 0 AND ($hm + numplayers) <= MissionSize ORDER BY MissionID ASC"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($getid); + $missionid = $rs[0]; + $numplayers = $rs[1]; + mysqli_close($link); + + if ($missionid == "") { + $missionsize = $_SESSION['mechpods']; + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "INSERT INTO pqs_mission (MissionDate, MissionSize, numplayers, MissionTime) VALUES ($tdate, $missionsize, $hm, $ttime)"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $sql = "SELECT MissionID, numplayers FROM pqs_mission WHERE Completed = 0 AND locked = 0 AND numplayers <= MissionSize ORDER BY MissionID DESC"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs1 = mysqli_fetch_array($getid); + $missionid = $rs1[0]; + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $i = 2; + while ($i <= $hm){ + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign-$i','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $i ++; + } + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + mysqli_close($link); + } else { + $newplayers = $numplayers + $hm; + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "UPDATE pqs_mission SET numplayers = $newplayers WHERE MissionID = $missionid"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $i = 2; + while ($i <= $hm){ + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign-$i','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $i ++; + } + + mysqli_close($link); + } + + $minToDeparture = $timePerGame*($missionid-$lastCommitedMissionID); + $d=strtotime("+$minToDeparture Minutes",$lastCommitTime); + $etd = date("h:i", $d); + + echo ""; + echo "


"; + echo ""; + echo "

Thank you $_GET[callsign]. You have been entered into the queue piloting a $mechname.

You are currently set for mission:
#$missionid
Your Estimated Departure time is: $etd

Please continue to check the queue displays for your position in the queue.

"; + echo ""; + + exit; + } + + $sql = "SELECT MissionID, numplayers FROM pqs_mission WHERE Completed = 0 AND locked = 0 AND numplayers < MissionSize ORDER BY MissionID ASC"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($getid); + $missionid = $rs[0]; + $numplayers = $rs[1]; + + mysqli_close($link); + + if ($missionid == "") { + $missionsize = $_SESSION['mechpods']; + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "INSERT INTO pqs_mission (MissionDate, MissionSize, numplayers, MissionTime) VALUES ($tdate, $missionsize, 1, $ttime)"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $sql = "SELECT MissionID, numplayers FROM pqs_mission WHERE Completed = 0 AND locked = 0 AND numplayers < MissionSize ORDER BY MissionID"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs1 = mysqli_fetch_array($getid); + $missionid = $rs1[0]; + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + mysqli_close($link); + } else { + $newplayers = $numplayers + 1; + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "UPDATE pqs_mission SET numplayers = $newplayers WHERE MissionID = $missionid"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $query = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mechname',$missionid)"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + mysqli_close($link); + } + + $minToDeparture = $timePerGame*($missionid-$lastCommitedMissionID); + $d=strtotime("+$minToDeparture Minutes",$lastCommitTime); + $etd = date("h:i", $d); + + echo ""; + echo "


"; + echo ""; + echo "

Thank you $_GET[callsign]. You have been entered into the queue piloting a $mechname.

You are currently set for mission:

#$missionid
Your Estimated Departure time is: $etd
Please continue to check the queue displays for your position in the queue.

"; + echo ""; + exit; +} +?> +
+
+ + +


+ + + + + + + + + + + + "; + } else if ($isMember){ + echo " + + + + + + + + +
                        

            

+ +
        group +
        howmany
        who
        "; + } + ?> + +
         +
         +
 
+
+
+ + + + diff --git a/docs/dbbuild.sql b/docs/dbbuild.sql new file mode 100644 index 0000000..793e0b9 --- /dev/null +++ b/docs/dbbuild.sql @@ -0,0 +1,133 @@ +/* +SQLyog Community Edition- MySQL GUI v6.03 +Host - 5.1.53-community-log : Database - pqs +********************************************************************* +Server version : 5.1.53-community-log +*/ + +/*!40101 SET NAMES utf8 */; + +/*!40101 SET SQL_MODE=''*/; + +create database if not exists `pqs`; + +USE `pqs`; + +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; + +/*Table structure for table `pqs_currentmission` */ + +DROP TABLE IF EXISTS `pqs_currentmission`; + +CREATE TABLE `pqs_currentmission` ( + `Callsign` varchar(25) DEFAULT NULL, + `Missionid` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*Data for the table `pqs_currentmission` */ + +insert into `pqs_currentmission`(`Callsign`,`Missionid`) values ('DocEVL',29),('Tide',29),('Trineghj',29),('Sh'dfghow',29); + +/*Table structure for table `pqs_gameconfig` */ + +DROP TABLE IF EXISTS `pqs_gameconfig`; + +CREATE TABLE `pqs_gameconfig` ( + `gamechoiceid` int(11) DEFAULT NULL, + `numpods` int(11) DEFAULT NULL, + `timepergame` int(11) DEFAULT NULL, + `timetoreset` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*Data for the table `pqs_gameconfig` */ + +insert into `pqs_gameconfig`(`gamechoiceid`,`numpods`,`timepergame`,`timetoreset`) values (1,12,7,2); + +/*Table structure for table `pqs_infopanel` */ + +DROP TABLE IF EXISTS `pqs_infopanel`; + +CREATE TABLE `pqs_infopanel` ( + `Updated` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*Data for the table `pqs_infopanel` */ + +insert into `pqs_infopanel`(`Updated`) values (0); + +/*Table structure for table `pqs_mechinfo` */ + +DROP TABLE IF EXISTS `pqs_mechinfo`; + +CREATE TABLE `pqs_mechinfo` ( + `MechID` int(11) NOT NULL AUTO_INCREMENT, + `MechName` varchar(25) NOT NULL, + `Firepower` int(11) NOT NULL, + `Armor` int(11) NOT NULL, + `Speed` int(11) NOT NULL, + `Heat` int(11) NOT NULL, + `Class` varchar(25) NOT NULL, + `img_name` varchar(25) NOT NULL, + `Tons` int(11) NOT NULL, + PRIMARY KEY (`MechID`) +) ENGINE=MyISAM AUTO_INCREMENT=43 DEFAULT CHARSET=latin1; + +/*Data for the table `pqs_mechinfo` */ + +insert into `pqs_mechinfo`(`MechID`,`MechName`,`Firepower`,`Armor`,`Speed`,`Heat`,`Class`,`img_name`,`Tons`) values (1,'Brigand',25,28,85,74,'Light','brigand.jpg',25),(2,'Commando',27,34,85,100,'Light','commando.jpg',25),(3,'Osiris',22,34,83,93,'Light','osiris.jpg',30),(4,'Uller',35,31,89,89,'Light','uller.jpg',30),(5,'Cougar',37,40,81,83,'Light','cougar.jpg',35),(6,'Owens',43,39,80,71,'Light','owens.jpg',35),(7,'Puma',57,38,82,89,'Light','puma.jpg',35),(8,'Raven',35,35,77,76,'Light','raven.jpg',35),(9,'Wolfhound IIC',28,39,72,80,'Light','wolfhound.jpg',35),(10,'Arctic Wolf',47,45,73,80,'Medium','arcticwolf.jpg',40),(11,'Chimera',47,46,73,59,'Medium','chimera.jpg',40),(12,'Hollander II',45,48,75,61,'Medium','hollanderii.jpg',45),(13,'Shadowcat',51,48,73,74,'Medium','shadowcat.jpg',45),(14,'Hellhound',47,54,67,59,'Medium','hellhound.jpg',50),(15,'Hunchback',38,52,64,63,'Medium','hunchback.jpg',50),(16,'Uziel',43,50,69,60,'Medium','uziel.jpg',50),(17,'Black Lanner',50,56,67,56,'Medium','blacklanner.jpg',55),(18,'Bushwacker',45,58,70,56,'Medium','bushwacker.jpg',55),(19,'Ryoken',55,58,70,56,'Medium','ryoken.jpg',55),(20,'Dragon',43,60,63,55,'Heavy','dragon.jpg',60),(21,'Vulture',59,63,63,52,'Heavy','vulture.jpg',60),(22,'Catapult',70,60,65,42,'Heavy','catapult.jpg',65),(23,'Cauldronborn',65,60,61,70,'Heavy','cauldronborn.jpg',65),(24,'Loki',48,64,57,77,'Heavy','loki.jpg',65),(25,'Grizzly',55,67,54,61,'Heavy','grizzly.jpg',70),(26,'Novacat',51,65,59,50,'Heavy','novacat.jpg',70),(27,'Thor',58,67,50,71,'Heavy','thor.jpg',70),(28,'Black Knight',61,65,55,50,'Heavy','blackknight.jpg',75),(29,'Mad Cat',58,70,58,56,'Heavy','madcat.jpg',75),(30,'Thanatos',63,66,48,51,'Heavy','thanatos.jpg',75),(31,'Awesome',57,74,47,58,'Assault','awesome.jpg',80),(32,'Zeus',80,71,49,60,'Assault','zeus.jpg',80),(33,'Deimos',80,71,49,60,'Assault','deimos.jpg',85),(34,'Masakari',66,78,49,69,'Assault','masakari.jpg',85),(35,'Templar',68,77,49,60,'Assault','templar.jpg',85),(36,'Cyclops',72,78,46,50,'Assault','cyclops.jpg',90),(37,'Highlander',73,79,42,55,'Assault','highlander.jpg',90),(38,'Madcat Mk II',93,78,46,56,'Assault','madcatii.jpg',90),(39,'Mauler',95,78,41,50,'Assault','mauler.jpg',90),(40,'Hauptmann IIC',86,84,35,51,'Assault','hauptmann.jpg',95),(41,'Atlas',95,99,38,50,'Assault','atlas.jpg',100),(42,'Daishi',78,91,36,57,'Assault','daishi.jpg',100); + +/*Table structure for table `pqs_mission` */ + +DROP TABLE IF EXISTS `pqs_mission`; + +CREATE TABLE `pqs_mission` ( + `MissionID` int(11) NOT NULL AUTO_INCREMENT, + `MissionDate` int(11) NOT NULL, + `MissionSize` int(11) NOT NULL, + `numplayers` int(11) DEFAULT NULL, + `Completed` tinyint(1) NOT NULL DEFAULT '0', + `nummercs` int(11) NOT NULL, + `locked` tinyint(1) NOT NULL DEFAULT '0', + `MissionTime` int(11) NOT NULL, + UNIQUE KEY `MatchID` (`MissionID`) +) ENGINE=MyISAM AUTO_INCREMENT=35 DEFAULT CHARSET=latin1; + +/*Data for the table `pqs_mission` */ + +insert into `pqs_mission`(`MissionID`,`MissionDate`,`MissionSize`,`numplayers`,`Completed`,`nummercs`,`locked`,`MissionTime`) values (5,20120630,6,5,1,1,0,0),(4,20120630,6,6,1,0,0,0),(6,20120630,6,6,1,0,0,0),(7,20120630,6,6,1,0,0,0),(8,20120630,12,3,1,0,0,0),(9,20120630,12,2,1,0,1,0),(10,20120630,12,3,1,0,0,0),(11,20120704,12,3,1,9,0,0),(12,20120704,12,1,1,0,1,0),(13,20120704,12,12,1,0,0,0),(14,20120704,12,12,1,0,0,2045),(15,20120705,12,5,1,0,0,2048),(16,20120705,4,4,1,0,0,2050),(17,20120705,4,4,1,0,0,957),(18,20120705,4,3,1,0,0,10),(19,20120705,4,1,1,0,1,17),(20,20120705,4,1,1,0,0,17),(21,20120705,4,1,1,0,0,17),(22,20120705,4,1,1,0,1,17),(23,20120709,4,4,1,0,0,1439),(25,20120715,4,4,1,0,1,1627),(27,20120723,4,4,1,0,0,2048),(28,20120723,4,4,1,0,1,2059),(29,20120723,4,4,1,0,0,918),(30,20120723,4,12,0,0,0,1645),(31,20120723,4,4,0,1,0,1650),(32,20120723,4,1,0,0,0,2130),(33,20120723,4,1,0,0,0,2130),(34,20120724,12,1,0,0,0,1741); + +/*Table structure for table `pqs_pastmissions` */ + +DROP TABLE IF EXISTS `pqs_pastmissions`; + +CREATE TABLE `pqs_pastmissions` ( + `Callsign` varchar(25) DEFAULT NULL, + `Mech` varchar(25) DEFAULT NULL, + `Missionid` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*Data for the table `pqs_pastmissions` */ + +insert into `pqs_pastmissions`(`Callsign`,`Mech`,`Missionid`) values ('Shadow','Brigand',6),('Eric','Osiris',6),('Ulyses','Puma',6),('Yoga','Commando',6),('Dad','Raven',6),('Inga','Dragon',6),('strhshsh','Madcat Mk II',7),('shtrzsf','Zeus',7),('dhtrstyhstrh','Owens',7),('sdgfdsfgdfg','Raven',7),('dfhfdgg','Commando',7),('Graffy','Wolfhound IIC',7),('Michael','Cougar',8),('Eric','Commando',8),('Shadow','Brigand',8),('Michael','Commando',9),('Eric','Osiris',9),('Dodo','Brigand',10),('Fred','Arctic Wolf',10),('John','Cougar',10),('George','Uller',11),('Messa','Puma',11),('Harry','Commando',11),('Holder','Commando',12),('seven','Brigand',13),('six','Brigand',13),('five','Brigand',13),('four','Brigand',13),('three','Brigand',13),('two','Brigand',13),('one','Brigand',13),('eight','Brigand',13),('nine','Brigand',13),('ten','Brigand',13),('eleven','Brigand',13),('twelve','Brigand',13),('11','Commando',14),('12','Commando',14),('10','Commando',14),('9','Commando',14),('8','Commando',14),('7','Commando',14),('6','Commando',14),('5','Commando',14),('4','Commando',14),('3','Commando',14),('1','Commando',14),('2','Commando',14),('Gobi','Wolfhound IIC',15),('Steve','Chimera',15),('Dad','Hunchback',15),('Shadow','Brigand',15),('Mike','Commando',15),('killo','Commando',16),('dasdi','Commando',16),('hello','Brigand',16),('fred','Brigand',16),('tenta','Hellhound',17),('redcat','Loki',17),('wendi','Shadowcat',17),('silva','Wolfhound IIC',17),('george','Chimera',18),('gooda','Commando',18),('dgfgdf','Arctic Wolf',18),('Shadow','Owens',19),('Shadow','Brigand',20),('Shadow','Osiris',21),('Shadow','Hollander II',22),('DocEVL','Madcat Mk II',23),('Lady Methalynn','Hauptmann IIC',23),('Shadow','Awesome',23),('QQQQQQQQQQQQQQQQ','Hauptmann IIC',23),('Roger','Madcat Mk II',25),('Roger','Madcat Mk II',25),('Roger','Madcat Mk II',25),('Roger','Madcat Mk II',25),('Roger','Madcat Mk II',25),('Me\'ath','Black Knight',25),('G\'ould','Arctic Wolf',25),('QQQQQQQQQQQQQQQQ','Hauptmann IIC',25),('Sh\'dfghow','Arctic Wolf',27),('DocEL','Bushwacker',27),('Tide','Black Lanner',27),('Trineghj','Dragon',27),('Slighlty Tilted','Mauler',28),('DocEVL','Bushwacker',28),('Tide','Black Lanner',28),('Trineghj','Dragon',28),('DocEVL','Bushwacker',29),('Tide','Black Lanner',29),('Trineghj','Dragon',29),('Sh'dfghow','Arctic Wolf',29); + +/*Table structure for table `pqs_queue` */ + +DROP TABLE IF EXISTS `pqs_queue`; + +CREATE TABLE `pqs_queue` ( + `CallSign` varchar(25) NOT NULL, + `Mech` varchar(25) NOT NULL, + `ID` int(11) NOT NULL AUTO_INCREMENT, + `MissionID` int(11) DEFAULT NULL, + `Merc` tinyint(1) NOT NULL DEFAULT '0', + `Updated` tinyint(1) NOT NULL DEFAULT '0', + UNIQUE KEY `ID` (`ID`) +) ENGINE=MyISAM AUTO_INCREMENT=365 DEFAULT CHARSET=latin1; + +/*Data for the table `pqs_queue` */ + +insert into `pqs_queue`(`CallSign`,`Mech`,`ID`,`MissionID`,`Merc`,`Updated`) values ('h','Dragon',361,30,0,0),('Flyscreen','Hauptmann IIC',359,30,0,1),('g','Dragon',360,30,0,0),('e','Dragon',358,30,0,0),('DocEVL','Bushwacker',334,30,0,0),('d','Dragon',357,30,0,0),('Tide','Black Lanner',353,33,0,0),('Tide','Black Lanner',352,32,0,0),('c','Dragon',356,30,0,0),('Tide','Black Lanner',351,31,0,0),('b','Dragon',355,30,0,0),('Briana9','Dragon',339,30,1,0),('Trineghj','Dragon',340,31,1,0),('Alpha','Cougar',354,30,0,0),('Sh'dfghow','Arctic Wolf',348,30,0,0),('ShadowHawk','Zeus',349,30,0,0),('Superman','Hauptmann IIC',350,31,0,0),('Sh'dow','Atlas',363,34,0,0),('Gorgalla','Templar',364,31,0,0); + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; diff --git a/docs/get.py b/docs/get.py new file mode 100644 index 0000000..66ecf7f --- /dev/null +++ b/docs/get.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +from urllib2 import urlopen +from time import sleep +import os + +while True: + + sleep(5) + response = urlopen('http://10.0.0.10/pqs/playFSTrainer.php') + play = response.readline() + + if ( play == "1" ): + os.system('pkill omxplayer') + os.system('omxplayer -b -o hdmi /home/pi/Downloads/BTFS_VTS_01_1.mp4 &') + sleep(1) + diff --git a/docs/intro.mp4 b/docs/intro.mp4 new file mode 100644 index 0000000..39e6c12 Binary files /dev/null and b/docs/intro.mp4 differ diff --git a/docs/ni.mp3 b/docs/ni.mp3 new file mode 100644 index 0000000..4eba917 Binary files /dev/null and b/docs/ni.mp3 differ diff --git a/docs/npp.6.9.2.Installer.exe b/docs/npp.6.9.2.Installer.exe new file mode 100644 index 0000000..4d5517f Binary files /dev/null and b/docs/npp.6.9.2.Installer.exe differ diff --git a/docs/omx_button.py b/docs/omx_button.py new file mode 100644 index 0000000..a4890ed --- /dev/null +++ b/docs/omx_button.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +from time import sleep +import os +import RPi.GPIO as GPIO + +GPIO.setmode(GPIO.BCM) +GPIO.setwarnings(False) +GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP) +GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP) +GPIO.setup(25, GPIO.IN, pull_up_down=GPIO.PUD_UP) + +while True: + + sleep(.1) + + if ( GPIO.input(23) == False ): + os.system('pkill omxplayer') + sleep(1) + + if ( GPIO.input(24) == False ): + os.system('pkill omxplayer') +# os.system('omxplayer -b -o hdmi --vol -1500 /home/pi/Downloads/BTFS_VTS_01_1.mp4 &') + os.system('omxplayer -b -o hdmi /home/pi/Downloads/BTFS_VTS_01_1.mp4 &') + sleep(1) + + if ( GPIO.input(25) == False ): + os.system('pkill omxplayer') +# os.system('omxplayer -b -o hdmi --amp 600 /home/pi/Downloads/RP_Dooley_Tesla.mp4 &') + os.system('omxplayer -b -o hdmi /home/pi/Downloads/RP_Dooley_Tesla_boosted_audio_20.mp4 &') + sleep(1) diff --git a/docs/omxplayer-helper-scripts.rev2.tar b/docs/omxplayer-helper-scripts.rev2.tar new file mode 100644 index 0000000..6ae87fc Binary files /dev/null and b/docs/omxplayer-helper-scripts.rev2.tar differ diff --git a/docs/pqs.sql b/docs/pqs.sql new file mode 100644 index 0000000..1ea96c8 --- /dev/null +++ b/docs/pqs.sql @@ -0,0 +1,355 @@ +-- phpMyAdmin SQL Dump +-- version 3.4.11.1deb2+deb7u5 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: Feb 19, 2017 at 12:21 AM +-- Server version: 5.5.50 +-- PHP Version: 5.4.45-0+deb7u4 + +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +-- +-- Database: `pqs` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_currentmission` +-- + +CREATE TABLE IF NOT EXISTS `pqs_currentmission` ( + `Callsign` varchar(25) DEFAULT NULL, + `MissionID` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_gameconfig` +-- + +CREATE TABLE IF NOT EXISTS `pqs_gameconfig` ( + `gamechoiceid` int(11) DEFAULT NULL, + `numpods` int(11) DEFAULT NULL, + `timepergame` int(11) DEFAULT NULL, + `timetoreset` int(11) DEFAULT NULL, + `mapid` int(11) NOT NULL, + `typeid` int(11) NOT NULL, + `launchdelay` int(11) NOT NULL, + `visibility` int(11) NOT NULL, + `weather` int(11) NOT NULL, + `timeofday` int(11) NOT NULL, + `timelimit` int(11) NOT NULL, + `radar` int(11) NOT NULL, + `heat` tinyint(1) NOT NULL, + `friendlyfire` tinyint(1) NOT NULL, + `splashdamage` tinyint(1) NOT NULL, + `limitedammo` tinyint(1) NOT NULL, + `noreturn` tinyint(1) NOT NULL, + `printdebriefing` tinyint(1) NOT NULL, + `missionreview` tinyint(1) NOT NULL, + `weaponjam` tinyint(1) NOT NULL, + `advancemode` tinyint(1) NOT NULL, + `armormode` tinyint(1) NOT NULL, + `cameraship` int(2) NOT NULL, + `GroupAvalible` tinyint(1) NOT NULL, + UNIQUE KEY `gamechoiceid` (`gamechoiceid`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `pqs_gameconfig` +-- + +INSERT INTO `pqs_gameconfig` (`gamechoiceid`, `numpods`, `timepergame`, `timetoreset`, `mapid`, `typeid`, `launchdelay`, `visibility`, `weather`, `timeofday`, `timelimit`, `radar`, `heat`, `friendlyfire`, `splashdamage`, `limitedammo`, `noreturn`, `printdebriefing`, `missionreview`, `weaponjam`, `advancemode`, `armormode`, `cameraship`, `GroupAvalible`) VALUES +(1, 6, 10, 5, -1, 3, 5, 1, 1, 1, 10, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 2, 0); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_gametype` +-- + +CREATE TABLE IF NOT EXISTS `pqs_gametype` ( + `TypeID` int(11) NOT NULL AUTO_INCREMENT, + `TypeName` varchar(22) NOT NULL, + `roster` int(11) NOT NULL, + PRIMARY KEY (`TypeID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ; + +-- +-- Dumping data for table `pqs_gametype` +-- + +INSERT INTO `pqs_gametype` (`TypeID`, `TypeName`, `roster`) VALUES +(1, 'Destruction', -2), +(2, 'Team Destruction', -1), +(3, 'Attrition', 0), +(4, 'Team Attrition', 1), +(5, 'Capture the Flag', 2), +(6, 'King of the Hill', 3), +(7, 'Team King of the Hill', 4), +(8, 'Steal the Beacon', 5), +(9, 'Master Trial', 6), +(10, 'Siege Assault', 7); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_infopanel` +-- + +CREATE TABLE IF NOT EXISTS `pqs_infopanel` ( + `Updated` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `pqs_infopanel` +-- + +INSERT INTO `pqs_infopanel` (`Updated`) VALUES +(0); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_mapinfo` +-- + +CREATE TABLE IF NOT EXISTS `pqs_mapinfo` ( + `MapID` int(11) NOT NULL, + `MapName` varchar(25) NOT NULL, + `D` tinyint(1) NOT NULL, + `TD` tinyint(1) NOT NULL, + `A` tinyint(1) NOT NULL, + `TA` tinyint(1) NOT NULL, + `CTF` tinyint(1) NOT NULL, + `KOTH` tinyint(1) NOT NULL, + `TKOTH` tinyint(1) NOT NULL, + `STB` tinyint(1) NOT NULL, + `MT` tinyint(1) NOT NULL, + `SA` tinyint(1) NOT NULL, + `size` int(11) NOT NULL, + `DZ` int(11) NOT NULL, + `HE` int(11) NOT NULL, + `MRB` int(11) NOT NULL, + UNIQUE KEY `MapID` (`MapID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `pqs_mapinfo` +-- + +INSERT INTO `pqs_mapinfo` (`MapID`, `MapName`, `D`, `TD`, `A`, `TA`, `CTF`, `KOTH`, `TKOTH`, `STB`, `MT`, `SA`, `size`, `DZ`, `HE`, `MRB`) VALUES +(-1, 'Random', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(1, 'BigCity', 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 4, 4, 0, 0), +(2, 'Cantina', 2, 2, 2, 2, 2, 0, 0, 0, 0, 1, 3, 4, 0, 1), +(3, 'CentralPark', 3, 3, 3, 3, 0, 1, 1, 1, 1, 0, 4, 4, 0, 0), +(4, 'Coliseum', 4, 4, 4, 4, 3, 0, 0, 0, 0, 0, 2, 4, 0, 1), +(5, 'DustBowl', 5, 5, 5, 5, 0, 2, 2, 0, 0, 0, 4, 4, 0, 0), +(6, 'Factory', 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0), +(7, 'Frostbite', 7, 7, 7, 7, 4, 3, 3, 2, 0, 0, 4, 4, 0, 0), +(8, 'Freezer', 8, 8, 8, 8, 0, 4, 4, 0, 2, 0, 4, 4, 0, 0), +(9, 'GatorBait', 9, 9, 9, 9, 0, 5, 5, 3, 3, 0, 4, 4, 0, 0), +(10, 'GhostHighway', 10, 10, 10, 10, 0, 6, 6, 4, 4, 0, 4, 4, 0, 0), +(11, 'Grassland', 11, 11, 11, 11, 5, 7, 0, 0, 5, 0, 4, 4, 0, 0), +(12, 'Hidaway', 12, 12, 12, 12, 6, 8, 7, 5, 0, 0, 4, 2, 0, 1), +(13, 'Hotplate', 13, 13, 13, 13, 7, 0, 0, 0, 6, 0, 4, 4, 0, 0), +(14, 'InnerCity', 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0), +(15, 'Jungle', 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0), +(16, 'Lunacy', 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0), +(17, 'Nazca', 17, 17, 17, 17, 8, 9, 8, 0, 7, 0, 4, 4, 0, 0), +(18, 'PalaceGates', 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0), +(19, 'Peaks', 19, 19, 19, 19, 9, 0, 0, 0, 8, 0, 4, 4, 0, 0), +(20, 'Reduex', 20, 20, 20, 20, 10, 0, 0, 0, 0, 2, 3, 4, 0, 1), +(21, 'ScarabStronghold', 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0), +(22, 'SnowJob', 22, 22, 22, 22, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0), +(23, 'StormCanyon', 23, 23, 23, 23, 11, 0, 0, 0, 0, 3, 3, 4, 0, 1), +(24, 'Timberline', 24, 24, 24, 24, 12, 0, 0, 0, 0, 0, 4, 4, 0, 0), +(25, 'TribelIncursion', 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 3, 3, 0, 1); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_mechinfo` +-- + +CREATE TABLE IF NOT EXISTS `pqs_mechinfo` ( + `MechID` int(11) NOT NULL AUTO_INCREMENT, + `MechName` varchar(25) NOT NULL, + `Firepower` int(11) NOT NULL, + `Armor` int(11) NOT NULL, + `Speed` int(11) NOT NULL, + `Heat` int(11) NOT NULL, + `Class` varchar(25) NOT NULL, + `img_name` varchar(25) NOT NULL, + `Tons` int(11) NOT NULL, + `roster` int(11) NOT NULL, + PRIMARY KEY (`MechID`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=64 ; + +-- +-- Dumping data for table `pqs_mechinfo` +-- + +INSERT INTO `pqs_mechinfo` (`MechID`, `MechName`, `Firepower`, `Armor`, `Speed`, `Heat`, `Class`, `img_name`, `Tons`, `roster`) VALUES +(1, 'Brigand', 25, 28, 85, 74, 'Light', 'brigand.jpg', 25, 17), +(2, 'Commando', 27, 34, 85, 100, 'Light', 'commando.jpg', 25, 22), +(3, 'Osiris', 22, 34, 83, 93, 'Light', 'osiris.jpg', 30, 46), +(4, 'Uller', 35, 31, 89, 89, 'Light', 'uller.jpg', 30, 58), +(5, 'Cougar', 37, 40, 81, 83, 'Light', 'cougar.jpg', 35, 23), +(6, 'Owens', 43, 39, 80, 71, 'Light', 'owens.jpg', 35, 47), +(7, 'Puma', 57, 38, 82, 89, 'Light', 'puma.jpg', 35, 48), +(8, 'Raven', 35, 35, 77, 76, 'Light', 'raven.jpg', 35, 49), +(9, 'Wolfhound IIC', 28, 39, 72, 80, 'Light', 'wolfhound.jpg', 35, 64), +(10, 'Arctic Wolf', 47, 45, 73, 80, 'Medium', 'arcticwolf.jpg', 40, 3), +(11, 'Chimera', 47, 46, 73, 59, 'Medium', 'chimera.jpg', 40, 21), +(12, 'Hollander II', 45, 48, 75, 61, 'Medium', 'hollanderii.jpg', 45, 36), +(13, 'Shadowcat', 51, 48, 73, 74, 'Medium', 'shadowcat.jpg', 45, 52), +(14, 'Hellhound', 47, 54, 67, 59, 'Medium', 'hellhound.jpg', 50, 33), +(15, 'Hunchback', 38, 52, 64, 63, 'Medium', 'hunchback.jpg', 50, 37), +(16, 'Uziel', 43, 50, 69, 60, 'Medium', 'uziel.jpg', 50, 60), +(17, 'Black Lanner', 50, 56, 67, 56, 'Medium', 'blacklanner.jpg', 55, 16), +(18, 'Bushwacker', 45, 58, 70, 56, 'Medium', 'bushwacker.jpg', 55, 18), +(19, 'Ryoken', 55, 58, 70, 56, 'Medium', 'ryoken.jpg', 55, 51), +(20, 'Dragon', 43, 60, 63, 55, 'Heavy', 'dragon.jpg', 60, 27), +(21, 'Vulture', 59, 63, 63, 52, 'Heavy', 'vulture.jpg', 60, 62), +(22, 'Catapult', 70, 60, 65, 42, 'Heavy', 'catapult.jpg', 65, 19), +(23, 'Cauldronborn', 65, 60, 61, 70, 'Heavy', 'cauldronborn.jpg', 65, 20), +(24, 'Loki', 48, 64, 57, 77, 'Heavy', 'loki.jpg', 65, 39), +(25, 'Grizzly', 55, 67, 54, 61, 'Heavy', 'grizzly.jpg', 70, 31), +(26, 'Novacat', 51, 65, 59, 50, 'Heavy', 'novacat.jpg', 70, 45), +(27, 'Thor', 58, 67, 50, 71, 'Heavy', 'thor.jpg', 70, 57), +(28, 'Black Knight', 61, 65, 55, 50, 'Heavy', 'blackknight.jpg', 75, 15), +(29, 'Mad Cat', 58, 70, 58, 56, 'Heavy', 'madcat.jpg', 75, 41), +(30, 'Thanatos', 63, 66, 48, 51, 'Heavy', 'thanatos.jpg', 75, 56), +(31, 'Awesome', 57, 74, 47, 58, 'Assault', 'awesome.jpg', 80, 9), +(32, 'Zeus', 80, 71, 49, 60, 'Assault', 'zeus.jpg', 80, 65), +(33, 'Deimos', 80, 71, 49, 60, 'Assault', 'deimos.jpg', 85, 26), +(34, 'Masakari', 66, 78, 49, 69, 'Assault', 'masakari.jpg', 85, 43), +(35, 'Templar', 68, 77, 49, 60, 'Assault', 'templar.jpg', 85, 55), +(36, 'Cyclops', 72, 78, 46, 50, 'Assault', 'cyclops.jpg', 90, 24), +(37, 'Highlander', 73, 79, 42, 55, 'Assault', 'highlander.jpg', 90, 35), +(38, 'Madcat Mk II', 93, 78, 46, 56, 'Assault', 'madcatii.jpg', 90, 42), +(39, 'Mauler', 95, 78, 41, 50, 'Assault', 'mauler.jpg', 90, 44), +(40, 'Hauptmann IIC', 86, 84, 35, 51, 'Assault', 'hauptmann.jpg', 95, 32), +(41, 'Atlas', 95, 99, 38, 50, 'Assault', 'atlas.jpg', 100, 7), +(42, 'Daishi', 78, 91, 36, 57, 'Assault', 'daishi.jpg', 100, 25), +(43, 'Flea', 0, 0, 0, 0, 'Light', 'bdicon.jpg', 20, 29), +(44, 'Solitare', 0, 0, 0, 0, 'Light', 'bdicon.jpg', 25, 53), +(45, 'Assassin II', 0, 0, 0, 0, 'Medium', 'bdicon.jpg', 45, 6), +(46, 'Hellspawn', 0, 0, 0, 0, 'Medium', 'bdicon.jpg', 45, 34), +(47, 'Black Hawk', 0, 0, 0, 0, 'Medium', 'bdicon.jpg', 50, 14), +(48, 'Ares', 0, 0, 0, 0, 'Heavy', 'bdicon.jpg', 60, 4), +(49, 'Argus', 0, 0, 0, 0, 'Heavy', 'bdicon.jpg', 60, 5), +(50, 'Avatar', 0, 0, 0, 0, 'Heavy', 'bdicon.jpg', 70, 8), +(51, 'Longbow', 0, 0, 0, 0, 'Assault', 'bdicon.jpg', 85, 40), +(52, 'Victor', 0, 0, 0, 0, 'Assault', 'bdicon.jpg', 85, 61), +(53, 'Sunder', 0, 0, 0, 0, 'Assault', 'bdicon.jpg', 90, 54), +(54, 'Gladiator', 0, 0, 0, 0, 'Assault', 'bdicon.jpg', 95, 30), +(55, 'Annihilator', 0, 0, 0, 0, 'Assault', 'bdicon.jpg', 100, 1), +(56, 'Behemoth', 0, 0, 0, 0, 'Assault', 'bdicon.jpg', 100, 12), +(57, 'Fafnir', 0, 0, 0, 0, 'Assault', 'bdicon.jpg', 100, 28), +(58, 'Kodiak', 0, 0, 0, 0, 'Assault', 'bdicon.jpg', 100, 38), +(59, 'Random Any', 0, 0, 0, 0, 'Random', 'bdicon.jpg', 0, 0), +(60, 'Random Light', 0, 0, 0, 0, 'Random', 'bdicon.jpg', 20, -1), +(61, 'Random Medium', 0, 0, 0, 0, 'Random', 'bdicon.jpg', 40, -2), +(62, 'Random Heavy', 0, 0, 0, 0, 'Random', 'bdicon.jpg', 60, -3), +(63, 'Random Assault', 0, 0, 0, 0, 'Random', 'bdicon.jpg', 80, -4); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_mission` +-- + +CREATE TABLE IF NOT EXISTS `pqs_mission` ( + `MissionID` int(11) NOT NULL AUTO_INCREMENT, + `MissionDate` int(11) NOT NULL, + `MissionSize` int(11) NOT NULL, + `numplayers` int(11) DEFAULT NULL, + `Completed` tinyint(1) NOT NULL DEFAULT '0', + `nummercs` int(11) NOT NULL, + `locked` tinyint(1) NOT NULL DEFAULT '0', + `MissionTime` int(11) NOT NULL, + `GameType` int(11) NOT NULL DEFAULT '3', + `map` int(11) NOT NULL DEFAULT '21', + UNIQUE KEY `MatchID` (`MissionID`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_pastmissions` +-- + +CREATE TABLE IF NOT EXISTS `pqs_pastmissions` ( + `Callsign` varchar(25) DEFAULT NULL, + `Mech` varchar(25) DEFAULT NULL, + `Missionid` int(11) DEFAULT NULL, + `ctime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_pods` +-- + +CREATE TABLE IF NOT EXISTS `pqs_pods` ( + `pod01` tinyint(1) NOT NULL, + `pod02` tinyint(1) NOT NULL, + `pod03` tinyint(1) NOT NULL, + `pod04` tinyint(1) NOT NULL, + `pod05` tinyint(1) NOT NULL, + `pod06` tinyint(1) NOT NULL, + `pod07` tinyint(1) NOT NULL, + `pod08` tinyint(1) NOT NULL, + `pod09` tinyint(1) NOT NULL, + `pod10` tinyint(1) NOT NULL, + `pod11` tinyint(1) NOT NULL, + `pod12` tinyint(1) NOT NULL, + `pod13` tinyint(1) NOT NULL, + `pod14` tinyint(1) NOT NULL, + `pod15` tinyint(1) NOT NULL, + `pod16` tinyint(1) NOT NULL, + `ID` tinyint(1) NOT NULL, + UNIQUE KEY `ID` (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `pqs_pods` +-- + +INSERT INTO `pqs_pods` (`pod01`, `pod02`, `pod03`, `pod04`, `pod05`, `pod06`, `pod07`, `pod08`, `pod09`, `pod10`, `pod11`, `pod12`, `pod13`, `pod14`, `pod15`, `pod16`, `ID`) VALUES +(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `pqs_queue` +-- + +CREATE TABLE IF NOT EXISTS `pqs_queue` ( + `CallSign` varchar(25) NOT NULL, + `Mech` varchar(25) NOT NULL, + `ID` int(11) NOT NULL AUTO_INCREMENT, + `MissionID` int(11) DEFAULT NULL, + `Merc` tinyint(1) NOT NULL DEFAULT '0', + `Updated` tinyint(1) NOT NULL DEFAULT '0', + `team` int(2) NOT NULL DEFAULT '0', + `unit` int(2) NOT NULL DEFAULT '0', + UNIQUE KEY `ID` (`ID`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/docs/putty-0.63-installer.exe b/docs/putty-0.63-installer.exe new file mode 100644 index 0000000..4f7fa9c Binary files /dev/null and b/docs/putty-0.63-installer.exe differ diff --git a/docs/readme screen adjust.txt b/docs/readme screen adjust.txt new file mode 100644 index 0000000..9313fa8 --- /dev/null +++ b/docs/readme screen adjust.txt @@ -0,0 +1,4 @@ +To change the size of the combinedqueue.php file: + +To adjust width open combinedqueue.php and scroll to the bottom. Change both table width's to desired width. +To adjust height open css/main.css. Find div.queuediv3 and div.queuediv4 and adjust height parameter accordingly. \ No newline at end of file diff --git a/genconqueue.php b/genconqueue.php new file mode 100644 index 0000000..93da6ec --- /dev/null +++ b/genconqueue.php @@ -0,0 +1,113 @@ + + +PQS - Extended Player Queue + + + + + +"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo "
 
 
 
 
 
"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo "
 
 
 
 
 
"; +?> + diff --git a/getFSgame.php b/getFSgame.php new file mode 100644 index 0000000..4e96652 --- /dev/null +++ b/getFSgame.php @@ -0,0 +1,66 @@ + \ No newline at end of file diff --git a/getFSplayers.php b/getFSplayers.php new file mode 100644 index 0000000..c44e08a --- /dev/null +++ b/getFSplayers.php @@ -0,0 +1,54 @@ + \ No newline at end of file diff --git a/history.php b/history.php new file mode 100644 index 0000000..6df2ce9 --- /dev/null +++ b/history.php @@ -0,0 +1,90 @@ + + +PQS - History + + + + $maxmission) { $index = $minmission; } + } +} + +if ($index == $maxmission) { $fl = "(Last Mission)"; } +if ($index == $minmission) { $fl = "(First Mission)"; } + +$query = "SELECT callsign, mech, pqs_pastmissions.missionid, missiondate, nummercs, missionsize, numplayers, missiontime FROM pqs_pastmissions inner join pqs_mission where pqs_pastmissions.missionid = pqs_mission.missionid HAVING pqs_pastmissions.missionid = $index"; +$result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + +if (isset($_GET['launch'])) { + if ($_GET['launch'] == 'console') { + echo "
"; + } +} else { + echo "
"; +} +echo ""; +echo ""; + +while ($line = mysqli_fetch_array($result)) { + echo ""; + $cfull = $line[3]; + $cyear = substr($cfull,0,4); + $cmonth = substr($cfull,4,2); + $cday = substr($cfull,6); + $mdate = date("l, F jS, o", mktime(0,0,0, $cmonth,$cday,$cyear)); + $mercs = $line[4]; + $pods = $line[5]; + $numplayers = $line[6]; + if (strlen($line[7]) == 3) { + $mtime = substr($line[7], 0, 1); + $mtime = $mtime . ":"; + $mtime = $mtime . (substr($line[7], 1,2)); + } else { + $mtime = substr($line[7], 0, 2); + $mtime = $mtime . ":"; + $mtime = $mtime . (substr($line[7], 2,2)); + } +} +echo ""; +echo ""; +echo ""; +echo "
Mission #$index $fl
CallsignMech
$line[0]$line[1]
 
# Pods: $pods    |    # Players: $numplayers    |    # Mercs: $mercs
Mission Date: $mdate - $mtime
"; +if (isset($_GET['launch'])) { + if ($_GET['launch'] == 'console') { + echo ""; + } +} else { + echo "
"; +} +echo ""; +echo "
PrevCloseNext
"; +mysqli_free_result($result); +mysqli_close($link); +echo ""; +?> + diff --git a/images/Galactic_Troopers_by_tetramegistus.ttf b/images/Galactic_Troopers_by_tetramegistus.ttf new file mode 100644 index 0000000..7b19804 Binary files /dev/null and b/images/Galactic_Troopers_by_tetramegistus.ttf differ diff --git a/images/add.png b/images/add.png new file mode 100644 index 0000000..cc85423 Binary files /dev/null and b/images/add.png differ diff --git a/images/bdicon.jpg b/images/bdicon.jpg new file mode 100644 index 0000000..0f1f4cb Binary files /dev/null and b/images/bdicon.jpg differ diff --git a/images/bdiconsmall.JPG b/images/bdiconsmall.JPG new file mode 100644 index 0000000..dc2b641 Binary files /dev/null and b/images/bdiconsmall.JPG differ diff --git a/images/bsb.jpg b/images/bsb.jpg new file mode 100644 index 0000000..e9267cd Binary files /dev/null and b/images/bsb.jpg differ diff --git a/images/callsign.gif b/images/callsign.gif new file mode 100644 index 0000000..5ef0fec Binary files /dev/null and b/images/callsign.gif differ diff --git a/images/class.gif b/images/class.gif new file mode 100644 index 0000000..bd1d607 Binary files /dev/null and b/images/class.gif differ diff --git a/images/delete.png b/images/delete.png new file mode 100644 index 0000000..511a033 Binary files /dev/null and b/images/delete.png differ diff --git a/images/edit.png b/images/edit.png new file mode 100644 index 0000000..8bc5c66 Binary files /dev/null and b/images/edit.png differ diff --git a/images/grad.png b/images/grad.png new file mode 100644 index 0000000..75be618 Binary files /dev/null and b/images/grad.png differ diff --git a/images/group.gif b/images/group.gif new file mode 100644 index 0000000..bc3a3d0 Binary files /dev/null and b/images/group.gif differ diff --git a/images/howmany.gif b/images/howmany.gif new file mode 100644 index 0000000..07fc46b Binary files /dev/null and b/images/howmany.gif differ diff --git a/images/mech picts/arcticwolf.jpg b/images/mech picts/arcticwolf.jpg new file mode 100644 index 0000000..ed36881 Binary files /dev/null and b/images/mech picts/arcticwolf.jpg differ diff --git a/images/mech picts/atlas.jpg b/images/mech picts/atlas.jpg new file mode 100644 index 0000000..6e27179 Binary files /dev/null and b/images/mech picts/atlas.jpg differ diff --git a/images/mech picts/awesome.jpg b/images/mech picts/awesome.jpg new file mode 100644 index 0000000..18278e1 Binary files /dev/null and b/images/mech picts/awesome.jpg differ diff --git a/images/mech picts/bdicon.jpg b/images/mech picts/bdicon.jpg new file mode 100644 index 0000000..46dafb2 Binary files /dev/null and b/images/mech picts/bdicon.jpg differ diff --git a/images/mech picts/blackknight.jpg b/images/mech picts/blackknight.jpg new file mode 100644 index 0000000..9bfbbae Binary files /dev/null and b/images/mech picts/blackknight.jpg differ diff --git a/images/mech picts/blacklanner.jpg b/images/mech picts/blacklanner.jpg new file mode 100644 index 0000000..4d0cd63 Binary files /dev/null and b/images/mech picts/blacklanner.jpg differ diff --git a/images/mech picts/brigand.jpg b/images/mech picts/brigand.jpg new file mode 100644 index 0000000..ba98d59 Binary files /dev/null and b/images/mech picts/brigand.jpg differ diff --git a/images/mech picts/bushwacker.jpg b/images/mech picts/bushwacker.jpg new file mode 100644 index 0000000..d6b9941 Binary files /dev/null and b/images/mech picts/bushwacker.jpg differ diff --git a/images/mech picts/catapult.jpg b/images/mech picts/catapult.jpg new file mode 100644 index 0000000..3412595 Binary files /dev/null and b/images/mech picts/catapult.jpg differ diff --git a/images/mech picts/cauldronborn.jpg b/images/mech picts/cauldronborn.jpg new file mode 100644 index 0000000..e9cc847 Binary files /dev/null and b/images/mech picts/cauldronborn.jpg differ diff --git a/images/mech picts/chimera.jpg b/images/mech picts/chimera.jpg new file mode 100644 index 0000000..dd9f6a5 Binary files /dev/null and b/images/mech picts/chimera.jpg differ diff --git a/images/mech picts/commando.jpg b/images/mech picts/commando.jpg new file mode 100644 index 0000000..fbbe7e0 Binary files /dev/null and b/images/mech picts/commando.jpg differ diff --git a/images/mech picts/cougar.jpg b/images/mech picts/cougar.jpg new file mode 100644 index 0000000..40cf464 Binary files /dev/null and b/images/mech picts/cougar.jpg differ diff --git a/images/mech picts/cyclops.jpg b/images/mech picts/cyclops.jpg new file mode 100644 index 0000000..ef0e51c Binary files /dev/null and b/images/mech picts/cyclops.jpg differ diff --git a/images/mech picts/daishi.jpg b/images/mech picts/daishi.jpg new file mode 100644 index 0000000..5f4102a Binary files /dev/null and b/images/mech picts/daishi.jpg differ diff --git a/images/mech picts/deimos.jpg b/images/mech picts/deimos.jpg new file mode 100644 index 0000000..717d2c5 Binary files /dev/null and b/images/mech picts/deimos.jpg differ diff --git a/images/mech picts/dragon.jpg b/images/mech picts/dragon.jpg new file mode 100644 index 0000000..8438bee Binary files /dev/null and b/images/mech picts/dragon.jpg differ diff --git a/images/mech picts/grizzly.jpg b/images/mech picts/grizzly.jpg new file mode 100644 index 0000000..2739fca Binary files /dev/null and b/images/mech picts/grizzly.jpg differ diff --git a/images/mech picts/hauptmann.jpg b/images/mech picts/hauptmann.jpg new file mode 100644 index 0000000..25d63ce Binary files /dev/null and b/images/mech picts/hauptmann.jpg differ diff --git a/images/mech picts/hellhound.jpg b/images/mech picts/hellhound.jpg new file mode 100644 index 0000000..430b3a5 Binary files /dev/null and b/images/mech picts/hellhound.jpg differ diff --git a/images/mech picts/highlander.jpg b/images/mech picts/highlander.jpg new file mode 100644 index 0000000..0d1eead Binary files /dev/null and b/images/mech picts/highlander.jpg differ diff --git a/images/mech picts/hollanderii.jpg b/images/mech picts/hollanderii.jpg new file mode 100644 index 0000000..229a877 Binary files /dev/null and b/images/mech picts/hollanderii.jpg differ diff --git a/images/mech picts/hunchback.jpg b/images/mech picts/hunchback.jpg new file mode 100644 index 0000000..6b9c855 Binary files /dev/null and b/images/mech picts/hunchback.jpg differ diff --git a/images/mech picts/loki.jpg b/images/mech picts/loki.jpg new file mode 100644 index 0000000..76c8d7a Binary files /dev/null and b/images/mech picts/loki.jpg differ diff --git a/images/mech picts/madcat.jpg b/images/mech picts/madcat.jpg new file mode 100644 index 0000000..3a17413 Binary files /dev/null and b/images/mech picts/madcat.jpg differ diff --git a/images/mech picts/madcatii.jpg b/images/mech picts/madcatii.jpg new file mode 100644 index 0000000..31427c5 Binary files /dev/null and b/images/mech picts/madcatii.jpg differ diff --git a/images/mech picts/masakari.jpg b/images/mech picts/masakari.jpg new file mode 100644 index 0000000..fa11721 Binary files /dev/null and b/images/mech picts/masakari.jpg differ diff --git a/images/mech picts/mauler.jpg b/images/mech picts/mauler.jpg new file mode 100644 index 0000000..72d7091 Binary files /dev/null and b/images/mech picts/mauler.jpg differ diff --git a/images/mech picts/novacat.jpg b/images/mech picts/novacat.jpg new file mode 100644 index 0000000..b586751 Binary files /dev/null and b/images/mech picts/novacat.jpg differ diff --git a/images/mech picts/osiris.jpg b/images/mech picts/osiris.jpg new file mode 100644 index 0000000..d3db9c6 Binary files /dev/null and b/images/mech picts/osiris.jpg differ diff --git a/images/mech picts/owens.jpg b/images/mech picts/owens.jpg new file mode 100644 index 0000000..f9f4738 Binary files /dev/null and b/images/mech picts/owens.jpg differ diff --git a/images/mech picts/puma.jpg b/images/mech picts/puma.jpg new file mode 100644 index 0000000..141596f Binary files /dev/null and b/images/mech picts/puma.jpg differ diff --git a/images/mech picts/raven.jpg b/images/mech picts/raven.jpg new file mode 100644 index 0000000..3f41800 Binary files /dev/null and b/images/mech picts/raven.jpg differ diff --git a/images/mech picts/ryoken.jpg b/images/mech picts/ryoken.jpg new file mode 100644 index 0000000..3915b0e Binary files /dev/null and b/images/mech picts/ryoken.jpg differ diff --git a/images/mech picts/shadowcat.jpg b/images/mech picts/shadowcat.jpg new file mode 100644 index 0000000..4c2568b Binary files /dev/null and b/images/mech picts/shadowcat.jpg differ diff --git a/images/mech picts/templar.jpg b/images/mech picts/templar.jpg new file mode 100644 index 0000000..062632c Binary files /dev/null and b/images/mech picts/templar.jpg differ diff --git a/images/mech picts/thanatos.jpg b/images/mech picts/thanatos.jpg new file mode 100644 index 0000000..c5ce91e Binary files /dev/null and b/images/mech picts/thanatos.jpg differ diff --git a/images/mech picts/thor.jpg b/images/mech picts/thor.jpg new file mode 100644 index 0000000..80f2ecc Binary files /dev/null and b/images/mech picts/thor.jpg differ diff --git a/images/mech picts/uller.jpg b/images/mech picts/uller.jpg new file mode 100644 index 0000000..672e894 Binary files /dev/null and b/images/mech picts/uller.jpg differ diff --git a/images/mech picts/uziel.jpg b/images/mech picts/uziel.jpg new file mode 100644 index 0000000..f8c65ce Binary files /dev/null and b/images/mech picts/uziel.jpg differ diff --git a/images/mech picts/vulture.jpg b/images/mech picts/vulture.jpg new file mode 100644 index 0000000..e4fe0e5 Binary files /dev/null and b/images/mech picts/vulture.jpg differ diff --git a/images/mech picts/wolfhound.jpg b/images/mech picts/wolfhound.jpg new file mode 100644 index 0000000..3885bc4 Binary files /dev/null and b/images/mech picts/wolfhound.jpg differ diff --git a/images/mech picts/zeus.jpg b/images/mech picts/zeus.jpg new file mode 100644 index 0000000..f151418 Binary files /dev/null and b/images/mech picts/zeus.jpg differ diff --git a/images/mech.gif b/images/mech.gif new file mode 100644 index 0000000..86e346b Binary files /dev/null and b/images/mech.gif differ diff --git a/images/mr-block.gif b/images/mr-block.gif new file mode 100644 index 0000000..048d397 Binary files /dev/null and b/images/mr-block.gif differ diff --git a/images/mr.gif b/images/mr.gif new file mode 100644 index 0000000..2302cd1 Binary files /dev/null and b/images/mr.gif differ diff --git a/images/submit.gif b/images/submit.gif new file mode 100644 index 0000000..5f85469 Binary files /dev/null and b/images/submit.gif differ diff --git a/images/weight.gif b/images/weight.gif new file mode 100644 index 0000000..f10422a Binary files /dev/null and b/images/weight.gif differ diff --git a/images/who.gif b/images/who.gif new file mode 100644 index 0000000..198d359 Binary files /dev/null and b/images/who.gif differ diff --git a/includes/api.php b/includes/api.php new file mode 100644 index 0000000..8bcc58f --- /dev/null +++ b/includes/api.php @@ -0,0 +1,38 @@ +wcall = $wcall
"; + switch ($wcall) { + case "updatemerc": + echo "DEBUG: updatemerc is called
"; + $wdo = ""; + if (isset($_GET['wdo'])) $wdo = $_GET['wdo']; + switch ($wdo) { + case "add": + echo "DEBUG: updatemerc add is called
"; + $sql = "UPDATE pqs_queue SET merc = 1 WHERE id = $_GET[playerid]"; + echo "sql:
$sql
"; + mysqli_query($dbconnect, $sql) or die('Update Merc status failed: ' . mysqli_error($dbconnect)); + break; + case "remove": + echo "DEBUG: updatemerc remove is called
"; + $sql = "UPDATE pqs_queue SET merc = 0 WHERE id = $_GET[playerid]"; + echo "sql:
$sql
"; + mysqli_query($dbconnect, $sql) or die('Update Merc status failed: ' . mysqli_error($dbconnect)); + break; + } + break; + case "updateinfo": + $sql = "SELECT Updated FROM pqs_infopanel"; + $getid = mysqli_query($dbconnect, $sql) or die('Query failed: ' . mysqli_error($dbconnect)); + $rs1 = mysqli_fetch_array($getid); + $updateinfo = $rs1[0]; + mysqli_query($dbconnect, $sql) or die('Query failed: ' . mysqli_error($dbconnect)); + echo json_encode($updateinfo); + break; + } +} +mysqli_close($dbconnect); +?> \ No newline at end of file diff --git a/includes/config.php b/includes/config.php new file mode 100644 index 0000000..e07aa66 --- /dev/null +++ b/includes/config.php @@ -0,0 +1,54 @@ + \ No newline at end of file diff --git a/includes/getconsole.php b/includes/getconsole.php new file mode 100644 index 0000000..f34cfaa --- /dev/null +++ b/includes/getconsole.php @@ -0,0 +1,80 @@ +"; +echo "Next Mission (#$missionid)"; +echo "ETD: $etd"; +echo " CallsignMech"; +while ($line = mysqli_fetch_array($result)) { + if ($queuecount < $numplayers) { + $queuecount++; + if ($line[5] == 1) { + echo "$queuecount)$line[0]$line[1]***"; + } else { + echo "$queuecount)$line[0]$line[1] "; + } + } +} +if ($queuecount == 0) { + echo "No players currently in the queue!"; +} else if ($queuecount == $missionsize) { + echo " "; + echo "Mission is FULL!"; +} else if ($queuecount > $missionsize) { + echo " "; + echo "DANGER Containment Bay OVERLOADED!"; +} +if ($locked == 1) { + echo " "; + echo "This mission is CLOSED to new players!"; +} +echo ""; +mysqli_close($link); +?> \ No newline at end of file diff --git a/includes/getcurrent.php b/includes/getcurrent.php new file mode 100644 index 0000000..e72a234 --- /dev/null +++ b/includes/getcurrent.php @@ -0,0 +1,38 @@ +"; +echo "Current Mission (#$missionid)"; +$queuecount = 0; + +echo ""; +while ($line = mysqli_fetch_array($result)) { + echo "$line[0]"; + $queuecount++; + if(($queuecount==2)||($queuecount==4)||($queuecount==6)||($queuecount==8)||($queuecount==10)||($queuecount==12)||($queuecount==14)){echo"";} +} +echo""; +if ($queuecount == 0) { + echo "No players currently in pods!"; +} +echo ""; +mysqli_free_result($result); +mysqli_close($link); +?> diff --git a/includes/getgroup.php b/includes/getgroup.php new file mode 100644 index 0000000..45da8c6 --- /dev/null +++ b/includes/getgroup.php @@ -0,0 +1,69 @@ +"; +echo "Mission #$groupname ETD: $etd"; +while ($line = mysqli_fetch_array($result)) { + if ($line[3] == $missionid) { + echo "$line[0]"; + $queuecount++; + } +} +if ($queuecount == 0) { + echo "No players currently in the queue!"; +} +$sql = "SELECT locked, MissionSize, numplayers FROM pqs_mission WHERE MissionId=$missionid"; +$getid = mysqli_query($link, $sql) or die('Query failed getting locked status: ' . mysqli_error($link)); +$rs1 = mysqli_fetch_array($getid); +$locked = $rs1[0]; +$mz = $rs1[1]; +$np = $rs1[2]; + +if (($np >= $mz)&&($np != 0)) { +// echo " "; + echo "Mission FULL"; +} + +if ($locked == 1) { +// echo " "; + echo "CLOSED to new players!"; +} +echo ""; +mysqli_free_result($result); +mysqli_close($link); +?> diff --git a/includes/getqueue.php b/includes/getqueue.php new file mode 100644 index 0000000..d4df9fb --- /dev/null +++ b/includes/getqueue.php @@ -0,0 +1,73 @@ +"; +echo "Next Mission (#$missionid) ETD: $etd"; +//echo " CallsignMech"; +while ($line = mysqli_fetch_array($result)) { + if ($queuecount < $numplayers) { + $queuecount++; +// echo "$queuecount) $line[0]$line[1]"; + echo "$line[0]$line[1]"; + } +} +if ($queuecount == 0) { + echo "No players currently in the queue!"; +} else if ($queuecount >= $missionsize) { +// echo " "; + echo "Mission is FULL!"; +} +if ($locked == 1) { +// echo " "; + echo "Mission CLOSED to new players!"; +} +echo ""; +mysqli_close($link); +?> diff --git a/includes/getreg.php b/includes/getreg.php new file mode 100644 index 0000000..b922728 --- /dev/null +++ b/includes/getreg.php @@ -0,0 +1,173 @@ + +"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +while ($line = mysqli_fetch_array($result)) { + if ($queuecount < $numplayers) { + $queuecount++; + $callsign=str_replace("'", "'", $line[0]); + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } +} + +if ($queuecount == 0) { + echo ""; +} else if ($queuecount == $missionsize) { + echo ""; + echo ""; +} else if ($queuecount > $missionsize) { + echo ""; + echo ""; +} +if ($locked == 1) { + echo ""; + echo ""; +} + +echo ""; +echo ""; +echo "
Mission #$missionid
Game : $TypeName  Map : $mapname  
  CallsignMechClassMerc
$queuecount)  "; + echo "  "; + echo "  "; + echo "$line[0]$line[1]$line[4]"; + if ($line[5] == 1) { echo ""; } else { echo ""; } + echo "
No players currently in the queue!
 
Mission is FULL!
 
DANGER Containment Bay OVERLOADED!
 
This mission is CLOSED to new players!
 
"; + +$sql = "SELECT MAX(missionid) FROM pqs_mission"; +$getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); +$rs = mysqli_fetch_array($getid); +$maxmissionid = $rs[0] + 1; + +$sql = "SELECT MIN(missionid) FROM pqs_queue"; +$getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); +$rs = mysqli_fetch_array($getid); +$nmissionid = $rs[0]; + +$query = "SELECT timepergame, timetoreset FROM pqs_gameconfig"; +$gettpg = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); +$rs1 = mysqli_fetch_array($gettpg); +$tpg = $rs1[0]+$rs1[1]; + + +$query = "SELECT max(MissionID), max(UNIX_TIMESTAMP(ctime)) FROM pqs_pastmissions"; +$getlct = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); +$rs2 = mysqli_fetch_array($getlct); +$lastCommitTime = $rs2[1];//-(6*60*60);// utc -H*mm*sc +if(is_null($lastCommitTime)){$lastCommitTime = time();}//-(6*60*60);} + + +$a=1; +$b=1; +if(!is_null($nmissionid)){ +while ($nmissionid < $maxmissionid){ + $sql = "SELECT numplayers, MissionSize FROM pqs_mission WHERE missionid = $nmissionid"; + $result = mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($result); + $nplayers = $rs[0]; + $zplayers = $rs[1]; + $mtd = $tpg * $b; + $d=strtotime("+$mtd Minutes",$lastCommitTime); + $etd = date("h:i", $d); + if ($nplayers == "") { + echo ""; + } else { + echo ""; + } + if($a==5){ + echo ""; + $a=0;} + $a++; + $b++; + $nmissionid++; + } +} +echo "
M#$nmissionid: Empty (0 players)M#$nmissionid:"; + if($nplayers>$zplayers){echo "";} + echo " $nplayers/$zplayers"; + if($zplayers > $nplayers){echo "";} + echo " $etd
"; +mysqli_free_result($result); +mysqli_close($link); +?> diff --git a/includes/graph.php b/includes/graph.php new file mode 100644 index 0000000..bb38c59 --- /dev/null +++ b/includes/graph.php @@ -0,0 +1,14 @@ + 0) +{ + $grad = imagecreatefrompng("../images/grad.png"); + $per2 = imagecopy($per, $grad, 1, 1, 0, 0, ($_GET['per'] * 3.23), 10); + imagerectangle($per, 0, 0, 324, 11, $border); +} +header("Content-type: image/png"); +imagepng($per, NULL, 5); +?> \ No newline at end of file diff --git a/includes/infopanel.php b/includes/infopanel.php new file mode 100644 index 0000000..f945735 --- /dev/null +++ b/includes/infopanel.php @@ -0,0 +1,21 @@ + + + + +"; +#echo "

"; +#echo "
FallOut Shelter pricing:

1 Mission: $5.00
6 Missions: $27.00
12 Missions: $50.00

We accept cash or credit!! Taxes included.
ALL SALES ARE FINAL!
"; +#echo "

FallOut Shelter pricing:

1 Mission: $5.00
6 Missions: $27.00
12 Missions: $50.00

We accept cash or credit!! Taxes included.
ALL SALES ARE FINAL!
"; +#echo "


Congratulations Pooka and Cyd!

Happy Anniversary!!!
"; +echo "


Welcome to Cougar CON!!!
"; +echo "
"; +?> diff --git a/includes/mechpods.php b/includes/mechpods.php new file mode 100644 index 0000000..ae4eafe --- /dev/null +++ b/includes/mechpods.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/includes/now.php b/includes/now.php new file mode 100644 index 0000000..d565f0e --- /dev/null +++ b/includes/now.php @@ -0,0 +1,31 @@ +"; +echo "Oficial Pod Bay Time:"; +echo ""; +echo date("h:i", time()); +echo ""; + +//echo " "; +echo ""; +echo "Current Mission ETR: "; +if($tramaining > 0){ +echo ""; echo date("i:s", $tramaining); echo""; +}else{ +echo "Awaiting Next Launch"; +} +?> diff --git a/includes/smallinfopanel.php b/includes/smallinfopanel.php new file mode 100644 index 0000000..03610ca --- /dev/null +++ b/includes/smallinfopanel.php @@ -0,0 +1,19 @@ + + + + +"; +#echo "

"; +#echo "

Fall Out Shelter pricing:

1 Mission: $5.00
6 Missions: $27.00
12 Missions: $50.00

We accept cash or credit!! Taxes included.
ALL SALES ARE FINAL!
"; +#echo "


Congratulations Pooka and Cyd!

Happy Anniversary!!!
"; +echo "
"; +?> \ No newline at end of file diff --git a/js/jquery.alphanumeric.js b/js/jquery.alphanumeric.js new file mode 100644 index 0000000..e2addf9 --- /dev/null +++ b/js/jquery.alphanumeric.js @@ -0,0 +1 @@ +eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(2($){$.c.f=2(p){p=$.d({g:"!@#$%^&*()+=[]\\\\\\\';,/{}|\\":<>?~`.- ",4:"",9:""},p);7 3.b(2(){5(p.G)p.4+="Q";5(p.w)p.4+="n";s=p.9.z(\'\');x(i=0;i= options.elements.length) { + log('invalid slide index: ' + num); + return false; + } + options.nextSlide = num; + if (cont.cycleTimeout) { + clearTimeout(cont.cycleTimeout); + cont.cycleTimeout = 0; + } + if (typeof arg2 == 'string') + options.oneTimeFx = arg2; + go(options.elements, options, 1, num >= options.currSlide); + return false; + } + return options; + + function checkInstantResume(isPaused, arg2, cont) { + if (!isPaused && arg2 === true) { // resume now! + var options = $(cont).data('cycle.opts'); + if (!options) { + log('options not found, can not resume'); + return false; + } + if (cont.cycleTimeout) { + clearTimeout(cont.cycleTimeout); + cont.cycleTimeout = 0; + } + go(options.elements, options, 1, !options.backwards); + } + } +} + +function removeFilter(el, opts) { + if (!$.support.opacity && opts.cleartype && el.style.filter) { + try { el.style.removeAttribute('filter'); } + catch(smother) {} // handle old opera versions + } +} + +// unbind event handlers +function destroy(cont, opts) { + if (opts.next) + $(opts.next).unbind(opts.prevNextEvent); + if (opts.prev) + $(opts.prev).unbind(opts.prevNextEvent); + + if (opts.pager || opts.pagerAnchorBuilder) + $.each(opts.pagerAnchors || [], function() { + this.unbind().remove(); + }); + opts.pagerAnchors = null; + $(cont).unbind('mouseenter.cycle mouseleave.cycle'); + if (opts.destroy) // callback + opts.destroy(opts); +} + +// one-time initialization +function buildOptions($cont, $slides, els, options, o) { + var startingSlideSpecified; + // support metadata plugin (v1.0 and v2.0) + var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {}); + var meta = $.isFunction($cont.data) ? $cont.data(opts.metaAttr) : null; + if (meta) + opts = $.extend(opts, meta); + if (opts.autostop) + opts.countdown = opts.autostopCount || els.length; + + var cont = $cont[0]; + $cont.data('cycle.opts', opts); + opts.$cont = $cont; + opts.stopCount = cont.cycleStop; + opts.elements = els; + opts.before = opts.before ? [opts.before] : []; + opts.after = opts.after ? [opts.after] : []; + + // push some after callbacks + if (!$.support.opacity && opts.cleartype) + opts.after.push(function() { removeFilter(this, opts); }); + if (opts.continuous) + opts.after.push(function() { go(els,opts,0,!opts.backwards); }); + + saveOriginalOpts(opts); + + // clearType corrections + if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg) + clearTypeFix($slides); + + // container requires non-static position so that slides can be position within + if ($cont.css('position') == 'static') + $cont.css('position', 'relative'); + if (opts.width) + $cont.width(opts.width); + if (opts.height && opts.height != 'auto') + $cont.height(opts.height); + + if (opts.startingSlide !== undefined) { + opts.startingSlide = parseInt(opts.startingSlide,10); + if (opts.startingSlide >= els.length || opts.startSlide < 0) + opts.startingSlide = 0; // catch bogus input + else + startingSlideSpecified = true; + } + else if (opts.backwards) + opts.startingSlide = els.length - 1; + else + opts.startingSlide = 0; + + // if random, mix up the slide array + if (opts.random) { + opts.randomMap = []; + for (var i = 0; i < els.length; i++) + opts.randomMap.push(i); + opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;}); + if (startingSlideSpecified) { + // try to find the specified starting slide and if found set start slide index in the map accordingly + for ( var cnt = 0; cnt < els.length; cnt++ ) { + if ( opts.startingSlide == opts.randomMap[cnt] ) { + opts.randomIndex = cnt; + } + } + } + else { + opts.randomIndex = 1; + opts.startingSlide = opts.randomMap[1]; + } + } + else if (opts.startingSlide >= els.length) + opts.startingSlide = 0; // catch bogus input + opts.currSlide = opts.startingSlide || 0; + var first = opts.startingSlide; + + // set position and zIndex on all the slides + $slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) { + var z; + if (opts.backwards) + z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i; + else + z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i; + $(this).css('z-index', z); + }); + + // make sure first slide is visible + $(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case + removeFilter(els[first], opts); + + // stretch slides + if (opts.fit) { + if (!opts.aspect) { + if (opts.width) + $slides.width(opts.width); + if (opts.height && opts.height != 'auto') + $slides.height(opts.height); + } else { + $slides.each(function(){ + var $slide = $(this); + var ratio = (opts.aspect === true) ? $slide.width()/$slide.height() : opts.aspect; + if( opts.width && $slide.width() != opts.width ) { + $slide.width( opts.width ); + $slide.height( opts.width / ratio ); + } + + if( opts.height && $slide.height() < opts.height ) { + $slide.height( opts.height ); + $slide.width( opts.height * ratio ); + } + }); + } + } + + if (opts.center && ((!opts.fit) || opts.aspect)) { + $slides.each(function(){ + var $slide = $(this); + $slide.css({ + "margin-left": opts.width ? + ((opts.width - $slide.width()) / 2) + "px" : + 0, + "margin-top": opts.height ? + ((opts.height - $slide.height()) / 2) + "px" : + 0 + }); + }); + } + + if (opts.center && !opts.fit && !opts.slideResize) { + $slides.each(function(){ + var $slide = $(this); + $slide.css({ + "margin-left": opts.width ? ((opts.width - $slide.width()) / 2) + "px" : 0, + "margin-top": opts.height ? ((opts.height - $slide.height()) / 2) + "px" : 0 + }); + }); + } + + // stretch container + var reshape = opts.containerResize && !$cont.innerHeight(); + if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9 + var maxw = 0, maxh = 0; + for(var j=0; j < els.length; j++) { + var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight(); + if (!w) w = e.offsetWidth || e.width || $e.attr('width'); + if (!h) h = e.offsetHeight || e.height || $e.attr('height'); + maxw = w > maxw ? w : maxw; + maxh = h > maxh ? h : maxh; + } + if (maxw > 0 && maxh > 0) + $cont.css({width:maxw+'px',height:maxh+'px'}); + } + + var pauseFlag = false; // https://github.com/malsup/cycle/issues/44 + if (opts.pause) + $cont.bind('mouseenter.cycle', function(){ + pauseFlag = true; + this.cyclePause++; + triggerPause(cont, true); + }).bind('mouseleave.cycle', function(){ + if (pauseFlag) + this.cyclePause--; + triggerPause(cont, true); + }); + + if (supportMultiTransitions(opts) === false) + return false; + + // apparently a lot of people use image slideshows without height/width attributes on the images. + // Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that. + var requeue = false; + options.requeueAttempts = options.requeueAttempts || 0; + $slides.each(function() { + // try to get height/width of each slide + var $el = $(this); + this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0); + this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0); + + if ( $el.is('img') ) { + // sigh.. sniffing, hacking, shrugging... this crappy hack tries to account for what browsers do when + // an image is being downloaded and the markup did not include sizing info (height/width attributes); + // there seems to be some "default" sizes used in this situation + var loadingIE = ($.browser.msie && this.cycleW == 28 && this.cycleH == 30 && !this.complete); + var loadingFF = ($.browser.mozilla && this.cycleW == 34 && this.cycleH == 19 && !this.complete); + var loadingOp = ($.browser.opera && ((this.cycleW == 42 && this.cycleH == 19) || (this.cycleW == 37 && this.cycleH == 17)) && !this.complete); + var loadingOther = (this.cycleH === 0 && this.cycleW === 0 && !this.complete); + // don't requeue for images that are still loading but have a valid size + if (loadingIE || loadingFF || loadingOp || loadingOther) { + if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever + log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH); + setTimeout(function() {$(o.s,o.c).cycle(options);}, opts.requeueTimeout); + requeue = true; + return false; // break each loop + } + else { + log('could not determine size of image: '+this.src, this.cycleW, this.cycleH); + } + } + } + return true; + }); + + if (requeue) + return false; + + opts.cssBefore = opts.cssBefore || {}; + opts.cssAfter = opts.cssAfter || {}; + opts.cssFirst = opts.cssFirst || {}; + opts.animIn = opts.animIn || {}; + opts.animOut = opts.animOut || {}; + + $slides.not(':eq('+first+')').css(opts.cssBefore); + $($slides[first]).css(opts.cssFirst); + + if (opts.timeout) { + opts.timeout = parseInt(opts.timeout,10); + // ensure that timeout and speed settings are sane + if (opts.speed.constructor == String) + opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10); + if (!opts.sync) + opts.speed = opts.speed / 2; + + var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250; + while((opts.timeout - opts.speed) < buffer) // sanitize timeout + opts.timeout += opts.speed; + } + if (opts.easing) + opts.easeIn = opts.easeOut = opts.easing; + if (!opts.speedIn) + opts.speedIn = opts.speed; + if (!opts.speedOut) + opts.speedOut = opts.speed; + + opts.slideCount = els.length; + opts.currSlide = opts.lastSlide = first; + if (opts.random) { + if (++opts.randomIndex == els.length) + opts.randomIndex = 0; + opts.nextSlide = opts.randomMap[opts.randomIndex]; + } + else if (opts.backwards) + opts.nextSlide = opts.startingSlide === 0 ? (els.length-1) : opts.startingSlide-1; + else + opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1; + + // run transition init fn + if (!opts.multiFx) { + var init = $.fn.cycle.transitions[opts.fx]; + if ($.isFunction(init)) + init($cont, $slides, opts); + else if (opts.fx != 'custom' && !opts.multiFx) { + log('unknown transition: ' + opts.fx,'; slideshow terminating'); + return false; + } + } + + // fire artificial events + var e0 = $slides[first]; + if (!opts.skipInitializationCallbacks) { + if (opts.before.length) + opts.before[0].apply(e0, [e0, e0, opts, true]); + if (opts.after.length) + opts.after[0].apply(e0, [e0, e0, opts, true]); + } + if (opts.next) + $(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,1);}); + if (opts.prev) + $(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,0);}); + if (opts.pager || opts.pagerAnchorBuilder) + buildPager(els,opts); + + exposeAddSlide(opts, els); + + return opts; +} + +// save off original opts so we can restore after clearing state +function saveOriginalOpts(opts) { + opts.original = { before: [], after: [] }; + opts.original.cssBefore = $.extend({}, opts.cssBefore); + opts.original.cssAfter = $.extend({}, opts.cssAfter); + opts.original.animIn = $.extend({}, opts.animIn); + opts.original.animOut = $.extend({}, opts.animOut); + $.each(opts.before, function() { opts.original.before.push(this); }); + $.each(opts.after, function() { opts.original.after.push(this); }); +} + +function supportMultiTransitions(opts) { + var i, tx, txs = $.fn.cycle.transitions; + // look for multiple effects + if (opts.fx.indexOf(',') > 0) { + opts.multiFx = true; + opts.fxs = opts.fx.replace(/\s*/g,'').split(','); + // discard any bogus effect names + for (i=0; i < opts.fxs.length; i++) { + var fx = opts.fxs[i]; + tx = txs[fx]; + if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) { + log('discarding unknown transition: ',fx); + opts.fxs.splice(i,1); + i--; + } + } + // if we have an empty list then we threw everything away! + if (!opts.fxs.length) { + log('No valid transitions named; slideshow terminating.'); + return false; + } + } + else if (opts.fx == 'all') { // auto-gen the list of transitions + opts.multiFx = true; + opts.fxs = []; + for (var p in txs) { + if (txs.hasOwnProperty(p)) { + tx = txs[p]; + if (txs.hasOwnProperty(p) && $.isFunction(tx)) + opts.fxs.push(p); + } + } + } + if (opts.multiFx && opts.randomizeEffects) { + // munge the fxs array to make effect selection random + var r1 = Math.floor(Math.random() * 20) + 30; + for (i = 0; i < r1; i++) { + var r2 = Math.floor(Math.random() * opts.fxs.length); + opts.fxs.push(opts.fxs.splice(r2,1)[0]); + } + debug('randomized fx sequence: ',opts.fxs); + } + return true; +} + +// provide a mechanism for adding slides after the slideshow has started +function exposeAddSlide(opts, els) { + opts.addSlide = function(newSlide, prepend) { + var $s = $(newSlide), s = $s[0]; + if (!opts.autostopCount) + opts.countdown++; + els[prepend?'unshift':'push'](s); + if (opts.els) + opts.els[prepend?'unshift':'push'](s); // shuffle needs this + opts.slideCount = els.length; + + // add the slide to the random map and resort + if (opts.random) { + opts.randomMap.push(opts.slideCount-1); + opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;}); + } + + $s.css('position','absolute'); + $s[prepend?'prependTo':'appendTo'](opts.$cont); + + if (prepend) { + opts.currSlide++; + opts.nextSlide++; + } + + if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg) + clearTypeFix($s); + + if (opts.fit && opts.width) + $s.width(opts.width); + if (opts.fit && opts.height && opts.height != 'auto') + $s.height(opts.height); + s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height(); + s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width(); + + $s.css(opts.cssBefore); + + if (opts.pager || opts.pagerAnchorBuilder) + $.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts); + + if ($.isFunction(opts.onAddSlide)) + opts.onAddSlide($s); + else + $s.hide(); // default behavior + }; +} + +// reset internal state; we do this on every pass in order to support multiple effects +$.fn.cycle.resetState = function(opts, fx) { + fx = fx || opts.fx; + opts.before = []; opts.after = []; + opts.cssBefore = $.extend({}, opts.original.cssBefore); + opts.cssAfter = $.extend({}, opts.original.cssAfter); + opts.animIn = $.extend({}, opts.original.animIn); + opts.animOut = $.extend({}, opts.original.animOut); + opts.fxFn = null; + $.each(opts.original.before, function() { opts.before.push(this); }); + $.each(opts.original.after, function() { opts.after.push(this); }); + + // re-init + var init = $.fn.cycle.transitions[fx]; + if ($.isFunction(init)) + init(opts.$cont, $(opts.elements), opts); +}; + +// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt +function go(els, opts, manual, fwd) { + var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide]; + + // opts.busy is true if we're in the middle of an animation + if (manual && opts.busy && opts.manualTrump) { + // let manual transitions requests trump active ones + debug('manualTrump in go(), stopping active transition'); + $(els).stop(true,true); + opts.busy = 0; + clearTimeout(p.cycleTimeout); + } + + // don't begin another timeout-based transition if there is one active + if (opts.busy) { + debug('transition active, ignoring new tx request'); + return; + } + + + // stop cycling if we have an outstanding stop request + if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual) + return; + + // check to see if we should stop cycling based on autostop options + if (!manual && !p.cyclePause && !opts.bounce && + ((opts.autostop && (--opts.countdown <= 0)) || + (opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) { + if (opts.end) + opts.end(opts); + return; + } + + // if slideshow is paused, only transition on a manual trigger + var changed = false; + if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) { + changed = true; + var fx = opts.fx; + // keep trying to get the slide size if we don't have it yet + curr.cycleH = curr.cycleH || $(curr).height(); + curr.cycleW = curr.cycleW || $(curr).width(); + next.cycleH = next.cycleH || $(next).height(); + next.cycleW = next.cycleW || $(next).width(); + + // support multiple transition types + if (opts.multiFx) { + if (fwd && (opts.lastFx === undefined || ++opts.lastFx >= opts.fxs.length)) + opts.lastFx = 0; + else if (!fwd && (opts.lastFx === undefined || --opts.lastFx < 0)) + opts.lastFx = opts.fxs.length - 1; + fx = opts.fxs[opts.lastFx]; + } + + // one-time fx overrides apply to: $('div').cycle(3,'zoom'); + if (opts.oneTimeFx) { + fx = opts.oneTimeFx; + opts.oneTimeFx = null; + } + + $.fn.cycle.resetState(opts, fx); + + // run the before callbacks + if (opts.before.length) + $.each(opts.before, function(i,o) { + if (p.cycleStop != opts.stopCount) return; + o.apply(next, [curr, next, opts, fwd]); + }); + + // stage the after callacks + var after = function() { + opts.busy = 0; + $.each(opts.after, function(i,o) { + if (p.cycleStop != opts.stopCount) return; + o.apply(next, [curr, next, opts, fwd]); + }); + if (!p.cycleStop) { + // queue next transition + queueNext(); + } + }; + + debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide); + + // get ready to perform the transition + opts.busy = 1; + if (opts.fxFn) // fx function provided? + opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent); + else if ($.isFunction($.fn.cycle[opts.fx])) // fx plugin ? + $.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent); + else + $.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent); + } + else { + queueNext(); + } + + if (changed || opts.nextSlide == opts.currSlide) { + // calculate the next slide + var roll; + opts.lastSlide = opts.currSlide; + if (opts.random) { + opts.currSlide = opts.nextSlide; + if (++opts.randomIndex == els.length) { + opts.randomIndex = 0; + opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;}); + } + opts.nextSlide = opts.randomMap[opts.randomIndex]; + if (opts.nextSlide == opts.currSlide) + opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1; + } + else if (opts.backwards) { + roll = (opts.nextSlide - 1) < 0; + if (roll && opts.bounce) { + opts.backwards = !opts.backwards; + opts.nextSlide = 1; + opts.currSlide = 0; + } + else { + opts.nextSlide = roll ? (els.length-1) : opts.nextSlide-1; + opts.currSlide = roll ? 0 : opts.nextSlide+1; + } + } + else { // sequence + roll = (opts.nextSlide + 1) == els.length; + if (roll && opts.bounce) { + opts.backwards = !opts.backwards; + opts.nextSlide = els.length-2; + opts.currSlide = els.length-1; + } + else { + opts.nextSlide = roll ? 0 : opts.nextSlide+1; + opts.currSlide = roll ? els.length-1 : opts.nextSlide-1; + } + } + } + if (changed && opts.pager) + opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass); + + function queueNext() { + // stage the next transition + var ms = 0, timeout = opts.timeout; + if (opts.timeout && !opts.continuous) { + ms = getTimeout(els[opts.currSlide], els[opts.nextSlide], opts, fwd); + if (opts.fx == 'shuffle') + ms -= opts.speedOut; + } + else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic + ms = 10; + if (ms > 0) + p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.backwards); }, ms); + } +} + +// invoked after transition +$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) { + $(pager).each(function() { + $(this).children().removeClass(clsName).eq(currSlide).addClass(clsName); + }); +}; + +// calculate timeout value for current transition +function getTimeout(curr, next, opts, fwd) { + if (opts.timeoutFn) { + // call user provided calc fn + var t = opts.timeoutFn.call(curr,curr,next,opts,fwd); + while (opts.fx != 'none' && (t - opts.speed) < 250) // sanitize timeout + t += opts.speed; + debug('calculated timeout: ' + t + '; speed: ' + opts.speed); + if (t !== false) + return t; + } + return opts.timeout; +} + +// expose next/prev function, caller must pass in state +$.fn.cycle.next = function(opts) { advance(opts,1); }; +$.fn.cycle.prev = function(opts) { advance(opts,0);}; + +// advance slide forward or back +function advance(opts, moveForward) { + var val = moveForward ? 1 : -1; + var els = opts.elements; + var p = opts.$cont[0], timeout = p.cycleTimeout; + if (timeout) { + clearTimeout(timeout); + p.cycleTimeout = 0; + } + if (opts.random && val < 0) { + // move back to the previously display slide + opts.randomIndex--; + if (--opts.randomIndex == -2) + opts.randomIndex = els.length-2; + else if (opts.randomIndex == -1) + opts.randomIndex = els.length-1; + opts.nextSlide = opts.randomMap[opts.randomIndex]; + } + else if (opts.random) { + opts.nextSlide = opts.randomMap[opts.randomIndex]; + } + else { + opts.nextSlide = opts.currSlide + val; + if (opts.nextSlide < 0) { + if (opts.nowrap) return false; + opts.nextSlide = els.length - 1; + } + else if (opts.nextSlide >= els.length) { + if (opts.nowrap) return false; + opts.nextSlide = 0; + } + } + + var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated + if ($.isFunction(cb)) + cb(val > 0, opts.nextSlide, els[opts.nextSlide]); + go(els, opts, 1, moveForward); + return false; +} + +function buildPager(els, opts) { + var $p = $(opts.pager); + $.each(els, function(i,o) { + $.fn.cycle.createPagerAnchor(i,o,$p,els,opts); + }); + opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass); +} + +$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) { + var a; + if ($.isFunction(opts.pagerAnchorBuilder)) { + a = opts.pagerAnchorBuilder(i,el); + debug('pagerAnchorBuilder('+i+', el) returned: ' + a); + } + else + a = ''+(i+1)+''; + + if (!a) + return; + var $a = $(a); + // don't reparent if anchor is in the dom + if ($a.parents('body').length === 0) { + var arr = []; + if ($p.length > 1) { + $p.each(function() { + var $clone = $a.clone(true); + $(this).append($clone); + arr.push($clone[0]); + }); + $a = $(arr); + } + else { + $a.appendTo($p); + } + } + + opts.pagerAnchors = opts.pagerAnchors || []; + opts.pagerAnchors.push($a); + + var pagerFn = function(e) { + e.preventDefault(); + opts.nextSlide = i; + var p = opts.$cont[0], timeout = p.cycleTimeout; + if (timeout) { + clearTimeout(timeout); + p.cycleTimeout = 0; + } + var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated + if ($.isFunction(cb)) + cb(opts.nextSlide, els[opts.nextSlide]); + go(els,opts,1,opts.currSlide < i); // trigger the trans +// return false; // <== allow bubble + }; + + if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) { + $a.hover(pagerFn, function(){/* no-op */} ); + } + else { + $a.bind(opts.pagerEvent, pagerFn); + } + + if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble) + $a.bind('click.cycle', function(){return false;}); // suppress click + + var cont = opts.$cont[0]; + var pauseFlag = false; // https://github.com/malsup/cycle/issues/44 + if (opts.pauseOnPagerHover) { + $a.hover( + function() { + pauseFlag = true; + cont.cyclePause++; + triggerPause(cont,true,true); + }, function() { + if (pauseFlag) + cont.cyclePause--; + triggerPause(cont,true,true); + } + ); + } +}; + +// helper fn to calculate the number of slides between the current and the next +$.fn.cycle.hopsFromLast = function(opts, fwd) { + var hops, l = opts.lastSlide, c = opts.currSlide; + if (fwd) + hops = c > l ? c - l : opts.slideCount - l; + else + hops = c < l ? l - c : l + opts.slideCount - c; + return hops; +}; + +// fix clearType problems in ie6 by setting an explicit bg color +// (otherwise text slides look horrible during a fade transition) +function clearTypeFix($slides) { + debug('applying clearType background-color hack'); + function hex(s) { + s = parseInt(s,10).toString(16); + return s.length < 2 ? '0'+s : s; + } + function getBg(e) { + for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) { + var v = $.css(e,'background-color'); + if (v && v.indexOf('rgb') >= 0 ) { + var rgb = v.match(/\d+/g); + return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]); + } + if (v && v != 'transparent') + return v; + } + return '#ffffff'; + } + $slides.each(function() { $(this).css('background-color', getBg(this)); }); +} + +// reset common props before the next transition +$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) { + $(opts.elements).not(curr).hide(); + if (typeof opts.cssBefore.opacity == 'undefined') + opts.cssBefore.opacity = 1; + opts.cssBefore.display = 'block'; + if (opts.slideResize && w !== false && next.cycleW > 0) + opts.cssBefore.width = next.cycleW; + if (opts.slideResize && h !== false && next.cycleH > 0) + opts.cssBefore.height = next.cycleH; + opts.cssAfter = opts.cssAfter || {}; + opts.cssAfter.display = 'none'; + $(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0)); + $(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1)); +}; + +// the actual fn for effecting a transition +$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) { + var $l = $(curr), $n = $(next); + var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut; + $n.css(opts.cssBefore); + if (speedOverride) { + if (typeof speedOverride == 'number') + speedIn = speedOut = speedOverride; + else + speedIn = speedOut = 1; + easeIn = easeOut = null; + } + var fn = function() { + $n.animate(opts.animIn, speedIn, easeIn, function() { + cb(); + }); + }; + $l.animate(opts.animOut, speedOut, easeOut, function() { + $l.css(opts.cssAfter); + if (!opts.sync) + fn(); + }); + if (opts.sync) fn(); +}; + +// transition definitions - only fade is defined here, transition pack defines the rest +$.fn.cycle.transitions = { + fade: function($cont, $slides, opts) { + $slides.not(':eq('+opts.currSlide+')').css('opacity',0); + opts.before.push(function(curr,next,opts) { + $.fn.cycle.commonReset(curr,next,opts); + opts.cssBefore.opacity = 0; + }); + opts.animIn = { opacity: 1 }; + opts.animOut = { opacity: 0 }; + opts.cssBefore = { top: 0, left: 0 }; + } +}; + +$.fn.cycle.ver = function() { return ver; }; + +// override these globally if you like (they are all optional) +$.fn.cycle.defaults = { + activePagerClass: 'activeSlide', // class name used for the active pager link + after: null, // transition callback (scope set to element that was shown): function(currSlideElement, nextSlideElement, options, forwardFlag) + allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling + animIn: null, // properties that define how the slide animates in + animOut: null, // properties that define how the slide animates out + aspect: false, // preserve aspect ratio during fit resizing, cropping if necessary (must be used with fit option) + autostop: 0, // true to end slideshow after X transitions (where X == slide count) + autostopCount: 0, // number of transitions (optionally used with autostop to define X) + backwards: false, // true to start slideshow at last slide and move backwards through the stack + before: null, // transition callback (scope set to element to be shown): function(currSlideElement, nextSlideElement, options, forwardFlag) + center: null, // set to true to have cycle add top/left margin to each slide (use with width and height options) + cleartype: !$.support.opacity, // true if clearType corrections should be applied (for IE) + cleartypeNoBg: false, // set to true to disable extra cleartype fixing (leave false to force background color setting on slides) + containerResize: 1, // resize container to fit largest slide + continuous: 0, // true to start next transition immediately after current one completes + cssAfter: null, // properties that defined the state of the slide after transitioning out + cssBefore: null, // properties that define the initial state of the slide before transitioning in + delay: 0, // additional delay (in ms) for first transition (hint: can be negative) + easeIn: null, // easing for "in" transition + easeOut: null, // easing for "out" transition + easing: null, // easing method for both in and out transitions + end: null, // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options) + fastOnEvent: 0, // force fast transitions when triggered manually (via pager or prev/next); value == time in ms + fit: 0, // force slides to fit container + fx: 'fade', // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle') + fxFn: null, // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag) + height: 'auto', // container height (if the 'fit' option is true, the slides will be set to this height as well) + manualTrump: true, // causes manual transition to stop an active transition instead of being ignored + metaAttr: 'cycle', // data- attribute that holds the option data for the slideshow + next: null, // element, jQuery object, or jQuery selector string for the element to use as event trigger for next slide + nowrap: 0, // true to prevent slideshow from wrapping + onPagerEvent: null, // callback fn for pager events: function(zeroBasedSlideIndex, slideElement) + onPrevNextEvent: null, // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement) + pager: null, // element, jQuery object, or jQuery selector string for the element to use as pager container + pagerAnchorBuilder: null, // callback fn for building anchor links: function(index, DOMelement) + pagerEvent: 'click.cycle', // name of event which drives the pager navigation + pause: 0, // true to enable "pause on hover" + pauseOnPagerHover: 0, // true to pause when hovering over pager link + prev: null, // element, jQuery object, or jQuery selector string for the element to use as event trigger for previous slide + prevNextEvent: 'click.cycle',// event which drives the manual transition to the previous or next slide + random: 0, // true for random, false for sequence (not applicable to shuffle fx) + randomizeEffects: 1, // valid when multiple effects are used; true to make the effect sequence random + requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded + requeueTimeout: 250, // ms delay for requeue + rev: 0, // causes animations to transition in reverse (for effects that support it such as scrollHorz/scrollVert/shuffle) + shuffle: null, // coords for shuffle animation, ex: { top:15, left: 200 } + skipInitializationCallbacks: false, // set to true to disable the first before/after callback that occurs prior to any transition + slideExpr: null, // expression for selecting slides (if something other than all children is required) + slideResize: 1, // force slide width/height to fixed size before every transition + speed: 1000, // speed of the transition (any valid fx speed value) + speedIn: null, // speed of the 'in' transition + speedOut: null, // speed of the 'out' transition + startingSlide: undefined,// zero-based index of the first slide to be displayed + sync: 1, // true if in/out transitions should occur simultaneously + timeout: 4000, // milliseconds between slide transitions (0 to disable auto advance) + timeoutFn: null, // callback for determining per-slide timeout value: function(currSlideElement, nextSlideElement, options, forwardFlag) + updateActivePagerLink: null,// callback fn invoked to update the active pager link (adds/removes activePagerClass style) + width: null // container width (if the 'fit' option is true, the slides will be set to this width as well) +}; + +})(jQuery); + + +/*! + * jQuery Cycle Plugin Transition Definitions + * This script is a plugin for the jQuery Cycle Plugin + * Examples and documentation at: http://malsup.com/jquery/cycle/ + * Copyright (c) 2007-2010 M. Alsup + * Version: 2.73 + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function($) { +"use strict"; + +// +// These functions define slide initialization and properties for the named +// transitions. To save file size feel free to remove any of these that you +// don't need. +// +$.fn.cycle.transitions.none = function($cont, $slides, opts) { + opts.fxFn = function(curr,next,opts,after){ + $(next).show(); + $(curr).hide(); + after(); + }; +}; + +// not a cross-fade, fadeout only fades out the top slide +$.fn.cycle.transitions.fadeout = function($cont, $slides, opts) { + $slides.not(':eq('+opts.currSlide+')').css({ display: 'block', 'opacity': 1 }); + opts.before.push(function(curr,next,opts,w,h,rev) { + $(curr).css('zIndex',opts.slideCount + (rev !== true ? 1 : 0)); + $(next).css('zIndex',opts.slideCount + (rev !== true ? 0 : 1)); + }); + opts.animIn.opacity = 1; + opts.animOut.opacity = 0; + opts.cssBefore.opacity = 1; + opts.cssBefore.display = 'block'; + opts.cssAfter.zIndex = 0; +}; + +// scrollUp/Down/Left/Right +$.fn.cycle.transitions.scrollUp = function($cont, $slides, opts) { + $cont.css('overflow','hidden'); + opts.before.push($.fn.cycle.commonReset); + var h = $cont.height(); + opts.cssBefore.top = h; + opts.cssBefore.left = 0; + opts.cssFirst.top = 0; + opts.animIn.top = 0; + opts.animOut.top = -h; +}; +$.fn.cycle.transitions.scrollDown = function($cont, $slides, opts) { + $cont.css('overflow','hidden'); + opts.before.push($.fn.cycle.commonReset); + var h = $cont.height(); + opts.cssFirst.top = 0; + opts.cssBefore.top = -h; + opts.cssBefore.left = 0; + opts.animIn.top = 0; + opts.animOut.top = h; +}; +$.fn.cycle.transitions.scrollLeft = function($cont, $slides, opts) { + $cont.css('overflow','hidden'); + opts.before.push($.fn.cycle.commonReset); + var w = $cont.width(); + opts.cssFirst.left = 0; + opts.cssBefore.left = w; + opts.cssBefore.top = 0; + opts.animIn.left = 0; + opts.animOut.left = 0-w; +}; +$.fn.cycle.transitions.scrollRight = function($cont, $slides, opts) { + $cont.css('overflow','hidden'); + opts.before.push($.fn.cycle.commonReset); + var w = $cont.width(); + opts.cssFirst.left = 0; + opts.cssBefore.left = -w; + opts.cssBefore.top = 0; + opts.animIn.left = 0; + opts.animOut.left = w; +}; +$.fn.cycle.transitions.scrollHorz = function($cont, $slides, opts) { + $cont.css('overflow','hidden').width(); + opts.before.push(function(curr, next, opts, fwd) { + if (opts.rev) + fwd = !fwd; + $.fn.cycle.commonReset(curr,next,opts); + opts.cssBefore.left = fwd ? (next.cycleW-1) : (1-next.cycleW); + opts.animOut.left = fwd ? -curr.cycleW : curr.cycleW; + }); + opts.cssFirst.left = 0; + opts.cssBefore.top = 0; + opts.animIn.left = 0; + opts.animOut.top = 0; +}; +$.fn.cycle.transitions.scrollVert = function($cont, $slides, opts) { + $cont.css('overflow','hidden'); + opts.before.push(function(curr, next, opts, fwd) { + if (opts.rev) + fwd = !fwd; + $.fn.cycle.commonReset(curr,next,opts); + opts.cssBefore.top = fwd ? (1-next.cycleH) : (next.cycleH-1); + opts.animOut.top = fwd ? curr.cycleH : -curr.cycleH; + }); + opts.cssFirst.top = 0; + opts.cssBefore.left = 0; + opts.animIn.top = 0; + opts.animOut.left = 0; +}; + +// slideX/slideY +$.fn.cycle.transitions.slideX = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $(opts.elements).not(curr).hide(); + $.fn.cycle.commonReset(curr,next,opts,false,true); + opts.animIn.width = next.cycleW; + }); + opts.cssBefore.left = 0; + opts.cssBefore.top = 0; + opts.cssBefore.width = 0; + opts.animIn.width = 'show'; + opts.animOut.width = 0; +}; +$.fn.cycle.transitions.slideY = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $(opts.elements).not(curr).hide(); + $.fn.cycle.commonReset(curr,next,opts,true,false); + opts.animIn.height = next.cycleH; + }); + opts.cssBefore.left = 0; + opts.cssBefore.top = 0; + opts.cssBefore.height = 0; + opts.animIn.height = 'show'; + opts.animOut.height = 0; +}; + +// shuffle +$.fn.cycle.transitions.shuffle = function($cont, $slides, opts) { + var i, w = $cont.css('overflow', 'visible').width(); + $slides.css({left: 0, top: 0}); + opts.before.push(function(curr,next,opts) { + $.fn.cycle.commonReset(curr,next,opts,true,true,true); + }); + // only adjust speed once! + if (!opts.speedAdjusted) { + opts.speed = opts.speed / 2; // shuffle has 2 transitions + opts.speedAdjusted = true; + } + opts.random = 0; + opts.shuffle = opts.shuffle || {left:-w, top:15}; + opts.els = []; + for (i=0; i < $slides.length; i++) + opts.els.push($slides[i]); + + for (i=0; i < opts.currSlide; i++) + opts.els.push(opts.els.shift()); + + // custom transition fn (hat tip to Benjamin Sterling for this bit of sweetness!) + opts.fxFn = function(curr, next, opts, cb, fwd) { + if (opts.rev) + fwd = !fwd; + var $el = fwd ? $(curr) : $(next); + $(next).css(opts.cssBefore); + var count = opts.slideCount; + $el.animate(opts.shuffle, opts.speedIn, opts.easeIn, function() { + var hops = $.fn.cycle.hopsFromLast(opts, fwd); + for (var k=0; k < hops; k++) { + if (fwd) + opts.els.push(opts.els.shift()); + else + opts.els.unshift(opts.els.pop()); + } + if (fwd) { + for (var i=0, len=opts.els.length; i < len; i++) + $(opts.els[i]).css('z-index', len-i+count); + } + else { + var z = $(curr).css('z-index'); + $el.css('z-index', parseInt(z,10)+1+count); + } + $el.animate({left:0, top:0}, opts.speedOut, opts.easeOut, function() { + $(fwd ? this : curr).hide(); + if (cb) cb(); + }); + }); + }; + $.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 }); +}; + +// turnUp/Down/Left/Right +$.fn.cycle.transitions.turnUp = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,true,false); + opts.cssBefore.top = next.cycleH; + opts.animIn.height = next.cycleH; + opts.animOut.width = next.cycleW; + }); + opts.cssFirst.top = 0; + opts.cssBefore.left = 0; + opts.cssBefore.height = 0; + opts.animIn.top = 0; + opts.animOut.height = 0; +}; +$.fn.cycle.transitions.turnDown = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,true,false); + opts.animIn.height = next.cycleH; + opts.animOut.top = curr.cycleH; + }); + opts.cssFirst.top = 0; + opts.cssBefore.left = 0; + opts.cssBefore.top = 0; + opts.cssBefore.height = 0; + opts.animOut.height = 0; +}; +$.fn.cycle.transitions.turnLeft = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,false,true); + opts.cssBefore.left = next.cycleW; + opts.animIn.width = next.cycleW; + }); + opts.cssBefore.top = 0; + opts.cssBefore.width = 0; + opts.animIn.left = 0; + opts.animOut.width = 0; +}; +$.fn.cycle.transitions.turnRight = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,false,true); + opts.animIn.width = next.cycleW; + opts.animOut.left = curr.cycleW; + }); + $.extend(opts.cssBefore, { top: 0, left: 0, width: 0 }); + opts.animIn.left = 0; + opts.animOut.width = 0; +}; + +// zoom +$.fn.cycle.transitions.zoom = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,false,false,true); + opts.cssBefore.top = next.cycleH/2; + opts.cssBefore.left = next.cycleW/2; + $.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH }); + $.extend(opts.animOut, { width: 0, height: 0, top: curr.cycleH/2, left: curr.cycleW/2 }); + }); + opts.cssFirst.top = 0; + opts.cssFirst.left = 0; + opts.cssBefore.width = 0; + opts.cssBefore.height = 0; +}; + +// fadeZoom +$.fn.cycle.transitions.fadeZoom = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,false,false); + opts.cssBefore.left = next.cycleW/2; + opts.cssBefore.top = next.cycleH/2; + $.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH }); + }); + opts.cssBefore.width = 0; + opts.cssBefore.height = 0; + opts.animOut.opacity = 0; +}; + +// blindX +$.fn.cycle.transitions.blindX = function($cont, $slides, opts) { + var w = $cont.css('overflow','hidden').width(); + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts); + opts.animIn.width = next.cycleW; + opts.animOut.left = curr.cycleW; + }); + opts.cssBefore.left = w; + opts.cssBefore.top = 0; + opts.animIn.left = 0; + opts.animOut.left = w; +}; +// blindY +$.fn.cycle.transitions.blindY = function($cont, $slides, opts) { + var h = $cont.css('overflow','hidden').height(); + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts); + opts.animIn.height = next.cycleH; + opts.animOut.top = curr.cycleH; + }); + opts.cssBefore.top = h; + opts.cssBefore.left = 0; + opts.animIn.top = 0; + opts.animOut.top = h; +}; +// blindZ +$.fn.cycle.transitions.blindZ = function($cont, $slides, opts) { + var h = $cont.css('overflow','hidden').height(); + var w = $cont.width(); + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts); + opts.animIn.height = next.cycleH; + opts.animOut.top = curr.cycleH; + }); + opts.cssBefore.top = h; + opts.cssBefore.left = w; + opts.animIn.top = 0; + opts.animIn.left = 0; + opts.animOut.top = h; + opts.animOut.left = w; +}; + +// growX - grow horizontally from centered 0 width +$.fn.cycle.transitions.growX = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,false,true); + opts.cssBefore.left = this.cycleW/2; + opts.animIn.left = 0; + opts.animIn.width = this.cycleW; + opts.animOut.left = 0; + }); + opts.cssBefore.top = 0; + opts.cssBefore.width = 0; +}; +// growY - grow vertically from centered 0 height +$.fn.cycle.transitions.growY = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,true,false); + opts.cssBefore.top = this.cycleH/2; + opts.animIn.top = 0; + opts.animIn.height = this.cycleH; + opts.animOut.top = 0; + }); + opts.cssBefore.height = 0; + opts.cssBefore.left = 0; +}; + +// curtainX - squeeze in both edges horizontally +$.fn.cycle.transitions.curtainX = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,false,true,true); + opts.cssBefore.left = next.cycleW/2; + opts.animIn.left = 0; + opts.animIn.width = this.cycleW; + opts.animOut.left = curr.cycleW/2; + opts.animOut.width = 0; + }); + opts.cssBefore.top = 0; + opts.cssBefore.width = 0; +}; +// curtainY - squeeze in both edges vertically +$.fn.cycle.transitions.curtainY = function($cont, $slides, opts) { + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,true,false,true); + opts.cssBefore.top = next.cycleH/2; + opts.animIn.top = 0; + opts.animIn.height = next.cycleH; + opts.animOut.top = curr.cycleH/2; + opts.animOut.height = 0; + }); + opts.cssBefore.height = 0; + opts.cssBefore.left = 0; +}; + +// cover - curr slide covered by next slide +$.fn.cycle.transitions.cover = function($cont, $slides, opts) { + var d = opts.direction || 'left'; + var w = $cont.css('overflow','hidden').width(); + var h = $cont.height(); + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts); + if (d == 'right') + opts.cssBefore.left = -w; + else if (d == 'up') + opts.cssBefore.top = h; + else if (d == 'down') + opts.cssBefore.top = -h; + else + opts.cssBefore.left = w; + }); + opts.animIn.left = 0; + opts.animIn.top = 0; + opts.cssBefore.top = 0; + opts.cssBefore.left = 0; +}; + +// uncover - curr slide moves off next slide +$.fn.cycle.transitions.uncover = function($cont, $slides, opts) { + var d = opts.direction || 'left'; + var w = $cont.css('overflow','hidden').width(); + var h = $cont.height(); + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,true,true,true); + if (d == 'right') + opts.animOut.left = w; + else if (d == 'up') + opts.animOut.top = -h; + else if (d == 'down') + opts.animOut.top = h; + else + opts.animOut.left = -w; + }); + opts.animIn.left = 0; + opts.animIn.top = 0; + opts.cssBefore.top = 0; + opts.cssBefore.left = 0; +}; + +// toss - move top slide and fade away +$.fn.cycle.transitions.toss = function($cont, $slides, opts) { + var w = $cont.css('overflow','visible').width(); + var h = $cont.height(); + opts.before.push(function(curr, next, opts) { + $.fn.cycle.commonReset(curr,next,opts,true,true,true); + // provide default toss settings if animOut not provided + if (!opts.animOut.left && !opts.animOut.top) + $.extend(opts.animOut, { left: w*2, top: -h/2, opacity: 0 }); + else + opts.animOut.opacity = 0; + }); + opts.cssBefore.left = 0; + opts.cssBefore.top = 0; + opts.animIn.left = 0; +}; + +// wipe - clip animation +$.fn.cycle.transitions.wipe = function($cont, $slides, opts) { + var w = $cont.css('overflow','hidden').width(); + var h = $cont.height(); + opts.cssBefore = opts.cssBefore || {}; + var clip; + if (opts.clip) { + if (/l2r/.test(opts.clip)) + clip = 'rect(0px 0px '+h+'px 0px)'; + else if (/r2l/.test(opts.clip)) + clip = 'rect(0px '+w+'px '+h+'px '+w+'px)'; + else if (/t2b/.test(opts.clip)) + clip = 'rect(0px '+w+'px 0px 0px)'; + else if (/b2t/.test(opts.clip)) + clip = 'rect('+h+'px '+w+'px '+h+'px 0px)'; + else if (/zoom/.test(opts.clip)) { + var top = parseInt(h/2,10); + var left = parseInt(w/2,10); + clip = 'rect('+top+'px '+left+'px '+top+'px '+left+'px)'; + } + } + + opts.cssBefore.clip = opts.cssBefore.clip || clip || 'rect(0px 0px 0px 0px)'; + + var d = opts.cssBefore.clip.match(/(\d+)/g); + var t = parseInt(d[0],10), r = parseInt(d[1],10), b = parseInt(d[2],10), l = parseInt(d[3],10); + + opts.before.push(function(curr, next, opts) { + if (curr == next) return; + var $curr = $(curr), $next = $(next); + $.fn.cycle.commonReset(curr,next,opts,true,true,false); + opts.cssAfter.display = 'block'; + + var step = 1, count = parseInt((opts.speedIn / 13),10) - 1; + (function f() { + var tt = t ? t - parseInt(step * (t/count),10) : 0; + var ll = l ? l - parseInt(step * (l/count),10) : 0; + var bb = b < h ? b + parseInt(step * ((h-b)/count || 1),10) : h; + var rr = r < w ? r + parseInt(step * ((w-r)/count || 1),10) : w; + $next.css({ clip: 'rect('+tt+'px '+rr+'px '+bb+'px '+ll+'px)' }); + (step++ <= count) ? setTimeout(f, 13) : $curr.css('display', 'none'); + })(); + }); + $.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 }); + opts.animIn = { left: 0 }; + opts.animOut = { left: 0 }; +}; + +})(jQuery); diff --git a/js/jquery.js b/js/jquery.js new file mode 100644 index 0000000..3684c36 --- /dev/null +++ b/js/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */ +(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(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 bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,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=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};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=n.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.6.4",length:0,size:function(){return this.length},toArray:function(){return G.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)?F.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(),B.done(a);return this},eq:function(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(G.apply(this,arguments),"slice",G.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:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},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},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw 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(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))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(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.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:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([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&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i=f.expando,j=typeof c=="string",k=a.nodeType,l=k?f.cache:a,m=k?a[f.expando]:a[f.expando]&&f.expando;if((!m||e&&m&&l[m]&&!l[m][i])&&j&&d===b)return;m||(k?a[f.expando]=m=++f.uuid:m=f.expando),l[m]||(l[m]={},k||(l[m].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?l[m][i]=f.extend(l[m][i],c):l[m]=f.extend(l[m],c);g=l[m],e&&(g[i]||(g[i]={}),g=g[i]),d!==b&&(g[f.camelCase(c)]=d);if(c==="events"&&!g[c])return g[i]&&g[i].events;j?(h=g[c],h==null&&(h=g[f.camelCase(c)])):h=g;return h}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e=f.expando,g=a.nodeType,h=g?f.cache:a,i=g?a[f.expando]:f.expando;if(!h[i])return;if(b){d=c?h[i][e]:h[i];if(d){d[b]||(b=f.camelCase(b)),delete d[b];if(!l(d))return}}if(c){delete h[i][e];if(!l(h[i]))return}var j=h[i][e];f.support.deleteExpando||!h.setInterval?delete h[i]:h[i]=null,j?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=j):g&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=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=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.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}})}}),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=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=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},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=v:u&&(i=u)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.attr(a,b,""),a.removeAttribute(b),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.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(u&&f.nodeName(a,"button"))return u.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(u&&f.nodeName(a,"button"))return u.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=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==null?g:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabIndex=f.propHooks.tabIndex,v={get:function(a,c){var d;return f.prop(a,c)===!0||(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}},f.support.getSetAttribute||(u=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?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.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.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.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 w=/\.(.*)$/,x=/^(?:textarea|input|select)$/i,y=/\./g,z=/ /g,A=/[^\w\s.|`]/g,B=function(a){return a.replace(A,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),B).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},I=function(c){var d=c.target,e,g;if(!!x.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=H(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:I,beforedeactivate:I,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&I.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&I.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",H(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in G)f.event.add(this,c+".specialChange",G[c]);return x.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return x.test(this.nodeName)}},G=f.event.special.change.filters,G.focus=G.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.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]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),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]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.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!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":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=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=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(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.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:[]}},l.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&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[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}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.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 k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=S.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(U(c[0])||U(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),g=R.call(arguments);N.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!T[a]?f.unique(e):e,(this.length>1||P.test(d))&&O.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.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 W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(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(arguments[0]);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(arguments[0]).toArray());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))&&!be[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.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.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,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=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,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.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/)<[^<]*)*<\/script>/gi,bK=/^(?:select|textarea)/i,bL=/\s+/,bM=/([?&])_=[^&]*/,bN=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bO=f.fn.load,bP={},bQ={},bR,bS,bT=["*/"]+["*"];try{bR=e.href}catch(bU){bR=c.createElement("a"),bR.href="",bR=bR.href}bS=bN.exec(bR.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bO)return bO.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bJ,"")).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||bK.test(this.nodeName)||bE.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(bB,"\r\n")}}):{name:b.name,value:c.replace(bB,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(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?bX(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),bX(a,b);return a},ajaxSettings:{url:bR,isLocal:bF.test(bS[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","*":bT},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:bV(bP),ajaxTransport:bV(bQ),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?bZ(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=b$(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.resolveWith(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._Deferred(),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=bD.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.done,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(bC,"").replace(bH,bS[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bL),d.crossDomain==null&&(r=bN.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bS[1]&&r[2]==bS[2]&&(r[3]||(r[1]==="http:"?80:443))==(bS[3]||(bS[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bW(bP,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bG.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bI.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bM,"$1_="+x);d.url=y+(y===d.url?(bI.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]!=="*"?", "+bT+"; 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=bW(bQ,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){s<2?w(-1,z):f.error(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)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),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&&(ca.test(b.url)||e&&ca.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(ca,l),b.url===j&&(e&&(k=k.replace(ca,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 cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,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,cb&&delete cd[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=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cq("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.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=ct.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&&!ct.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=cu(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=cu(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")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):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.isNaN(j)?i:j}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/js/jquery.qtip.js b/js/jquery.qtip.js new file mode 100644 index 0000000..405485d --- /dev/null +++ b/js/jquery.qtip.js @@ -0,0 +1,3395 @@ +/*! +* qTip2 - Pretty powerful tooltips +* http://craigsworks.com/projects/qtip2/ +* +* Version: nightly +* Copyright 2009-2010 Craig Michael Thompson - http://craigsworks.com +* +* Dual licensed under MIT or GPLv2 licenses +* http://en.wikipedia.org/wiki/MIT_License +* http://en.wikipedia.org/wiki/GNU_General_Public_License +* +* Date: Sun Jul 15 16:44:57.0000000000 2012 +*/ + +/*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true */ +/*global window: false, jQuery: false, console: false, define: false */ + +// Uses AMD or browser globals to create a jQuery plugin. +(function(factory) { + if(typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } + else if(jQuery && !jQuery.fn.qtip) { + factory(jQuery); + } +} +(function($) { + + "use strict"; // Enable ECMAScript "strict" operation for this function. See more: http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ + + // Munge the primitives - Paul Irish tip + var TRUE = true, + FALSE = false, + NULL = null, + undefined, + + // Side names and other stuff + X = 'x', Y = 'y', + WIDTH = 'width', + HEIGHT = 'height', + TOP = 'top', + LEFT = 'left', + BOTTOM = 'bottom', + RIGHT = 'right', + CENTER = 'center', + FLIP = 'flip', + FLIPINVERT = 'flipinvert', + SHIFT = 'shift', + + // Shortcut vars + QTIP, PLUGINS, MOUSE, + usedIDs = {}, + uitooltip = 'ui-tooltip', + widget = 'ui-widget', + disabled = 'ui-state-disabled', + selector = 'div.qtip.'+uitooltip, + defaultClass = uitooltip + '-default', + focusClass = uitooltip + '-focus', + hoverClass = uitooltip + '-hover', + fluidClass = uitooltip + '-fluid', + hideOffset = '-31000px', + replaceSuffix = '_replacedByqTip', + oldtitle = 'oldtitle', + trackingBound; + + /* Thanks to Paul Irish for this one: http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/ */ + function log() { + log.history = log.history || []; + log.history.push(arguments); + + // Make sure console is present + if('object' === typeof console) { + + // Setup console and arguments + var c = console[ console.warn ? 'warn' : 'log' ], + args = Array.prototype.slice.call(arguments), a; + + // Add qTip2 marker to first argument if it's a string + if(typeof arguments[0] === 'string') { args[0] = 'qTip2: ' + args[0]; } + + // Apply console.warn or .log if not supported + a = c.apply ? c.apply(console, args) : c(args); + } + } + +// Option object sanitizer +function sanitizeOptions(opts) +{ + var content; + + if(!opts || 'object' !== typeof opts) { return FALSE; } + + if(opts.metadata === NULL || 'object' !== typeof opts.metadata) { + opts.metadata = { + type: opts.metadata + }; + } + + if('content' in opts) { + if(opts.content === NULL || 'object' !== typeof opts.content || opts.content.jquery) { + opts.content = { + text: opts.content + }; + } + + content = opts.content.text || FALSE; + if(!$.isFunction(content) && ((!content && !content.attr) || content.length < 1 || ('object' === typeof content && !content.jquery))) { + opts.content.text = FALSE; + } + + if('title' in opts.content) { + if(opts.content.title === NULL || 'object' !== typeof opts.content.title) { + opts.content.title = { + text: opts.content.title + }; + } + + content = opts.content.title.text || FALSE; + if(!$.isFunction(content) && ((!content && !content.attr) || content.length < 1 || ('object' === typeof content && !content.jquery))) { + opts.content.title.text = FALSE; + } + } + } + + if('position' in opts) { + if(opts.position === NULL || 'object' !== typeof opts.position) { + opts.position = { + my: opts.position, + at: opts.position + }; + } + } + + if('show' in opts) { + if(opts.show === NULL || 'object' !== typeof opts.show) { + if(opts.show.jquery) { + opts.show = { target: opts.show }; + } + else { + opts.show = { event: opts.show }; + } + } + } + + if('hide' in opts) { + if(opts.hide === NULL || 'object' !== typeof opts.hide) { + if(opts.hide.jquery) { + opts.hide = { target: opts.hide }; + } + else { + opts.hide = { event: opts.hide }; + } + } + } + + if('style' in opts) { + if(opts.style === NULL || 'object' !== typeof opts.style) { + opts.style = { + classes: opts.style + }; + } + } + + // Sanitize plugin options + $.each(PLUGINS, function() { + if(this.sanitize) { this.sanitize(opts); } + }); + + return opts; +} + +/* +* Core plugin implementation +*/ +function QTip(target, options, id, attr) +{ + // Declare this reference + var self = this, + docBody = document.body, + tooltipID = uitooltip + '-' + id, + isPositioning = 0, + isDrawing = 0, + tooltip = $(), + namespace = '.qtip-' + id, + elements, cache; + + // Setup class attributes + self.id = id; + self.rendered = FALSE; + self.destroyed = FALSE; + self.elements = elements = { target: target }; + self.timers = { img: {} }; + self.options = options; + self.checks = {}; + self.plugins = {}; + self.cache = cache = { + event: {}, + target: $(), + disabled: FALSE, + attr: attr, + onTarget: FALSE, + lastClass: '' + }; + + /* + * Private core functions + */ + function convertNotation(notation) + { + var i = 0, obj, option = options, + + // Split notation into array + levels = notation.split('.'); + + // Loop through + while( option = option[ levels[i++] ] ) { + if(i < levels.length) { obj = option; } + } + + return [obj || options, levels.pop()]; + } + + function setWidget() { + var on = options.style.widget; + + tooltip.toggleClass(widget, on).toggleClass(defaultClass, options.style.def && !on); + elements.content.toggleClass(widget+'-content', on); + + if(elements.titlebar){ + elements.titlebar.toggleClass(widget+'-header', on); + } + if(elements.button){ + elements.button.toggleClass(uitooltip+'-icon', !on); + } + } + + function removeTitle(reposition) + { + if(elements.title) { + elements.titlebar.remove(); + elements.titlebar = elements.title = elements.button = NULL; + + // Reposition if enabled + if(reposition !== FALSE) { self.reposition(); } + } + } + + function createButton() + { + var button = options.content.title.button, + isString = typeof button === 'string', + close = isString ? button : 'Close tooltip'; + + if(elements.button) { elements.button.remove(); } + + // Use custom button if one was supplied by user, else use default + if(button.jquery) { + elements.button = button; + } + else { + elements.button = $('', { + 'class': 'ui-state-default ui-tooltip-close ' + (options.style.widget ? '' : uitooltip+'-icon'), + 'title': close, + 'aria-label': close + }) + .prepend( + $('', { + 'class': 'ui-icon ui-icon-close', + 'html': '×' + }) + ); + } + + // Create button and setup attributes + elements.button.appendTo(elements.titlebar) + .attr('role', 'button') + .click(function(event) { + if(!tooltip.hasClass(disabled)) { self.hide(event); } + return FALSE; + }); + + // Redraw the tooltip when we're done + self.redraw(); + } + + function createTitle() + { + var id = tooltipID+'-title'; + + // Destroy previous title element, if present + if(elements.titlebar) { removeTitle(); } + + // Create title bar and title elements + elements.titlebar = $('
', { + 'class': uitooltip + '-titlebar ' + (options.style.widget ? 'ui-widget-header' : '') + }) + .append( + elements.title = $('
', { + 'id': id, + 'class': uitooltip + '-title', + 'aria-atomic': TRUE + }) + ) + .insertBefore(elements.content) + + // Button-specific events + .delegate('.ui-tooltip-close', 'mousedown keydown mouseup keyup mouseout', function(event) { + $(this).toggleClass('ui-state-active ui-state-focus', event.type.substr(-4) === 'down'); + }) + .delegate('.ui-tooltip-close', 'mouseover mouseout', function(event){ + $(this).toggleClass('ui-state-hover', event.type === 'mouseover'); + }); + + // Create button if enabled + if(options.content.title.button) { createButton(); } + + // Redraw the tooltip dimensions if it's rendered + else if(self.rendered){ self.redraw(); } + } + + function updateButton(button) + { + var elem = elements.button, + title = elements.title; + + // Make sure tooltip is rendered and if not, return + if(!self.rendered) { return FALSE; } + + if(!button) { + elem.remove(); + } + else { + if(!title) { + createTitle(); + } + createButton(); + } + } + + function updateTitle(content, reposition) + { + var elem = elements.title; + + // Make sure tooltip is rendered and if not, return + if(!self.rendered || !content) { return FALSE; } + + // Use function to parse content + if($.isFunction(content)) { + content = content.call(target, cache.event, self); + } + + // Remove title if callback returns false or null/undefined (but not '') + if(content === FALSE || (!content && content !== '')) { return removeTitle(FALSE); } + + // Append new content if its a DOM array and show it if hidden + else if(content.jquery && content.length > 0) { + elem.empty().append(content.css({ display: 'block' })); + } + + // Content is a regular string, insert the new content + else { elem.html(content); } + + // Redraw and reposition + self.redraw(); + if(reposition !== FALSE && self.rendered && tooltip[0].offsetWidth > 0) { + self.reposition(cache.event); + } + } + + function updateContent(content, reposition) + { + var elem = elements.content; + + // Make sure tooltip is rendered and content is defined. If not return + if(!self.rendered || !content) { return FALSE; } + + // Use function to parse content + if($.isFunction(content)) { + content = content.call(target, cache.event, self) || ''; + } + + // Append new content if its a DOM array and show it if hidden + if(content.jquery && content.length > 0) { + elem.empty().append(content.css({ display: 'block' })); + } + + // Content is a regular string, insert the new content + else { elem.html(content); } + + // Image detection + function detectImages(next) { + var images, srcs = {}; + + function imageLoad(image) { + // Clear src from object and any timers and events associated with the image + if(image) { + delete srcs[image.src]; + clearTimeout(self.timers.img[image.src]); + $(image).unbind(namespace); + } + + // If queue is empty after image removal, update tooltip and continue the queue + if($.isEmptyObject(srcs)) { + self.redraw(); + if(reposition !== FALSE) { + self.reposition(cache.event); + } + + next(); + } + } + + // Find all content images without dimensions, and if no images were found, continue + if((images = elem.find('img[src]:not([height]):not([width])')).length === 0) { return imageLoad(); } + + // Apply timer to each image to poll for dimensions + images.each(function(i, elem) { + // Skip if the src is already present + if(srcs[elem.src] !== undefined) { return; } + + // Keep track of how many times we poll for image dimensions. + // If it doesn't return in a reasonable amount of time, it's better + // to display the tooltip, rather than hold up the queue. + var iterations = 0, maxIterations = 3; + + (function timer(){ + // When the dimensions are found, remove the image from the queue + if(elem.height || elem.width || (iterations > maxIterations)) { return imageLoad(elem); } + + // Increase iterations and restart timer + iterations += 1; + self.timers.img[elem.src] = setTimeout(timer, 700); + }()); + + // Also apply regular load/error event handlers + $(elem).bind('error'+namespace+' load'+namespace, function(){ imageLoad(this); }); + + // Store the src and element in our object + srcs[elem.src] = elem; + }); + } + + /* + * If we're still rendering... insert into 'fx' queue our image dimension + * checker which will halt the showing of the tooltip until image dimensions + * can be detected properly. + */ + if(self.rendered < 0) { tooltip.queue('fx', detectImages); } + + // We're fully rendered, so reset isDrawing flag and proceed without queue delay + else { isDrawing = 0; detectImages($.noop); } + + return self; + } + + function assignEvents() + { + var posOptions = options.position, + targets = { + show: options.show.target, + hide: options.hide.target, + viewport: $(posOptions.viewport), + document: $(document), + body: $(document.body), + window: $(window) + }, + events = { + show: $.trim('' + options.show.event).split(' '), + hide: $.trim('' + options.hide.event).split(' ') + }, + IE6 = $.browser.msie && parseInt($.browser.version, 10) === 6; + + // Define show event method + function showMethod(event) + { + if(tooltip.hasClass(disabled)) { return FALSE; } + + // Clear hide timers + clearTimeout(self.timers.show); + clearTimeout(self.timers.hide); + + // Start show timer + var callback = function(){ self.toggle(TRUE, event); }; + if(options.show.delay > 0) { + self.timers.show = setTimeout(callback, options.show.delay); + } + else{ callback(); } + } + + // Define hide method + function hideMethod(event) + { + if(tooltip.hasClass(disabled) || isPositioning || isDrawing) { return FALSE; } + + // Check if new target was actually the tooltip element + var relatedTarget = $(event.relatedTarget || event.target), + ontoTooltip = relatedTarget.closest(selector)[0] === tooltip[0], + ontoTarget = relatedTarget[0] === targets.show[0]; + + // Clear timers and stop animation queue + clearTimeout(self.timers.show); + clearTimeout(self.timers.hide); + + // Prevent hiding if tooltip is fixed and event target is the tooltip. Or if mouse positioning is enabled and cursor momentarily overlaps + if((posOptions.target === 'mouse' && ontoTooltip) || (options.hide.fixed && ((/mouse(out|leave|move)/).test(event.type) && (ontoTooltip || ontoTarget)))) { + try { event.preventDefault(); event.stopImmediatePropagation(); } catch(e) {} return; + } + + // If tooltip has displayed, start hide timer + if(options.hide.delay > 0) { + self.timers.hide = setTimeout(function(){ self.hide(event); }, options.hide.delay); + } + else{ self.hide(event); } + } + + // Define inactive method + function inactiveMethod(event) + { + if(tooltip.hasClass(disabled)) { return FALSE; } + + // Clear timer + clearTimeout(self.timers.inactive); + self.timers.inactive = setTimeout(function(){ self.hide(event); }, options.hide.inactive); + } + + function repositionMethod(event) { + if(self.rendered && tooltip[0].offsetWidth > 0) { self.reposition(event); } + } + + // On mouseenter/mouseleave... + tooltip.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) { + var state = event.type === 'mouseenter'; + + // Focus the tooltip on mouseenter (z-index stacking) + if(state) { self.focus(event); } + + // Add hover class + tooltip.toggleClass(hoverClass, state); + }); + + // If using mouseout/mouseleave as a hide event... + if(/mouse(out|leave)/i.test(options.hide.event)) { + // Hide tooltips when leaving current window/frame (but not select/option elements) + if(options.hide.leave === 'window') { + targets.window.bind('mouseleave'+namespace+' blur'+namespace, function(event) { + if(!/select|option/.test(event.target.nodeName) && !event.relatedTarget) { self.hide(event); } + }); + } + } + + // Enable hide.fixed + if(options.hide.fixed) { + // Add tooltip as a hide target + targets.hide = targets.hide.add(tooltip); + + // Clear hide timer on tooltip hover to prevent it from closing + tooltip.bind('mouseover'+namespace, function() { + if(!tooltip.hasClass(disabled)) { clearTimeout(self.timers.hide); } + }); + } + + /* + * Make sure hoverIntent functions properly by using mouseleave to clear show timer if + * mouseenter/mouseout is used for show.event, even if it isn't in the users options. + */ + else if(/mouse(over|enter)/i.test(options.show.event)) { + targets.hide.bind('mouseleave'+namespace, function(event) { + clearTimeout(self.timers.show); + }); + } + + // Hide tooltip on document mousedown if unfocus events are enabled + if(('' + options.hide.event).indexOf('unfocus') > -1) { + posOptions.container.closest('html').bind('mousedown'+namespace, function(event) { + var elem = $(event.target), + enabled = self.rendered && !tooltip.hasClass(disabled) && tooltip[0].offsetWidth > 0, + isAncestor = elem.parents(selector).filter(tooltip[0]).length > 0; + + if(elem[0] !== target[0] && elem[0] !== tooltip[0] && !isAncestor && + !target.has(elem[0]).length && !elem.attr('disabled') + ) { + self.hide(event); + } + }); + } + + // Check if the tooltip hides when inactive + if('number' === typeof options.hide.inactive) { + // Bind inactive method to target as a custom event + targets.show.bind('qtip-'+id+'-inactive', inactiveMethod); + + // Define events which reset the 'inactive' event handler + $.each(QTIP.inactiveEvents, function(index, type){ + targets.hide.add(elements.tooltip).bind(type+namespace+'-inactive', inactiveMethod); + }); + } + + // Apply hide events + $.each(events.hide, function(index, type) { + var showIndex = $.inArray(type, events.show), + targetHide = $(targets.hide); + + // Both events and targets are identical, apply events using a toggle + if((showIndex > -1 && targetHide.add(targets.show).length === targetHide.length) || type === 'unfocus') + { + targets.show.bind(type+namespace, function(event) { + if(tooltip[0].offsetWidth > 0) { hideMethod(event); } + else { showMethod(event); } + }); + + // Don't bind the event again + delete events.show[ showIndex ]; + } + + // Events are not identical, bind normally + else { targets.hide.bind(type+namespace, hideMethod); } + }); + + // Apply show events + $.each(events.show, function(index, type) { + targets.show.bind(type+namespace, showMethod); + }); + + // Check if the tooltip hides when mouse is moved a certain distance + if('number' === typeof options.hide.distance) { + // Bind mousemove to target to detect distance difference + targets.show.add(tooltip).bind('mousemove'+namespace, function(event) { + var origin = cache.origin || {}, + limit = options.hide.distance, + abs = Math.abs; + + // Check if the movement has gone beyond the limit, and hide it if so + if(abs(event.pageX - origin.pageX) >= limit || abs(event.pageY - origin.pageY) >= limit) { + self.hide(event); + } + }); + } + + // Mouse positioning events + if(posOptions.target === 'mouse') { + // Cache mousemove coords on show targets + targets.show.bind('mousemove'+namespace, function(event) { + MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' }; + }); + + // If mouse adjustment is on... + if(posOptions.adjust.mouse) { + // Apply a mouseleave event so we don't get problems with overlapping + if(options.hide.event) { + // Hide when we leave the tooltip and not onto the show target + tooltip.bind('mouseleave'+namespace, function(event) { + if((event.relatedTarget || event.target) !== targets.show[0]) { self.hide(event); } + }); + + // Track if we're on the target or not + elements.target.bind('mouseenter'+namespace+' mouseleave'+namespace, function(event) { + cache.onTarget = event.type === 'mouseenter'; + }); + } + + // Update tooltip position on mousemove + targets.document.bind('mousemove'+namespace, function(event) { + // Update the tooltip position only if the tooltip is visible and adjustment is enabled + if(self.rendered && cache.onTarget && !tooltip.hasClass(disabled) && tooltip[0].offsetWidth > 0) { + self.reposition(event || MOUSE); + } + }); + } + } + + // Adjust positions of the tooltip on window resize if enabled + if(posOptions.adjust.resize || targets.viewport.length) { + ($.event.special.resize ? targets.viewport : targets.window).bind('resize'+namespace, repositionMethod); + } + + // Adjust tooltip position on scroll if screen adjustment is enabled + if(targets.viewport.length || (IE6 && tooltip.css('position') === 'fixed')) { + targets.viewport.bind('scroll'+namespace, repositionMethod); + } + } + + function unassignEvents() + { + var targets = [ + options.show.target[0], + options.hide.target[0], + self.rendered && elements.tooltip[0], + options.position.container[0], + options.position.viewport[0], + window, + document + ]; + + // Check if tooltip is rendered + if(self.rendered) { + $([]).pushStack( $.grep(targets, function(i){ return typeof i === 'object'; }) ).unbind(namespace); + } + + // Tooltip isn't yet rendered, remove render event + else { options.show.target.unbind(namespace+'-create'); } + } + + // Setup builtin .set() option checks + self.checks.builtin = { + // Core checks + '^id$': function(obj, o, v) { + var id = v === TRUE ? QTIP.nextid : v, + tooltipID = uitooltip + '-' + id; + + if(id !== FALSE && id.length > 0 && !$('#'+tooltipID).length) { + tooltip[0].id = tooltipID; + elements.content[0].id = tooltipID + '-content'; + elements.title[0].id = tooltipID + '-title'; + } + }, + + // Content checks + '^content.text$': function(obj, o, v){ updateContent(v); }, + '^content.title.text$': function(obj, o, v) { + // Remove title if content is null + if(!v) { return removeTitle(); } + + // If title isn't already created, create it now and update + if(!elements.title && v) { createTitle(); } + updateTitle(v); + }, + '^content.title.button$': function(obj, o, v){ updateButton(v); }, + + // Position checks + '^position.(my|at)$': function(obj, o, v){ + // Parse new corner value into Corner objecct + if('string' === typeof v) { + obj[o] = new PLUGINS.Corner(v); + } + }, + '^position.container$': function(obj, o, v){ + if(self.rendered) { tooltip.appendTo(v); } + }, + + // Show checks + '^show.ready$': function() { + if(!self.rendered) { self.render(1); } + else { self.toggle(TRUE); } + }, + + // Style checks + '^style.classes$': function(obj, o, v) { + tooltip.attr('class', uitooltip + ' qtip ui-helper-reset ' + v); + }, + '^style.widget|content.title': setWidget, + + // Events check + '^events.(render|show|move|hide|focus|blur)$': function(obj, o, v) { + tooltip[($.isFunction(v) ? '' : 'un') + 'bind']('tooltip'+o, v); + }, + + // Properties which require event reassignment + '^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)': function() { + var posOptions = options.position; + + // Set tracking flag + tooltip.attr('tracking', posOptions.target === 'mouse' && posOptions.adjust.mouse); + + // Reassign events + unassignEvents(); assignEvents(); + } + }; + + /* + * Public API methods + */ + $.extend(self, { + render: function(show) + { + if(self.rendered) { return self; } // If tooltip has already been rendered, exit + + var text = options.content.text, + title = options.content.title.text, + posOptions = options.position, + callback = $.Event('tooltiprender'); + + // Add ARIA attributes to target + $.attr(target[0], 'aria-describedby', tooltipID); + + // Create tooltip element + tooltip = elements.tooltip = $('
', { + 'id': tooltipID, + 'class': uitooltip + ' qtip ui-helper-reset ' + defaultClass + ' ' + options.style.classes + ' '+ uitooltip + '-pos-' + options.position.my.abbrev(), + 'width': options.style.width || '', + 'height': options.style.height || '', + 'tracking': posOptions.target === 'mouse' && posOptions.adjust.mouse, + + /* ARIA specific attributes */ + 'role': 'alert', + 'aria-live': 'polite', + 'aria-atomic': FALSE, + 'aria-describedby': tooltipID + '-content', + 'aria-hidden': TRUE + }) + .toggleClass(disabled, cache.disabled) + .data('qtip', self) + .appendTo(options.position.container) + .append( + // Create content element + elements.content = $('
', { + 'class': uitooltip + '-content', + 'id': tooltipID + '-content', + 'aria-atomic': TRUE + }) + ); + + // Set rendered flag and prevent redundant redraw/reposition calls for now + self.rendered = -1; + isDrawing = 1; isPositioning = 1; + + // Create title... + if(title) { + createTitle(); + + // Update title only if its not a callback (called in toggle if so) + if(!$.isFunction(title)) { updateTitle(title, FALSE); } + } + + // Set proper rendered flag and update content if not a callback function (called in toggle) + if(!$.isFunction(text)) { updateContent(text, FALSE); } + self.rendered = TRUE; + + // Setup widget classes + setWidget(); + + // Assign passed event callbacks (before plugins!) + $.each(options.events, function(name, callback) { + if($.isFunction(callback)) { + tooltip.bind(name === 'toggle' ? 'tooltipshow tooltiphide' : 'tooltip'+name, callback); + } + }); + + // Initialize 'render' plugins + $.each(PLUGINS, function() { + if(this.initialize === 'render') { this(self); } + }); + + // Assign events + assignEvents(); + + /* Queue this part of the render process in our fx queue so we can + * load images before the tooltip renders fully. + * + * See: updateContent method + */ + tooltip.queue('fx', function(next) { + // Trigger tooltiprender event and pass original triggering event as original + callback.originalEvent = cache.event; + tooltip.trigger(callback, [self]); + + // Reset flags + isDrawing = 0; isPositioning = 0; + + // Redraw the tooltip manually now we're fully rendered + self.redraw(); + + // Show tooltip if needed + if(options.show.ready || show) { + self.toggle(TRUE, cache.event, FALSE); + } + + next(); // Move on to next method in queue + }); + + return self; + }, + + get: function(notation) + { + var result, o; + + switch(notation.toLowerCase()) + { + case 'dimensions': + result = { + height: tooltip.outerHeight(), width: tooltip.outerWidth() + }; + break; + + case 'offset': + result = PLUGINS.offset(tooltip, options.position.container); + break; + + default: + o = convertNotation(notation.toLowerCase()); + result = o[0][ o[1] ]; + result = result.precedance ? result.string() : result; + break; + } + + return result; + }, + + set: function(option, value) + { + var rmove = /^position\.(my|at|adjust|target|container)|style|content|show\.ready/i, + rdraw = /^content\.(title|attr)|style/i, + reposition = FALSE, + redraw = FALSE, + checks = self.checks, + name; + + function callback(notation, args) { + var category, rule, match; + + for(category in checks) { + for(rule in checks[category]) { + if(match = (new RegExp(rule, 'i')).exec(notation)) { + args.push(match); + checks[category][rule].apply(self, args); + } + } + } + } + + // Convert singular option/value pair into object form + if('string' === typeof option) { + name = option; option = {}; option[name] = value; + } + else { option = $.extend(TRUE, {}, option); } + + // Set all of the defined options to their new values + $.each(option, function(notation, value) { + var obj = convertNotation( notation.toLowerCase() ), previous; + + // Set new obj value + previous = obj[0][ obj[1] ]; + obj[0][ obj[1] ] = 'object' === typeof value && value.nodeType ? $(value) : value; + + // Set the new params for the callback + option[notation] = [obj[0], obj[1], value, previous]; + + // Also check if we need to reposition / redraw + reposition = rmove.test(notation) || reposition; + redraw = rdraw.test(notation) || redraw; + }); + + // Re-sanitize options + sanitizeOptions(options); + + /* + * Execute any valid callbacks for the set options + * Also set isPositioning/isDrawing so we don't get loads of redundant repositioning + * and redraw calls. + */ + isPositioning = isDrawing = 1; $.each(option, callback); isPositioning = isDrawing = 0; + + // Update position / redraw if needed + if(self.rendered && tooltip[0].offsetWidth > 0) { + if(reposition) { + self.reposition( options.position.target === 'mouse' ? NULL : cache.event ); + } + if(redraw) { self.redraw(); } + } + + return self; + }, + + toggle: function(state, event) + { + // Render the tooltip if showing and it isn't already + if(!self.rendered) { return state ? self.render(1) : self; } + + var type = state ? 'show' : 'hide', + opts = options[type], + otherOpts = options[ !state ? 'show' : 'hide' ], + posOptions = options.position, + contentOptions = options.content, + visible = tooltip[0].offsetWidth > 0, + animate = state || opts.target.length === 1, + sameTarget = !event || opts.target.length < 2 || cache.target[0] === event.target, + delay, callback; + + // Detect state if valid one isn't provided + if((typeof state).search('boolean|number')) { state = !visible; } + + // Return if element is already in correct state + if(!tooltip.is(':animated') && visible === state && sameTarget) { return self; } + + // Try to prevent flickering when tooltip overlaps show element + if(event) { + if((/over|enter/).test(event.type) && (/out|leave/).test(cache.event.type) && + options.show.target.add(event.target).length === options.show.target.length && + tooltip.has(event.relatedTarget).length) { + return self; + } + + // Cache event + cache.event = $.extend({}, event); + } + + // Call API methods + callback = $.Event('tooltip'+type); + callback.originalEvent = event ? cache.event : NULL; + tooltip.trigger(callback, [self, 90]); + if(callback.isDefaultPrevented()){ return self; } + + // Set ARIA hidden status attribute + $.attr(tooltip[0], 'aria-hidden', !!!state); + + // Execute state specific properties + if(state) { + // Store show origin coordinates + cache.origin = $.extend({}, MOUSE); + + // Focus the tooltip + self.focus(event); + + // Update tooltip content & title if it's a dynamic function + if($.isFunction(contentOptions.text)) { updateContent(contentOptions.text, FALSE); } + if($.isFunction(contentOptions.title.text)) { updateTitle(contentOptions.title.text, FALSE); } + + // Cache mousemove events for positioning purposes (if not already tracking) + if(!trackingBound && posOptions.target === 'mouse' && posOptions.adjust.mouse) { + $(document).bind('mousemove.qtip', function(event) { + MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' }; + }); + trackingBound = TRUE; + } + + // Update the tooltip position + self.reposition(event, arguments[2]); + + // Hide other tooltips if tooltip is solo, using it as the context + if((callback.solo = !!opts.solo)) { $(selector, opts.solo).not(tooltip).qtip('hide', callback); } + } + else { + // Clear show timer if we're hiding + clearTimeout(self.timers.show); + + // Remove cached origin on hide + delete cache.origin; + + // Remove mouse tracking event if not needed (all tracking qTips are hidden) + if(trackingBound && !$(selector+'[tracking="true"]:visible', opts.solo).not(tooltip).length) { + $(document).unbind('mousemove.qtip'); + trackingBound = FALSE; + } + + // Blur the tooltip + self.blur(event); + } + + // Define post-animation, state specific properties + function after() { + if(state) { + // Prevent antialias from disappearing in IE by removing filter + if($.browser.msie) { tooltip[0].style.removeAttribute('filter'); } + + // Remove overflow setting to prevent tip bugs + tooltip.css('overflow', ''); + + // Autofocus elements if enabled + if('string' === typeof opts.autofocus) { + $(opts.autofocus, tooltip).focus(); + } + + // If set, hide tooltip when inactive for delay period + opts.target.trigger('qtip-'+id+'-inactive'); + } + else { + // Reset CSS states + tooltip.css({ + display: '', + visibility: '', + opacity: '', + left: '', + top: '' + }); + } + + // Call API method + callback = $.Event('tooltip'+(state ? 'visible' : 'hidden')); + callback.originalEvent = event ? cache.event : NULL; + tooltip.trigger(callback, [self]); + } + + // If no effect type is supplied, use a simple toggle + if(opts.effect === FALSE || animate === FALSE) { + tooltip[ type ](); + after.call(tooltip); + } + + // Use custom function if provided + else if($.isFunction(opts.effect)) { + tooltip.stop(1, 1); + opts.effect.call(tooltip, self); + tooltip.queue('fx', function(n){ after(); n(); }); + } + + // Use basic fade function by default + else { tooltip.fadeTo(90, state ? 1 : 0, after); } + + // If inactive hide method is set, active it + if(state) { opts.target.trigger('qtip-'+id+'-inactive'); } + + return self; + }, + + show: function(event){ return self.toggle(TRUE, event); }, + + hide: function(event){ return self.toggle(FALSE, event); }, + + focus: function(event) + { + if(!self.rendered) { return self; } + + var qtips = $(selector), + curIndex = parseInt(tooltip[0].style.zIndex, 10), + newIndex = QTIP.zindex + qtips.length, + cachedEvent = $.extend({}, event), + focusedElem, callback; + + // Only update the z-index if it has changed and tooltip is not already focused + if(!tooltip.hasClass(focusClass)) + { + // Call API method + callback = $.Event('tooltipfocus'); + callback.originalEvent = cachedEvent; + tooltip.trigger(callback, [self, newIndex]); + + // If default action wasn't prevented... + if(!callback.isDefaultPrevented()) { + // Only update z-index's if they've changed + if(curIndex !== newIndex) { + // Reduce our z-index's and keep them properly ordered + qtips.each(function() { + if(this.style.zIndex > curIndex) { + this.style.zIndex = this.style.zIndex - 1; + } + }); + + // Fire blur event for focused tooltip + qtips.filter('.' + focusClass).qtip('blur', cachedEvent); + } + + // Set the new z-index + tooltip.addClass(focusClass)[0].style.zIndex = newIndex; + } + } + + return self; + }, + + blur: function(event) { + var cachedEvent = $.extend({}, event), + callback; + + // Set focused status to FALSE + tooltip.removeClass(focusClass); + + // Trigger blur event + callback = $.Event('tooltipblur'); + callback.originalEvent = cachedEvent; + tooltip.trigger(callback, [self]); + + return self; + }, + + reposition: function(event, effect) + { + if(!self.rendered || isPositioning) { return self; } + + // Set positioning flag + isPositioning = 1; + + var target = options.position.target, + posOptions = options.position, + my = posOptions.my, + at = posOptions.at, + adjust = posOptions.adjust, + method = adjust.method.split(' '), + elemWidth = tooltip.outerWidth(), + elemHeight = tooltip.outerHeight(), + targetWidth = 0, + targetHeight = 0, + callback = $.Event('tooltipmove'), + fixed = tooltip.css('position') === 'fixed', + viewport = posOptions.viewport, + position = { left: 0, top: 0 }, + container = posOptions.container, + visible = tooltip[0].offsetWidth > 0, + adjusted, offset, win; + + // Check if absolute position was passed + if($.isArray(target) && target.length === 2) { + // Force left top and set position + at = { x: LEFT, y: TOP }; + position = { left: target[0], top: target[1] }; + } + + // Check if mouse was the target + else if(target === 'mouse' && ((event && event.pageX) || cache.event.pageX)) { + // Force left top to allow flipping + at = { x: LEFT, y: TOP }; + + // Use cached event if one isn't available for positioning + event = (event && (event.type === 'resize' || event.type === 'scroll') ? cache.event : + event && event.pageX && event.type === 'mousemove' ? event : + MOUSE && MOUSE.pageX && (adjust.mouse || !event || !event.pageX) ? { pageX: MOUSE.pageX, pageY: MOUSE.pageY } : + !adjust.mouse && cache.origin && cache.origin.pageX && options.show.distance ? cache.origin : + event) || event || cache.event || MOUSE || {}; + + // Use event coordinates for position + position = { top: event.pageY, left: event.pageX }; + } + + // Target wasn't mouse or absolute... + else { + // Check if event targetting is being used + if(target === 'event' && event && event.target && event.type !== 'scroll' && event.type !== 'resize') { + cache.target = $(event.target); + } + else if(target !== 'event'){ + cache.target = $(target.jquery ? target : elements.target); + } + target = cache.target; + + // Parse the target into a jQuery object and make sure there's an element present + target = $(target).eq(0); + if(target.length === 0) { return self; } + + // Check if window or document is the target + else if(target[0] === document || target[0] === window) { + targetWidth = PLUGINS.iOS ? window.innerWidth : target.width(); + targetHeight = PLUGINS.iOS ? window.innerHeight : target.height(); + + if(target[0] === window) { + position = { + top: (viewport || target).scrollTop(), + left: (viewport || target).scrollLeft() + }; + } + } + + // Use Imagemap/SVG plugins if needed + else if(PLUGINS.imagemap && target.is('area')) { + adjusted = PLUGINS.imagemap(self, target, at, PLUGINS.viewport ? method : FALSE); + } + else if(PLUGINS.svg && typeof target[0].xmlbase === 'string') { + adjusted = PLUGINS.svg(self, target, at, PLUGINS.viewport ? method : FALSE); + } + + else { + targetWidth = target.outerWidth(); + targetHeight = target.outerHeight(); + + position = PLUGINS.offset(target, container); + } + + // Parse returned plugin values into proper variables + if(adjusted) { + targetWidth = adjusted.width; + targetHeight = adjusted.height; + offset = adjusted.offset; + position = adjusted.position; + } + + // Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2) + if((PLUGINS.iOS > 3.1 && PLUGINS.iOS < 4.1) || + (PLUGINS.iOS >= 4.3 && PLUGINS.iOS < 4.33) || + (!PLUGINS.iOS && fixed) + ){ + win = $(window); + position.left -= win.scrollLeft(); + position.top -= win.scrollTop(); + } + + // Adjust position relative to target + position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0; + position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0; + } + + // Adjust position relative to tooltip + position.left += adjust.x + (my.x === RIGHT ? -elemWidth : my.x === CENTER ? -elemWidth / 2 : 0); + position.top += adjust.y + (my.y === BOTTOM ? -elemHeight : my.y === CENTER ? -elemHeight / 2 : 0); + + // Use viewport adjustment plugin if enabled + if(PLUGINS.viewport) { + position.adjusted = PLUGINS.viewport( + self, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight + ); + + // Apply offsets supplied by positioning plugin (if used) + if(offset && position.adjusted.left) { position.left += offset.left; } + if(offset && position.adjusted.top) { position.top += offset.top; } + } + + // Viewport adjustment is disabled, set values to zero + else { position.adjusted = { left: 0, top: 0 }; } + + // Call API method + callback.originalEvent = $.extend({}, event); + tooltip.trigger(callback, [self, position, viewport.elem || viewport]); + if(callback.isDefaultPrevented()){ return self; } + delete position.adjusted; + + // If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly + if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) { + tooltip.css(position); + } + + // Use custom function if provided + else if($.isFunction(posOptions.effect)) { + posOptions.effect.call(tooltip, self, $.extend({}, position)); + tooltip.queue(function(next) { + // Reset attributes to avoid cross-browser rendering bugs + $(this).css({ opacity: '', height: '' }); + if($.browser.msie) { this.style.removeAttribute('filter'); } + + next(); + }); + } + + // Set positioning flag + isPositioning = 0; + + return self; + }, + + // Max/min width simulator function for all browsers.. yeaaah! + redraw: function() + { + if(self.rendered < 1 || isDrawing) { return self; } + + var container = options.position.container, + perc, width, max, min; + + // Set drawing flag + isDrawing = 1; + + // If tooltip has a set height, just set it... like a boss! + if(options.style.height) { tooltip.css(HEIGHT, options.style.height); } + + // If tooltip has a set width, just set it... like a boss! + if(options.style.width) { tooltip.css(WIDTH, options.style.width); } + + // Otherwise simualte max/min width... + else { + // Reset width and add fluid class + tooltip.css(WIDTH, '').addClass(fluidClass); + + // Grab our tooltip width (add 1 so we don't get wrapping problems.. huzzah!) + width = tooltip.width() + 1; + + // Grab our max/min properties + max = tooltip.css('max-width') || ''; + min = tooltip.css('min-width') || ''; + + // Parse into proper pixel values + perc = (max + min).indexOf('%') > -1 ? container.width() / 100 : 0; + max = ((max.indexOf('%') > -1 ? perc : 1) * parseInt(max, 10)) || width; + min = ((min.indexOf('%') > -1 ? perc : 1) * parseInt(min, 10)) || 0; + + // Determine new dimension size based on max/min/current values + width = max + min ? Math.min(Math.max(width, min), max) : width; + + // Set the newly calculated width and remvoe fluid class + tooltip.css(WIDTH, Math.round(width)).removeClass(fluidClass); + } + + // Set drawing flag + isDrawing = 0; + + return self; + }, + + disable: function(state) + { + if('boolean' !== typeof state) { + state = !(tooltip.hasClass(disabled) || cache.disabled); + } + + if(self.rendered) { + tooltip.toggleClass(disabled, state); + $.attr(tooltip[0], 'aria-disabled', state); + } + else { + cache.disabled = !!state; + } + + return self; + }, + + enable: function() { return self.disable(FALSE); }, + + destroy: function() + { + var t = target[0], + title = $.attr(t, oldtitle), + elemAPI = target.data('qtip'); + + // Set flag the signify destroy is taking place to plugins + self.destroyed = TRUE; + + // Destroy tooltip and any associated plugins if rendered + if(self.rendered) { + tooltip.stop(1,0).remove(); + + $.each(self.plugins, function() { + if(this.destroy) { this.destroy(); } + }); + } + + // Clear timers and remove bound events + clearTimeout(self.timers.show); + clearTimeout(self.timers.hide); + unassignEvents(); + + // If the API if actually this qTip API... + if(!elemAPI || self === elemAPI) { + // Remove api object + $.removeData(t, 'qtip'); + + // Reset old title attribute if removed + if(options.suppress && title) { + $.attr(t, 'title', title); + target.removeAttr(oldtitle); + } + + // Remove ARIA attributes + target.removeAttr('aria-describedby'); + } + + // Remove qTip events associated with this API + target.unbind('.qtip-'+id); + + // Remove ID from sued id object + delete usedIDs[self.id]; + + return target; + } + }); +} + +// Initialization method +function init(id, opts) +{ + var obj, posOptions, attr, config, title, + + // Setup element references + elem = $(this), + docBody = $(document.body), + + // Use document body instead of document element if needed + newTarget = this === document ? docBody : elem, + + // Grab metadata from element if plugin is present + metadata = (elem.metadata) ? elem.metadata(opts.metadata) : NULL, + + // If metadata type if HTML5, grab 'name' from the object instead, or use the regular data object otherwise + metadata5 = opts.metadata.type === 'html5' && metadata ? metadata[opts.metadata.name] : NULL, + + // Grab data from metadata.name (or data-qtipopts as fallback) using .data() method, + html5 = elem.data(opts.metadata.name || 'qtipopts'); + + // If we don't get an object returned attempt to parse it manualyl without parseJSON + try { html5 = typeof html5 === 'string' ? (new Function("return " + html5))() : html5; } + catch(e) { log('Unable to parse HTML5 attribute data: ' + html5); } + + // Merge in and sanitize metadata + config = $.extend(TRUE, {}, QTIP.defaults, opts, + typeof html5 === 'object' ? sanitizeOptions(html5) : NULL, + sanitizeOptions(metadata5 || metadata)); + + // Re-grab our positioning options now we've merged our metadata and set id to passed value + posOptions = config.position; + config.id = id; + + // Setup missing content if none is detected + if('boolean' === typeof config.content.text) { + attr = elem.attr(config.content.attr); + + // Grab from supplied attribute if available + if(config.content.attr !== FALSE && attr) { config.content.text = attr; } + + // No valid content was found, abort render + else { + log('Unable to locate content for tooltip! Aborting render of tooltip on element: ', elem); + return FALSE; + } + } + + // Setup target options + if(!posOptions.container.length) { posOptions.container = docBody; } + if(posOptions.target === FALSE) { posOptions.target = newTarget; } + if(config.show.target === FALSE) { config.show.target = newTarget; } + if(config.show.solo === TRUE) { config.show.solo = posOptions.container.closest('body'); } + if(config.hide.target === FALSE) { config.hide.target = newTarget; } + if(config.position.viewport === TRUE) { config.position.viewport = posOptions.container; } + + // Ensure we only use a single container + posOptions.container = posOptions.container.eq(0); + + // Convert position corner values into x and y strings + posOptions.at = new PLUGINS.Corner(posOptions.at); + posOptions.my = new PLUGINS.Corner(posOptions.my); + + // Destroy previous tooltip if overwrite is enabled, or skip element if not + if($.data(this, 'qtip')) { + if(config.overwrite) { + elem.qtip('destroy'); + } + else if(config.overwrite === FALSE) { + return FALSE; + } + } + + // Remove title attribute and store it if present + if(config.suppress && (title = $.attr(this, 'title'))) { + // Final attr call fixes event delegatiom and IE default tooltip showing problem + $(this).removeAttr('title').attr(oldtitle, title).attr('title', ''); + } + + // Initialize the tooltip and add API reference + obj = new QTip(elem, config, id, !!attr); + $.data(this, 'qtip', obj); + + // Catch remove/removeqtip events on target element to destroy redundant tooltip + elem.bind('remove.qtip-'+id+' removeqtip.qtip-'+id, function(){ obj.destroy(); }); + + return obj; +} + +// jQuery $.fn extension method +QTIP = $.fn.qtip = function(options, notation, newValue) +{ + var command = ('' + options).toLowerCase(), // Parse command + returned = NULL, + args = $.makeArray(arguments).slice(1), + event = args[args.length - 1], + opts = this[0] ? $.data(this[0], 'qtip') : NULL; + + // Check for API request + if((!arguments.length && opts) || command === 'api') { + return opts; + } + + // Execute API command if present + else if('string' === typeof options) + { + this.each(function() + { + var api = $.data(this, 'qtip'); + if(!api) { return TRUE; } + + // Cache the event if possible + if(event && event.timeStamp) { api.cache.event = event; } + + // Check for specific API commands + if((command === 'option' || command === 'options') && notation) { + if($.isPlainObject(notation) || newValue !== undefined) { + api.set(notation, newValue); + } + else { + returned = api.get(notation); + return FALSE; + } + } + + // Execute API command + else if(api[command]) { + api[command].apply(api[command], args); + } + }); + + return returned !== NULL ? returned : this; + } + + // No API commands. validate provided options and setup qTips + else if('object' === typeof options || !arguments.length) + { + opts = sanitizeOptions($.extend(TRUE, {}, options)); + + // Bind the qTips + return QTIP.bind.call(this, opts, event); + } +}; + +// $.fn.qtip Bind method +QTIP.bind = function(opts, event) +{ + return this.each(function(i) { + var options, targets, events, namespace, api, id; + + // Find next available ID, or use custom ID if provided + id = $.isArray(opts.id) ? opts.id[i] : opts.id; + id = !id || id === FALSE || id.length < 1 || usedIDs[id] ? QTIP.nextid++ : (usedIDs[id] = id); + + // Setup events namespace + namespace = '.qtip-'+id+'-create'; + + // Initialize the qTip and re-grab newly sanitized options + api = init.call(this, id, opts); + if(api === FALSE) { return TRUE; } + options = api.options; + + // Initialize plugins + $.each(PLUGINS, function() { + if(this.initialize === 'initialize') { this(api); } + }); + + // Determine hide and show targets + targets = { show: options.show.target, hide: options.hide.target }; + events = { + show: $.trim('' + options.show.event).replace(/ /g, namespace+' ') + namespace, + hide: $.trim('' + options.hide.event).replace(/ /g, namespace+' ') + namespace + }; + + /* + * Make sure hoverIntent functions properly by using mouseleave as a hide event if + * mouseenter/mouseout is used for show.event, even if it isn't in the users options. + */ + if(/mouse(over|enter)/i.test(events.show) && !/mouse(out|leave)/i.test(events.hide)) { + events.hide += ' mouseleave' + namespace; + } + + /* + * Also make sure initial mouse targetting works correctly by caching mousemove coords + * on show targets before the tooltip has rendered. + * + * Also set onTarget when triggered to keep mouse tracking working + */ + targets.show.bind('mousemove'+namespace, function(event) { + MOUSE = { pageX: event.pageX, pageY: event.pageY, type: 'mousemove' }; + api.cache.onTarget = TRUE; + }); + + // Define hoverIntent function + function hoverIntent(event) { + function render() { + // Cache mouse coords,render and render the tooltip + api.render(typeof event === 'object' || options.show.ready); + + // Unbind show and hide events + targets.show.add(targets.hide).unbind(namespace); + } + + // Only continue if tooltip isn't disabled + if(api.cache.disabled) { return FALSE; } + + // Cache the event data + api.cache.event = $.extend({}, event); + api.cache.target = event ? $(event.target) : [undefined]; + + // Start the event sequence + if(options.show.delay > 0) { + clearTimeout(api.timers.show); + api.timers.show = setTimeout(render, options.show.delay); + if(events.show !== events.hide) { + targets.hide.bind(events.hide, function() { clearTimeout(api.timers.show); }); + } + } + else { render(); } + } + + // Bind show events to target + targets.show.bind(events.show, hoverIntent); + + // Prerendering is enabled, create tooltip now + if(options.show.ready || options.prerender) { hoverIntent(event); } + }); +}; + +// Setup base plugins +PLUGINS = QTIP.plugins = { + // Corner object parser + Corner: function(corner) { + corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase(); + this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase(); + this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase(); + + var f = corner.charAt(0); this.precedance = (f === 't' || f === 'b' ? Y : X); + + this.string = function() { return this.precedance === Y ? this.y+this.x : this.x+this.y; }; + this.abbrev = function() { + var x = this.x.substr(0,1), y = this.y.substr(0,1); + return x === y ? x : this.precedance === Y ? y + x : x + y; + }; + + this.invertx = function(center) { this.x = this.x === LEFT ? RIGHT : this.x === RIGHT ? LEFT : center || this.x; }; + this.inverty = function(center) { this.y = this.y === TOP ? BOTTOM : this.y === BOTTOM ? TOP : center || this.y; }; + + this.clone = function() { + return { + x: this.x, y: this.y, precedance: this.precedance, + string: this.string, abbrev: this.abbrev, clone: this.clone, + invertx: this.invertx, inverty: this.inverty + }; + }; + }, + + // Custom (more correct for qTip!) offset calculator + offset: function(elem, container) { + var pos = elem.offset(), + docBody = elem.closest('body')[0], + parent = container, scrolled, + coffset, overflow; + + function scroll(e, i) { + pos.left += i * e.scrollLeft(); + pos.top += i * e.scrollTop(); + } + + if(parent) { + // Compensate for non-static containers offset + do { + if(parent.css('position') !== 'static') { + coffset = parent.position(); + + // Account for element positioning, borders and margins + pos.left -= coffset.left + (parseInt(parent.css('borderLeftWidth'), 10) || 0) + (parseInt(parent.css('marginLeft'), 10) || 0); + pos.top -= coffset.top + (parseInt(parent.css('borderTopWidth'), 10) || 0) + (parseInt(parent.css('marginTop'), 10) || 0); + + // If this is the first parent element with an overflow of "scroll" or "auto", store it + if(!scrolled && (overflow = parent.css('overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = parent; } + } + } + while((parent = $(parent[0].offsetParent)).length); + + // Compensate for containers scroll if it also has an offsetParent + if(scrolled && scrolled[0] !== docBody) { scroll( scrolled, 1 ); } + } + + return pos; + }, + + /* + * iOS version detection + */ + iOS: parseFloat( + ('' + (/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0,''])[1]) + .replace('undefined', '3_2').replace('_', '.').replace('_', '') + ) || FALSE, + + /* + * jQuery-specific $.fn overrides + */ + fn: { + /* Allow other plugins to successfully retrieve the title of an element with a qTip applied */ + attr: function(attr, val) { + if(this.length) { + var self = this[0], + title = 'title', + api = $.data(self, 'qtip'); + + if(attr === title && api && 'object' === typeof api && api.options.suppress) { + if(arguments.length < 2) { + return $.attr(self, oldtitle); + } + else { + // If qTip is rendered and title was originally used as content, update it + if(api && api.options.content.attr === title && api.cache.attr) { + api.set('content.text', val); + } + + // Use the regular attr method to set, then cache the result + return this.attr(oldtitle, val); + } + } + } + + return $.fn['attr'+replaceSuffix].apply(this, arguments); + }, + + /* Allow clone to correctly retrieve cached title attributes */ + clone: function(keepData) { + var titles = $([]), title = 'title', + + // Clone our element using the real clone method + elems = $.fn['clone'+replaceSuffix].apply(this, arguments); + + // Grab all elements with an oldtitle set, and change it to regular title attribute, if keepData is false + if(!keepData) { + elems.filter('['+oldtitle+']').attr('title', function() { + return $.attr(this, oldtitle); + }) + .removeAttr(oldtitle); + } + + return elems; + } + } +}; + +// Apply the fn overrides above +$.each(PLUGINS.fn, function(name, func) { + if(!func || $.fn[name+replaceSuffix]) { return TRUE; } + + var old = $.fn[name+replaceSuffix] = $.fn[name]; + $.fn[name] = function() { + return func.apply(this, arguments) || old.apply(this, arguments); + }; +}); + +/* Fire off 'removeqtip' handler in $.cleanData if jQuery UI not present (it already does similar). + * This snippet is taken directly from jQuery UI source code found here: + * http://code.jquery.com/ui/jquery-ui-git.js + */ +if(!$.ui) { + $['cleanData'+replaceSuffix] = $.cleanData; + $.cleanData = function( elems ) { + for(var i = 0, elem; (elem = elems[i]) !== undefined; i++) { + try { $( elem ).triggerHandler('removeqtip'); } + catch( e ) {} + } + $['cleanData'+replaceSuffix]( elems ); + }; +} + +// Set global qTip properties +QTIP.version = 'nightly'; +QTIP.nextid = 0; +QTIP.inactiveEvents = 'click dblclick mousedown mouseup mousemove mouseleave mouseenter'.split(' '); +QTIP.zindex = 15000; + +// Define configuration defaults +QTIP.defaults = { + prerender: FALSE, + id: FALSE, + overwrite: TRUE, + suppress: TRUE, + content: { + text: TRUE, + attr: 'title', + title: { + text: FALSE, + button: FALSE + } + }, + position: { + my: 'top left', + at: 'bottom right', + target: FALSE, + container: FALSE, + viewport: FALSE, + adjust: { + x: 0, y: 0, + mouse: TRUE, + resize: TRUE, + method: 'flip flip' + }, + effect: function(api, pos, viewport) { + $(this).animate(pos, { + duration: 200, + queue: FALSE + }); + } + }, + show: { + target: FALSE, + event: 'mouseenter', + effect: TRUE, + delay: 90, + solo: FALSE, + ready: FALSE, + autofocus: FALSE + }, + hide: { + target: FALSE, + event: 'mouseleave', + effect: TRUE, + delay: 0, + fixed: FALSE, + inactive: FALSE, + leave: 'window', + distance: FALSE + }, + style: { + classes: '', + widget: FALSE, + width: FALSE, + height: FALSE, + def: TRUE + }, + events: { + render: NULL, + move: NULL, + show: NULL, + hide: NULL, + toggle: NULL, + visible: NULL, + hidden: NULL, + focus: NULL, + blur: NULL + } +}; + +function Ajax(api) +{ + var self = this, + tooltip = api.elements.tooltip, + opts = api.options.content.ajax, + defaults = QTIP.defaults.content.ajax, + namespace = '.qtip-ajax', + rscript = /)<[^<]*)*<\/script>/gi, + first = TRUE, + stop = FALSE, + xhr; + + api.checks.ajax = { + '^content.ajax': function(obj, name, v) { + // If content.ajax object was reset, set our local var + if(name === 'ajax') { opts = v; } + + if(name === 'once') { + self.init(); + } + else if(opts && opts.url) { + self.load(); + } + else { + tooltip.unbind(namespace); + } + } + }; + + $.extend(self, { + init: function() { + // Make sure ajax options are enabled and bind event + if(opts && opts.url) { + tooltip.unbind(namespace)[ opts.once ? 'one' : 'bind' ]('tooltipshow'+namespace, self.load); + } + + return self; + }, + + load: function(event) { + if(stop) {stop = FALSE; return; } + + var hasSelector = opts.url.indexOf(' '), + url = opts.url, + selector, + hideFirst = !opts.loading && first; + + // If loading option is disabled, prevent the tooltip showing until we've completed the request + if(hideFirst) { try{ event.preventDefault(); } catch(e) {} } + + // Make sure default event hasn't been prevented + else if(event && event.isDefaultPrevented()) { return self; } + + // Cancel old request + if(xhr && xhr.abort) { xhr.abort(); } + + // Check if user delcared a content selector like in .load() + if(hasSelector > -1) { + selector = url.substr(hasSelector); + url = url.substr(0, hasSelector); + } + + // Define common after callback for both success/error handlers + function after() { + var complete; + + // Don't proceed if tooltip is destroyed + if(api.destroyed) { return; } + + // Set first flag to false + first = FALSE; + + // Re-display tip if loading and first time, and reset first flag + if(hideFirst) { stop = TRUE; api.show(event.originalEvent); } + + // Call users complete method if it was defined + if((complete = defaults.complete || opts.complete) && $.isFunction(complete)) { + complete.apply(opts.context || api, arguments); + } + } + + // Define success handler + function successHandler(content, status, jqXHR) { + var success; + + // Don't proceed if tooltip is destroyed + if(api.destroyed) { return; } + + if(selector) { + // Create a dummy div to hold the results and grab the selector element + content = $('
') + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append(content.replace(rscript, "")) + + // Locate the specified elements + .find(selector); + } + + // Call the success function if one is defined + if((success = defaults.success || opts.success) && $.isFunction(success)) { + success.call(opts.context || api, content, status, jqXHR); + } + + // Otherwise set the content + else { api.set('content.text', content); } + } + + // Error handler + function errorHandler(xhr, status, error) { + if(api.destroyed || xhr.status === 0) { return; } + api.set('content.text', status + ': ' + error); + } + + // Setup $.ajax option object and process the request + xhr = $.ajax( + $.extend({ + error: defaults.error || errorHandler, + context: api + }, + opts, { url: url, success: successHandler, complete: after }) + ); + }, + + destroy: function() { + // Cancel ajax request if possible + if(xhr && xhr.abort) { xhr.abort(); } + + // Set api.destroyed flag + api.destroyed = TRUE; + } + }); + + self.init(); +} + + +PLUGINS.ajax = function(api) +{ + var self = api.plugins.ajax; + + return 'object' === typeof self ? self : (api.plugins.ajax = new Ajax(api)); +}; + +PLUGINS.ajax.initialize = 'render'; + +// Setup plugin sanitization +PLUGINS.ajax.sanitize = function(options) +{ + var content = options.content, opts; + if(content && 'ajax' in content) { + opts = content.ajax; + if(typeof opts !== 'object') { opts = options.content.ajax = { url: opts }; } + if('boolean' !== typeof opts.once && opts.once) { opts.once = !!opts.once; } + } +}; + +// Extend original api defaults +$.extend(TRUE, QTIP.defaults, { + content: { + ajax: { + loading: TRUE, + once: TRUE + } + } +}); + +PLUGINS.viewport = function(api, position, posOptions, targetWidth, targetHeight, elemWidth, elemHeight) +{ + var target = posOptions.target, + tooltip = api.elements.tooltip, + my = posOptions.my, + at = posOptions.at, + adjust = posOptions.adjust, + method = adjust.method.split(' '), + methodX = method[0], + methodY = method[1] || method[0], + viewport = posOptions.viewport, + container = posOptions.container, + cache = api.cache, + tip = api.plugins.tip, + adjusted = { left: 0, top: 0 }, + fixed, newMy, newClass; + + // If viewport is not a jQuery element, or it's the window/document or no adjustment method is used... return + if(!viewport.jquery || target[0] === window || target[0] === document.body || adjust.method === 'none') { + return adjusted; + } + + // Cache our viewport details + fixed = tooltip.css('position') === 'fixed'; + viewport = { + elem: viewport, + height: viewport[ (viewport[0] === window ? 'h' : 'outerH') + 'eight' ](), + width: viewport[ (viewport[0] === window ? 'w' : 'outerW') + 'idth' ](), + scrollleft: fixed ? 0 : viewport.scrollLeft(), + scrolltop: fixed ? 0 : viewport.scrollTop(), + offset: viewport.offset() || { left: 0, top: 0 } + }; + container = { + elem: container, + scrollLeft: container.scrollLeft(), + scrollTop: container.scrollTop(), + offset: container.offset() || { left: 0, top: 0 } + }; + + // Generic calculation method + function calculate(side, otherSide, type, adjust, side1, side2, lengthName, targetLength, elemLength) { + var initialPos = position[side1], + mySide = my[side], atSide = at[side], + isShift = type === SHIFT, + viewportScroll = -container.offset[side1] + viewport.offset[side1] + viewport['scroll'+side1], + myLength = mySide === side1 ? elemLength : mySide === side2 ? -elemLength : -elemLength / 2, + atLength = atSide === side1 ? targetLength : atSide === side2 ? -targetLength : -targetLength / 2, + tipLength = tip && tip.size ? tip.size[lengthName] || 0 : 0, + tipAdjust = tip && tip.corner && tip.corner.precedance === side && !isShift ? tipLength : 0, + overflow1 = viewportScroll - initialPos + tipAdjust, + overflow2 = initialPos + elemLength - viewport[lengthName] - viewportScroll + tipAdjust, + offset = myLength - (my.precedance === side || mySide === my[otherSide] ? atLength : 0) - (atSide === CENTER ? targetLength / 2 : 0); + + // shift + if(isShift) { + tipAdjust = tip && tip.corner && tip.corner.precedance === otherSide ? tipLength : 0; + offset = (mySide === side1 ? 1 : -1) * myLength - tipAdjust; + + // Adjust position but keep it within viewport dimensions + position[side1] += overflow1 > 0 ? overflow1 : overflow2 > 0 ? -overflow2 : 0; + position[side1] = Math.max( + -container.offset[side1] + viewport.offset[side1] + (tipAdjust && tip.corner[side] === CENTER ? tip.offset : 0), + initialPos - offset, + Math.min( + Math.max(-container.offset[side1] + viewport.offset[side1] + viewport[lengthName], initialPos + offset), + position[side1] + ) + ); + } + + // flip/flipinvert + else { + // Update adjustment amount depending on if using flipinvert or flip + adjust *= (type === FLIPINVERT ? 2 : 0); + + // Check for overflow on the left/top + if(overflow1 > 0 && (mySide !== side1 || overflow2 > 0)) { + position[side1] -= offset + adjust; + newMy['invert'+side](side1); + } + + // Check for overflow on the bottom/right + else if(overflow2 > 0 && (mySide !== side2 || overflow1 > 0) ) { + position[side1] -= (mySide === CENTER ? -offset : offset) + adjust; + newMy['invert'+side](side2); + } + + // Make sure we haven't made things worse with the adjustment and reset if so + if(position[side1] < viewportScroll && -position[side1] > overflow2) { + position[side1] = initialPos; newMy = undefined; + } + } + + return position[side1] - initialPos; + } + + // Set newMy if using flip or flipinvert methods + if(methodX !== 'shift' || methodY !== 'shift') { newMy = my.clone(); } + + // Adjust position based onviewport and adjustment options + adjusted = { + left: methodX !== 'none' ? calculate( X, Y, methodX, adjust.x, LEFT, RIGHT, WIDTH, targetWidth, elemWidth ) : 0, + top: methodY !== 'none' ? calculate( Y, X, methodY, adjust.y, TOP, BOTTOM, HEIGHT, targetHeight, elemHeight ) : 0 + }; + + // Set tooltip position class if it's changed + if(newMy && cache.lastClass !== (newClass = uitooltip + '-pos-' + newMy.abbrev())) { + tooltip.removeClass(api.cache.lastClass).addClass( (api.cache.lastClass = newClass) ); + } + + return adjusted; +};function Modal(api) +{ + var self = this, + options = api.options.show.modal, + elems = api.elements, + tooltip = elems.tooltip, + overlaySelector = '#qtip-overlay', + globalNamespace = '.qtipmodal', + namespace = globalNamespace + api.id, + attr = 'is-modal-qtip', + docBody = $(document.body), + focusableSelector = PLUGINS.modal.focusable.join(','), + focusableElems = {}, overlay; + + // Setup option set checks + api.checks.modal = { + '^show.modal.(on|blur)$': function() { + // Initialise + self.init(); + + // Show the modal if not visible already and tooltip is visible + elems.overlay.toggle( tooltip.is(':visible') ); + }, + '^content.text$': updateFocusable + }; + + function updateFocusable() { + focusableElems = $(focusableSelector, tooltip).not('[disabled]').map(function() { + return typeof this.focus === 'function' ? this : null; + }); + } + + function focusInputs(blurElems) { + // Blurring body element in IE causes window.open windows to unfocus! + if(focusableElems.length < 1 && blurElems.length) { blurElems.not('body').blur(); } + + // Focus the inputs + else { focusableElems.first().focus(); } + } + + function stealFocus(event) { + var target = $(event.target), + container = target.closest('.qtip'), + targetOnTop; + + // Determine if input container target is above this + targetOnTop = container.length < 1 ? FALSE : + (parseInt(container[0].style.zIndex, 10) > parseInt(tooltip[0].style.zIndex, 10)); + + // If we're showing a modal, but focus has landed on an input below + // this modal, divert focus to the first visible input in this modal + // or if we can't find one... the tooltip itself + if(!targetOnTop && ($(event.target).closest(selector)[0] !== tooltip[0])) { + focusInputs(target); + } + } + + $.extend(self, { + init: function() + { + // If modal is disabled... return + if(!options.on) { return self; } + + // Create the overlay if needed + overlay = self.create(); + + // Add unique attribute so we can grab modal tooltips easily via a selector + tooltip.attr(attr, TRUE) + + // Set z-index + .css('z-index', PLUGINS.modal.zindex + $(selector+'['+attr+']').length) + + // Remove previous bound events in globalNamespace + .unbind(globalNamespace).unbind(namespace) + + // Apply our show/hide/focus modal events + .bind('tooltipshow'+globalNamespace+' tooltiphide'+globalNamespace, function(event, api, duration) { + var oEvent = event.originalEvent; + + // Make sure mouseout doesn't trigger a hide when showing the modal and mousing onto backdrop + if(event.target === tooltip[0]) { + if(oEvent && event.type === 'tooltiphide' && /mouse(leave|enter)/.test(oEvent.type) && $(oEvent.relatedTarget).closest(overlay[0]).length) { + try { event.preventDefault(); } catch(e) {} + } + else if(!oEvent || (oEvent && !oEvent.solo)) { + self[ event.type.replace('tooltip', '') ](event, duration); + } + } + }) + + // Adjust modal z-index on tooltip focus + .bind('tooltipfocus'+globalNamespace, function(event) { + // If focus was cancelled before it reearch us, don't do anything + if(event.isDefaultPrevented() || event.target !== tooltip[0]) { return; } + + var qtips = $(selector).filter('['+attr+']'), + + // Keep the modal's lower than other, regular qtips + newIndex = PLUGINS.modal.zindex + qtips.length, + curIndex = parseInt(tooltip[0].style.zIndex, 10); + + // Set overlay z-index + overlay[0].style.zIndex = newIndex - 2; + + // Reduce modal z-index's and keep them properly ordered + qtips.each(function() { + if(this.style.zIndex > curIndex) { + this.style.zIndex -= 1; + } + }); + + // Fire blur event for focused tooltip + qtips.end().filter('.' + focusClass).qtip('blur', event.originalEvent); + + // Set the new z-index + tooltip.addClass(focusClass)[0].style.zIndex = newIndex; + + // Prevent default handling + try { event.preventDefault(); } catch(e) {} + }) + + // Focus any other visible modals when this one hides + .bind('tooltiphide'+globalNamespace, function(event) { + if(event.target === tooltip[0]) { + $('[' + attr + ']').filter(':visible').not(tooltip).last().qtip('focus', event); + } + }); + + // Apply keyboard "Escape key" close handler + if(options.escape) { + $(document).unbind(namespace).bind('keydown'+namespace, function(event) { + if(event.keyCode === 27 && tooltip.hasClass(focusClass)) { + api.hide(event); + } + }); + } + + // Apply click handler for blur option + if(options.blur) { + elems.overlay.unbind(namespace).bind('click'+namespace, function(event) { + if(tooltip.hasClass(focusClass)) { api.hide(event); } + }); + } + + // Update focusable elements + updateFocusable(); + + return self; + }, + + create: function() + { + var elem = $(overlaySelector); + + // Return if overlay is already rendered + if(elem.length) { + // Modal overlay should always be below all tooltips if possible + return (elems.overlay = elem.insertAfter( $(selector).last() )); + } + + // Create document overlay + overlay = elems.overlay = $('
', { + id: overlaySelector.substr(1), + html: '
', + mousedown: function() { return FALSE; } + }) + .hide() + .insertAfter( $(selector).last() ); + + // Update position on window resize or scroll + function resize() { + overlay.css({ + height: $(window).height(), + width: $(window).width() + }); + } + $(window).unbind(globalNamespace).bind('resize'+globalNamespace, resize); + resize(); // Fire it initially too + + return overlay; + }, + + toggle: function(event, state, duration) + { + // Make sure default event hasn't been prevented + if(event && event.isDefaultPrevented()) { return self; } + + var effect = options.effect, + type = state ? 'show': 'hide', + visible = overlay.is(':visible'), + modals = $('[' + attr + ']').filter(':visible').not(tooltip), + zindex; + + // Create our overlay if it isn't present already + if(!overlay) { overlay = self.create(); } + + // Prevent modal from conflicting with show.solo, and don't hide backdrop is other modals are visible + if((overlay.is(':animated') && visible === state) || (!state && modals.length)) { return self; } + + // State specific... + if(state) { + // Set position + overlay.css({ left: 0, top: 0 }); + + // Toggle backdrop cursor style on show + overlay.toggleClass('blurs', options.blur); + + // IF the modal can steal the focus + if(options.stealfocus !== FALSE) { + // Make sure we can't focus anything outside the tooltip + docBody.bind('focusin'+namespace, stealFocus); + + // Blur the current item and focus anything in the modal we an + focusInputs( $('body *') ); + } + } + else { + // Undelegate focus handler + docBody.unbind('focusin'+namespace); + } + + // Stop all animations + overlay.stop(TRUE, FALSE); + + // Use custom function if provided + if($.isFunction(effect)) { + effect.call(overlay, state); + } + + // If no effect type is supplied, use a simple toggle + else if(effect === FALSE) { + overlay[ type ](); + } + + // Use basic fade function + else { + overlay.fadeTo( parseInt(duration, 10) || 90, state ? 1 : 0, function() { + if(!state) { $(this).hide(); } + }); + } + + // Reset position on hide + if(!state) { + overlay.queue(function(next) { + overlay.css({ left: '', top: '' }); + next(); + }); + } + + return self; + }, + + show: function(event, duration) { return self.toggle(event, TRUE, duration); }, + hide: function(event, duration) { return self.toggle(event, FALSE, duration); }, + + destroy: function() + { + var delBlanket = overlay; + + if(delBlanket) { + // Check if any other modal tooltips are present + delBlanket = $('[' + attr + ']').not(tooltip).length < 1; + + // Remove overlay if needed + if(delBlanket) { + elems.overlay.remove(); + $(document).unbind(globalNamespace); + } + else { + elems.overlay.unbind(globalNamespace+api.id); + } + + // Undelegate focus handler + docBody.undelegate('*', 'focusin'+namespace); + } + + // Remove bound events + return tooltip.removeAttr(attr).unbind(globalNamespace); + } + }); + + self.init(); +} + +PLUGINS.modal = function(api) { + var self = api.plugins.modal; + + return 'object' === typeof self ? self : (api.plugins.modal = new Modal(api)); +}; + +// Plugin needs to be initialized on render +PLUGINS.modal.initialize = 'render'; + +// Setup sanitiztion rules +PLUGINS.modal.sanitize = function(opts) { + if(opts.show) { + if(typeof opts.show.modal !== 'object') { opts.show.modal = { on: !!opts.show.modal }; } + else if(typeof opts.show.modal.on === 'undefined') { opts.show.modal.on = TRUE; } + } +}; + +// Base z-index for all modal tooltips (use qTip core z-index as a base) +PLUGINS.modal.zindex = QTIP.zindex + 1000; + +// Defines the selector used to select all 'focusable' elements within the modal when using the show.modal.stealfocus option. +// Selectors initially taken from http://stackoverflow.com/questions/7668525/is-there-a-jquery-selector-to-get-all-elements-that-can-get-focus +PLUGINS.modal.focusable = ['a[href]', 'area[href]', 'input', 'select', 'textarea', 'button', 'iframe', 'object', 'embed', '[tabindex]', '[contenteditable]']; + +// Extend original api defaults +$.extend(TRUE, QTIP.defaults, { + show: { + modal: { + on: FALSE, + effect: TRUE, + blur: TRUE, + stealfocus: TRUE, + escape: TRUE + } + } +}); + +PLUGINS.imagemap = function(api, area, corner, adjustMethod) +{ + if(!area.jquery) { area = $(area); } + + var cache = (api.cache.areas = {}), + shape = (area[0].shape || area.attr('shape')).toLowerCase(), + coordsString = area[0].coords || area.attr('coords'), + baseCoords = coordsString.split(','), + coords = [], + image = $('img[usemap="#'+area.parent('map').attr('name')+'"]'), + imageOffset = image.offset(), + result = { + width: 0, height: 0, + position: { + top: 1e10, right: 0, + bottom: 0, left: 1e10 + } + }, + i = 0, next = 0, dimensions; + + // POLY area coordinate calculator + // Special thanks to Ed Cradock for helping out with this. + // Uses a binary search algorithm to find suitable coordinates. + function polyCoordinates(result, coords, corner) + { + var i = 0, + compareX = 1, compareY = 1, + realX = 0, realY = 0, + newWidth = result.width, + newHeight = result.height; + + // Use a binary search algorithm to locate most suitable coordinate (hopefully) + while(newWidth > 0 && newHeight > 0 && compareX > 0 && compareY > 0) + { + newWidth = Math.floor(newWidth / 2); + newHeight = Math.floor(newHeight / 2); + + if(corner.x === LEFT){ compareX = newWidth; } + else if(corner.x === RIGHT){ compareX = result.width - newWidth; } + else{ compareX += Math.floor(newWidth / 2); } + + if(corner.y === TOP){ compareY = newHeight; } + else if(corner.y === BOTTOM){ compareY = result.height - newHeight; } + else{ compareY += Math.floor(newHeight / 2); } + + i = coords.length; while(i--) + { + if(coords.length < 2){ break; } + + realX = coords[i][0] - result.position.left; + realY = coords[i][1] - result.position.top; + + if((corner.x === LEFT && realX >= compareX) || + (corner.x === RIGHT && realX <= compareX) || + (corner.x === CENTER && (realX < compareX || realX > (result.width - compareX))) || + (corner.y === TOP && realY >= compareY) || + (corner.y === BOTTOM && realY <= compareY) || + (corner.y === CENTER && (realY < compareY || realY > (result.height - compareY)))) { + coords.splice(i, 1); + } + } + } + + return { left: coords[0][0], top: coords[0][1] }; + } + + // Make sure we account for padding and borders on the image + imageOffset.left += Math.ceil((image.outerWidth() - image.width()) / 2); + imageOffset.top += Math.ceil((image.outerHeight() - image.height()) / 2); + + // Parse coordinates into proper array + if(shape === 'poly') { + i = baseCoords.length; while(i--) + { + next = [ parseInt(baseCoords[--i], 10), parseInt(baseCoords[i+1], 10) ]; + + if(next[0] > result.position.right){ result.position.right = next[0]; } + if(next[0] < result.position.left){ result.position.left = next[0]; } + if(next[1] > result.position.bottom){ result.position.bottom = next[1]; } + if(next[1] < result.position.top){ result.position.top = next[1]; } + + coords.push(next); + } + } + else { + i = -1; while(i++ < baseCoords.length) { + coords.push( parseInt(baseCoords[i], 10) ); + } + } + + // Calculate details + switch(shape) + { + case 'rect': + result = { + width: Math.abs(coords[2] - coords[0]), + height: Math.abs(coords[3] - coords[1]), + position: { + left: Math.min(coords[0], coords[2]), + top: Math.min(coords[1], coords[3]) + } + }; + break; + + case 'circle': + result = { + width: coords[2] + 2, + height: coords[2] + 2, + position: { left: coords[0], top: coords[1] } + }; + break; + + case 'poly': + result.width = Math.abs(result.position.right - result.position.left); + result.height = Math.abs(result.position.bottom - result.position.top) + + if(corner.abbrev() === 'c') { + result.position = { + left: result.position.left + (result.width / 2), + top: result.position.top + (result.height / 2) + }; + } + else { + // Calculate if we can't find a cached value + if(!cache[corner+coordsString]) { + result.position = polyCoordinates(result, coords.slice(), corner); + + // If flip adjustment is enabled, also calculate the closest opposite point + if(adjustMethod && (adjustMethod[0] === 'flip' || adjustMethod[1] === 'flip')) { + result.offset = polyCoordinates(result, coords.slice(), { + x: corner.x === LEFT ? RIGHT : corner.x === RIGHT ? LEFT : CENTER, + y: corner.y === TOP ? BOTTOM : corner.y === BOTTOM ? TOP : CENTER + }); + + result.offset.left -= result.position.left; + result.offset.top -= result.position.top; + } + + // Store the result + cache[corner+coordsString] = result; + } + + // Grab the cached result + result = cache[corner+coordsString]; + } + + result.width = result.height = 0; + break; + } + + // Add image position to offset coordinates + result.position.left += imageOffset.left; + result.position.top += imageOffset.top; + + return result; +}; + +// Tip coordinates calculator +function calculateTip(corner, width, height) +{ + var width2 = Math.ceil(width / 2), height2 = Math.ceil(height / 2), + + // Define tip coordinates in terms of height and width values + tips = { + bottomright: [[0,0], [width,height], [width,0]], + bottomleft: [[0,0], [width,0], [0,height]], + topright: [[0,height], [width,0], [width,height]], + topleft: [[0,0], [0,height], [width,height]], + topcenter: [[0,height], [width2,0], [width,height]], + bottomcenter: [[0,0], [width,0], [width2,height]], + rightcenter: [[0,0], [width,height2], [0,height]], + leftcenter: [[width,0], [width,height], [0,height2]] + }; + + // Set common side shapes + tips.lefttop = tips.bottomright; tips.righttop = tips.bottomleft; + tips.leftbottom = tips.topright; tips.rightbottom = tips.topleft; + + return tips[ corner.string() ]; +} + + +function Tip(qTip, command) +{ + var self = this, + opts = qTip.options.style.tip, + elems = qTip.elements, + tooltip = elems.tooltip, + cache = { top: 0, left: 0 }, + size = { + width: opts.width, + height: opts.height + }, + color = { }, + border = opts.border || 0, + namespace = '.qtip-tip', + hasCanvas = !!($('')[0] || {}).getContext; + + self.corner = NULL; + self.mimic = NULL; + self.border = border; + self.offset = opts.offset; + self.size = size; + + // Add new option checks for the plugin + qTip.checks.tip = { + '^position.my|style.tip.(corner|mimic|border)$': function() { + // Make sure a tip can be drawn + if(!self.init()) { + self.destroy(); + } + + // Reposition the tooltip + qTip.reposition(); + }, + '^style.tip.(height|width)$': function() { + // Re-set dimensions and redraw the tip + size = { + width: opts.width, + height: opts.height + }; + self.create(); + self.update(); + + // Reposition the tooltip + qTip.reposition(); + }, + '^content.title.text|style.(classes|widget)$': function() { + if(elems.tip && elems.tip.length) { + self.update(); + } + } + }; + + function swapDimensions() { + size.width = opts.height; + size.height = opts.width; + } + + function resetDimensions() { + size.width = opts.width; + size.height = opts.height; + } + + function reposition(event, api, pos, viewport) { + if(!elems.tip) { return; } + + var newCorner = self.corner.clone(), + adjust = pos.adjusted, + method = qTip.options.position.adjust.method.split(' '), + horizontal = method[0], + vertical = method[1] || method[0], + shift = { left: FALSE, top: FALSE, x: 0, y: 0 }, + offset, css = {}, props; + + // If our tip position isn't fixed e.g. doesn't adjust with viewport... + if(self.corner.fixed !== TRUE) { + // Horizontal - Shift or flip method + if(horizontal === SHIFT && newCorner.precedance === X && adjust.left && newCorner.y !== CENTER) { + newCorner.precedance = newCorner.precedance === X ? Y : X; + } + else if(horizontal !== SHIFT && adjust.left){ + newCorner.x = newCorner.x === CENTER ? (adjust.left > 0 ? LEFT : RIGHT) : (newCorner.x === LEFT ? RIGHT : LEFT); + } + + // Vertical - Shift or flip method + if(vertical === SHIFT && newCorner.precedance === Y && adjust.top && newCorner.x !== CENTER) { + newCorner.precedance = newCorner.precedance === Y ? X : Y; + } + else if(vertical !== SHIFT && adjust.top) { + newCorner.y = newCorner.y === CENTER ? (adjust.top > 0 ? TOP : BOTTOM) : (newCorner.y === TOP ? BOTTOM : TOP); + } + + // Update and redraw the tip if needed (check cached details of last drawn tip) + if(newCorner.string() !== cache.corner.string() && (cache.top !== adjust.top || cache.left !== adjust.left)) { + self.update(newCorner, FALSE); + } + } + + // Setup tip offset properties + offset = self.position(newCorner, adjust); + offset[ newCorner.x ] += borderWidth(newCorner, newCorner.x, TRUE); + offset[ newCorner.y ] += borderWidth(newCorner, newCorner.y, TRUE); + + // Readjust offset object to make it left/top + if(offset.right !== undefined) { offset.left = -offset.right; } + if(offset.bottom !== undefined) { offset.top = -offset.bottom; } + offset.user = Math.max(0, opts.offset); + + // Viewport "shift" specific adjustments + if(shift.left = (horizontal === SHIFT && !!adjust.left)) { + if(newCorner.x === CENTER) { + css['margin-left'] = shift.x = offset['margin-left'] - adjust.left; + } + else { + props = offset.right !== undefined ? + [ adjust.left, -offset.left ] : [ -adjust.left, offset.left ]; + + if( (shift.x = Math.max(props[0], props[1])) > props[0] ) { + pos.left -= adjust.left; + shift.left = FALSE; + } + + css[ offset.right !== undefined ? RIGHT : LEFT ] = shift.x; + } + } + if(shift.top = (vertical === SHIFT && !!adjust.top)) { + if(newCorner.y === CENTER) { + css['margin-top'] = shift.y = offset['margin-top'] - adjust.top; + } + else { + props = offset.bottom !== undefined ? + [ adjust.top, -offset.top ] : [ -adjust.top, offset.top ]; + + if( (shift.y = Math.max(props[0], props[1])) > props[0] ) { + pos.top -= adjust.top; + shift.top = FALSE; + } + + css[ offset.bottom !== undefined ? BOTTOM : TOP ] = shift.y; + } + } + + /* + * If the tip is adjusted in both dimensions, or in a + * direction that would cause it to be anywhere but the + * outer border, hide it! + */ + elems.tip.css(css).toggle( + !((shift.x && shift.y) || (newCorner.x === CENTER && shift.y) || (newCorner.y === CENTER && shift.x)) + ); + + // Adjust position to accomodate tip dimensions + pos.left -= offset.left.charAt ? offset.user : horizontal !== SHIFT || shift.top || !shift.left && !shift.top ? offset.left : 0; + pos.top -= offset.top.charAt ? offset.user : vertical !== SHIFT || shift.left || !shift.left && !shift.top ? offset.top : 0; + + // Cache details + cache.left = adjust.left; cache.top = adjust.top; + cache.corner = newCorner.clone(); + } + + /* border width calculator */ + function borderWidth(corner, side, backup) { + side = !side ? corner[corner.precedance] : side; + + var isFluid = tooltip.hasClass(fluidClass), + isTitleTop = elems.titlebar && corner.y === TOP, + elem = isTitleTop ? elems.titlebar : elems.tooltip, + css = 'border-' + side + '-width', + val; + + // Grab the border-width value (add fluid class if needed) + tooltip.addClass(fluidClass); + val = parseInt(elem.css(css), 10); + val = (backup ? val || parseInt(tooltip.css(css), 10) : val) || 0; + tooltip.toggleClass(fluidClass, isFluid); + + return val; + } + + function borderRadius(corner) { + var isTitleTop = elems.titlebar && corner.y === TOP, + elem = isTitleTop ? elems.titlebar : elems.content, + moz = $.browser.mozilla, + prefix = moz ? '-moz-' : $.browser.webkit ? '-webkit-' : '', + side = corner.y + (moz ? '' : '-') + corner.x, + css = prefix + (moz ? 'border-radius-' + side : 'border-' + side + '-radius'); + + return parseInt(elem.css(css), 10) || parseInt(tooltip.css(css), 10) || 0; + } + + function calculateSize(corner) { + var y = corner.precedance === Y, + width = size [ y ? WIDTH : HEIGHT ], + height = size [ y ? HEIGHT : WIDTH ], + isCenter = corner.string().indexOf(CENTER) > -1, + base = width * (isCenter ? 0.5 : 1), + pow = Math.pow, + round = Math.round, + bigHyp, ratio, result, + + smallHyp = Math.sqrt( pow(base, 2) + pow(height, 2) ), + + hyp = [ + (border / base) * smallHyp, (border / height) * smallHyp + ]; + hyp[2] = Math.sqrt( pow(hyp[0], 2) - pow(border, 2) ); + hyp[3] = Math.sqrt( pow(hyp[1], 2) - pow(border, 2) ); + + bigHyp = smallHyp + hyp[2] + hyp[3] + (isCenter ? 0 : hyp[0]); + ratio = bigHyp / smallHyp; + + result = [ round(ratio * height), round(ratio * width) ]; + return { height: result[ y ? 0 : 1 ], width: result[ y ? 1 : 0 ] }; + } + + $.extend(self, { + init: function() + { + var enabled = self.detectCorner() && (hasCanvas || $.browser.msie); + + // Determine tip corner and type + if(enabled) { + // Create a new tip and draw it + self.create(); + self.update(); + + // Bind update events + tooltip.unbind(namespace).bind('tooltipmove'+namespace, reposition); + } + + return enabled; + }, + + detectCorner: function() + { + var corner = opts.corner, + posOptions = qTip.options.position, + at = posOptions.at, + my = posOptions.my.string ? posOptions.my.string() : posOptions.my; + + // Detect corner and mimic properties + if(corner === FALSE || (my === FALSE && at === FALSE)) { + return FALSE; + } + else { + if(corner === TRUE) { + self.corner = new PLUGINS.Corner(my); + } + else if(!corner.string) { + self.corner = new PLUGINS.Corner(corner); + self.corner.fixed = TRUE; + } + } + + // Cache it + cache.corner = new PLUGINS.Corner( self.corner.string() ); + + return self.corner.string() !== 'centercenter'; + }, + + detectColours: function(actual) { + var i, fill, border, + tip = elems.tip.css('cssText', ''), + corner = actual || self.corner, + precedance = corner[ corner.precedance ], + + borderSide = 'border-' + precedance + '-color', + borderSideCamel = 'border' + precedance.charAt(0) + precedance.substr(1) + 'Color', + + invalid = /rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i, + backgroundColor = 'background-color', + transparent = 'transparent', + important = ' !important', + + useTitle = elems.titlebar && (corner.y === TOP || (corner.y === CENTER && tip.position().top + (size.height / 2) + opts.offset < elems.titlebar.outerHeight(1))), + colorElem = useTitle ? elems.titlebar : elems.tooltip; + + // Apply the fluid class so we can see our CSS values properly + tooltip.addClass(fluidClass); + + // Detect tip colours from CSS styles + color.fill = fill = tip.css(backgroundColor); + color.border = border = tip[0].style[ borderSideCamel ] || tip.css(borderSide) || tooltip.css(borderSide); + + // Make sure colours are valid + if(!fill || invalid.test(fill)) { + color.fill = colorElem.css(backgroundColor) || transparent; + if(invalid.test(color.fill)) { + color.fill = tooltip.css(backgroundColor) || fill; + } + } + if(!border || invalid.test(border) || border === $(document.body).css('color')) { + color.border = colorElem.css(borderSide) || transparent; + if(invalid.test(color.border) || color.border === colorElem.css('color')) { + color.border = tooltip.css(borderSide) || tooltip.css(borderSideCamel) || border; + } + } + + // Reset background and border colours + $('*', tip).add(tip).css('cssText', backgroundColor+':'+transparent+important+';border:0'+important+';'); + + // Remove fluid class + tooltip.removeClass(fluidClass); + }, + + create: function() + { + var width = size.width, + height = size.height, + vml; + + // Remove previous tip element if present + if(elems.tip) { elems.tip.remove(); } + + // Create tip element and prepend to the tooltip + elems.tip = $('
', { 'class': 'ui-tooltip-tip' }).css({ width: width, height: height }).prependTo(tooltip); + + // Create tip drawing element(s) + if(hasCanvas) { + // save() as soon as we create the canvas element so FF2 doesn't bork on our first restore()! + $('').appendTo(elems.tip)[0].getContext('2d').save(); + } + else { + vml = ''; + elems.tip.html(vml + vml); + + // Prevent mousing down on the tip since it causes problems with .live() handling in IE due to VML + $('*', elems.tip).bind('click mousedown', function(event) { event.stopPropagation(); }); + } + }, + + update: function(corner, position) + { + var tip = elems.tip, + inner = tip.children(), + width = size.width, + height = size.height, + regular = 'px solid ', + transparent = 'px dashed transparent', // Dashed IE6 border-transparency hack. Awesome! + mimic = opts.mimic, + round = Math.round, + precedance, context, coords, translate, newSize; + + // Re-determine tip if not already set + if(!corner) { corner = cache.corner || self.corner; } + + // Use corner property if we detect an invalid mimic value + if(mimic === FALSE) { mimic = corner; } + + // Otherwise inherit mimic properties from the corner object as necessary + else { + mimic = new PLUGINS.Corner(mimic); + mimic.precedance = corner.precedance; + + if(mimic.x === 'inherit') { mimic.x = corner.x; } + else if(mimic.y === 'inherit') { mimic.y = corner.y; } + else if(mimic.x === mimic.y) { + mimic[ corner.precedance ] = corner[ corner.precedance ]; + } + } + precedance = mimic.precedance; + + // Ensure the tip width.height are relative to the tip position + if(corner.precedance === X) { swapDimensions(); } + else { resetDimensions(); } + + // Set the tip dimensions + elems.tip.css({ + width: (width = size.width), + height: (height = size.height) + }); + + // Update our colours + self.detectColours(corner); + + // Detect border width, taking into account colours + if(color.border !== 'transparent') { + // Grab border width + border = borderWidth(corner, NULL, TRUE); + + // If border width isn't zero, use border color as fill (1.0 style tips) + if(opts.border === 0 && border > 0) { color.fill = color.border; } + + // Set border width (use detected border width if opts.border is true) + self.border = border = opts.border !== TRUE ? opts.border : border; + } + + // Border colour was invalid, set border to zero + else { self.border = border = 0; } + + // Calculate coordinates + coords = calculateTip(mimic, width , height); + + // Determine tip size + self.size = newSize = calculateSize(corner); + tip.css(newSize); + + // Calculate tip translation + if(corner.precedance === Y) { + translate = [ + round(mimic.x === LEFT ? border : mimic.x === RIGHT ? newSize.width - width - border : (newSize.width - width) / 2), + round(mimic.y === TOP ? newSize.height - height : 0) + ]; + } + else { + translate = [ + round(mimic.x === LEFT ? newSize.width - width : 0), + round(mimic.y === TOP ? border : mimic.y === BOTTOM ? newSize.height - height - border : (newSize.height - height) / 2) + ]; + } + + // Canvas drawing implementation + if(hasCanvas) { + // Set the canvas size using calculated size + inner.attr(newSize); + + // Grab canvas context and clear/save it + context = inner[0].getContext('2d'); + context.restore(); context.save(); + context.clearRect(0,0,3000,3000); + + // Set properties + context.fillStyle = color.fill; + context.strokeStyle = color.border; + context.lineWidth = border * 2; + context.lineJoin = 'miter'; + context.miterLimit = 100; + + // Translate origin + context.translate(translate[0], translate[1]); + + // Draw the tip + context.beginPath(); + context.moveTo(coords[0][0], coords[0][1]); + context.lineTo(coords[1][0], coords[1][1]); + context.lineTo(coords[2][0], coords[2][1]); + context.closePath(); + + // Apply fill and border + if(border) { + // Make sure transparent borders are supported by doing a stroke + // of the background colour before the stroke colour + if(tooltip.css('background-clip') === 'border-box') { + context.strokeStyle = color.fill; + context.stroke(); + } + context.strokeStyle = color.border; + context.stroke(); + } + context.fill(); + } + + // VML (IE Proprietary implementation) + else { + // Setup coordinates string + coords = 'm' + coords[0][0] + ',' + coords[0][1] + ' l' + coords[1][0] + + ',' + coords[1][1] + ' ' + coords[2][0] + ',' + coords[2][1] + ' xe'; + + // Setup VML-specific offset for pixel-perfection + translate[2] = border && /^(r|b)/i.test(corner.string()) ? + parseFloat($.browser.version, 10) === 8 ? 2 : 1 : 0; + + // Set initial CSS + inner.css({ + antialias: ''+(mimic.string().indexOf(CENTER) > -1), + left: translate[0] - (translate[2] * Number(precedance === X)), + top: translate[1] - (translate[2] * Number(precedance === Y)), + width: width + border, + height: height + border + }) + .each(function(i) { + var $this = $(this); + + // Set shape specific attributes + $this[ $this.prop ? 'prop' : 'attr' ]({ + coordsize: (width+border) + ' ' + (height+border), + path: coords, + fillcolor: color.fill, + filled: !!i, + stroked: !i + }) + .css({ display: border || i ? 'block' : 'none' }); + + // Check if border is enabled and add stroke element + if(!i && $this.html() === '') { + $this.html( + '' + ); + } + }); + } + + // Position if needed + if(position !== FALSE) { self.position(corner); } + }, + + // Tip positioning method + position: function(corner) + { + var tip = elems.tip, + position = {}, + userOffset = Math.max(0, opts.offset), + precedance, dimensions, corners; + + // Return if tips are disabled or tip is not yet rendered + if(opts.corner === FALSE || !tip) { return FALSE; } + + // Inherit corner if not provided + corner = corner || self.corner; + precedance = corner.precedance; + + // Determine which tip dimension to use for adjustment + dimensions = calculateSize(corner); + + // Setup corners and offset array + corners = [ corner.x, corner.y ]; + if(precedance === X) { corners.reverse(); } + + // Calculate tip position + $.each(corners, function(i, side) { + var b, br; + + if(side === CENTER) { + b = precedance === Y ? LEFT : TOP; + position[ b ] = '50%'; + position['margin-' + b] = -Math.round(dimensions[ precedance === Y ? WIDTH : HEIGHT ] / 2) + userOffset; + } + else { + b = borderWidth(corner, side); + br = borderRadius(corner); + + position[ side ] = i ? 0 : (userOffset + (br > b ? br : -b)); + } + }); + + // Adjust for tip dimensions + position[ corner[precedance] ] -= dimensions[ precedance === X ? WIDTH : HEIGHT ]; + + // Set and return new position + tip.css({ top: '', bottom: '', left: '', right: '', margin: '' }).css(position); + return position; + }, + + destroy: function() + { + // Remove the tip element + if(elems.tip) { elems.tip.remove(); } + elems.tip = false; + + // Unbind events + tooltip.unbind(namespace); + } + }); + + self.init(); +} + +PLUGINS.tip = function(api) +{ + var self = api.plugins.tip; + + return 'object' === typeof self ? self : (api.plugins.tip = new Tip(api)); +}; + +// Initialize tip on render +PLUGINS.tip.initialize = 'render'; + +// Setup plugin sanitization options +PLUGINS.tip.sanitize = function(options) +{ + var style = options.style, opts; + if(style && 'tip' in style) { + opts = options.style.tip; + if(typeof opts !== 'object'){ options.style.tip = { corner: opts }; } + if(!(/string|boolean/i).test(typeof opts.corner)) { opts.corner = TRUE; } + if(typeof opts.width !== 'number'){ delete opts.width; } + if(typeof opts.height !== 'number'){ delete opts.height; } + if(typeof opts.border !== 'number' && opts.border !== TRUE){ delete opts.border; } + if(typeof opts.offset !== 'number'){ delete opts.offset; } + } +}; + +// Extend original qTip defaults +$.extend(TRUE, QTIP.defaults, { + style: { + tip: { + corner: TRUE, + mimic: FALSE, + width: 6, + height: 6, + border: TRUE, + offset: 0 + } + } +}); + +PLUGINS.svg = function(api, svg, corner, adjustMethod) +{ + var doc = $(document), + elem = svg[0], + result = { + width: 0, height: 0, + position: { top: 1e10, left: 1e10 } + }, + box, mtx, root, point, tPoint; + + // Ascend the parentNode chain until we find an element with getBBox() + while(!elem.getBBox) { elem = elem.parentNode; } + + // Check for a valid bounding box method + if (elem.getBBox && elem.parentNode) { + box = elem.getBBox(); + mtx = elem.getScreenCTM(); + root = elem.farthestViewportElement || elem; + + // Return if no method is found + if(!root.createSVGPoint) { return result; } + + // Create our point var + point = root.createSVGPoint(); + + // Adjust top and left + point.x = box.x; + point.y = box.y; + tPoint = point.matrixTransform(mtx); + result.position.left = tPoint.x; + result.position.top = tPoint.y; + + // Adjust width and height + point.x += box.width; + point.y += box.height; + tPoint = point.matrixTransform(mtx); + result.width = tPoint.x - result.position.left; + result.height = tPoint.y - result.position.top; + + // Adjust by scroll offset + result.position.left += doc.scrollLeft(); + result.position.top += doc.scrollTop(); + } + + return result; +}; + +/* + * BGIFrame adaption (http://plugins.jquery.com/project/bgiframe) + * Special thanks to Brandon Aaron + */ +function BGIFrame(api) +{ + var self = this, + elems = api.elements, + tooltip = elems.tooltip, + namespace = '.bgiframe-' + api.id; + + $.extend(self, { + init: function() + { + // Create the BGIFrame element + elems.bgiframe = $(''); + + // Append the new element to the tooltip + elems.bgiframe.appendTo(tooltip); + + // Update BGIFrame on tooltip move + tooltip.bind('tooltipmove'+namespace, self.adjust); + }, + + adjust: function() + { + var dimensions = api.get('dimensions'), // Determine current tooltip dimensions + plugin = api.plugins.tip, + tip = elems.tip, + tipAdjust, offset; + + // Adjust border offset + offset = parseInt(tooltip.css('border-left-width'), 10) || 0; + offset = { left: -offset, top: -offset }; + + // Adjust for tips plugin + if(plugin && tip) { + tipAdjust = (plugin.corner.precedance === 'x') ? ['width', 'left'] : ['height', 'top']; + offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ](); + } + + // Update bgiframe + elems.bgiframe.css(offset).css(dimensions); + }, + + destroy: function() + { + // Remove iframe + elems.bgiframe.remove(); + + // Remove bound events + tooltip.unbind(namespace); + } + }); + + self.init(); +} + +PLUGINS.bgiframe = function(api) +{ + var browser = $.browser, + self = api.plugins.bgiframe; + + // Proceed only if the browser is IE6 and offending elements are present + if($('select, object').length < 1 || !(browser.msie && (''+browser.version).charAt(0) === '6')) { + return FALSE; + } + + return 'object' === typeof self ? self : (api.plugins.bgiframe = new BGIFrame(api)); +}; + +// Plugin needs to be initialized on render +PLUGINS.bgiframe.initialize = 'render'; + + +})); \ No newline at end of file diff --git a/registration.php b/registration.php new file mode 100644 index 0000000..ddb0d8b --- /dev/null +++ b/registration.php @@ -0,0 +1,444 @@ + + +PQS - Registration Console + + + + + + + + 0){ + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "INSERT INTO pqs_mission (MissionDate, MissionSize, numplayers, MissionTime) VALUES ($tdate, $missionsize, 0, $ttime)"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $buildmissions--; + } + +} + +if (isset($_GET['clearcurrent'])) { + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $sql = "TRUNCATE TABLE pqs_currentmission"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + mysqli_close($link); +} + +if (isset($_GET['lock'])) { + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + if (isset($_GET['missionid'])) { + $missionid = $_GET['missionid']; + }else{ + $sql = "SELECT MIN(MissionID) FROM pqs_queue"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($getid); + $missionid = $rs[0]; + } + + $sql = "UPDATE pqs_mission SET locked=1 WHERE MissionID=$missionid"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + mysqli_close($link); +} + +if (isset($_POST['edit'])) { + if (isset($_POST['playerid'])) $playerid = $_POST['playerid']; + if (isset($_POST['callsign'])) $callsign = str_replace("'", "''", $_POST['callsign']); + if (isset($_POST['mech'])) $mech = $_POST['mech']; + + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + $sql = "UPDATE pqs_queue SET Callsign='$callsign', mech='$mech', Updated=1 WHERE id=$playerid"; + mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + + mysqli_close($link); +} + +if (isset($_POST['add'])) { + if (isset($_POST['playerid'])) $playerid = $_POST['playerid']; + if (isset($_POST['callsign'])) $callsign = str_replace("'", "'", $_POST['callsign']); + if (isset($_POST['missionid'])) $missionid = $_POST['missionid']; + if (isset($_POST['merc'])) $merc = $_POST['merc']; + if (isset($_POST['mech'])) $mech = $_POST['mech']; + if (isset($_POST['nummissions'])) $nummissions = $_POST['nummissions']; + + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + $sql = "SELECT MAX(MissionID) FROM pqs_mission"; + $result = mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($result); + $maxmission = $rs[0]; + $newmissionid = $missionid + 1; + + for ($i = 1; $i <= $nummissions;) { + if ($newmissionid <= $maxmission) { + $sql = "SELECT numplayers FROM pqs_mission WHERE MissionID = $newmissionid"; + $result = mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($result); + if ($rs[0] < $missionsize) { + $sql = "UPDATE pqs_mission SET numplayers = numplayers + 1 WHERE MissionID = $newmissionid"; + $result = mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + $sql = "INSERT INTO pqs_queue (CallSign, Mech, MissionID, Merc) VALUES ('$callsign', '$mech', $newmissionid, $merc)"; + $result = mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + $i++; + } + } else { + $sql = "INSERT INTO pqs_mission (MissionDate, MissionSize, numplayers, nummercs, MissionTime) VALUES ($tdate, $missionsize, 1, $merc, $ttime)"; + mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $sql = "INSERT INTO pqs_queue (CallSign, Mech, MissionID, Merc) VALUES ('$callsign', '$mech', $newmissionid, $merc)"; + $result = mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + $i++; + } + $newmissionid++; + } + mysqli_close($link); +} + +if (isset($_POST['new'])) { + if (isset($_POST['callsign'])) $callsign = str_replace("'", "''", $_POST['callsign']); + if(is_null($callsign)){ $callsign = 'empty'; } + if (isset($_POST['mech'])) $mech = $_POST['mech']; + if (isset($_POST['missionid'])) $missionid = $_POST['missionid']; + + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + $sql = "SELECT numplayers FROM pqs_mission WHERE MissionID = '$missionid'"; + $getid = mysqli_query($link, $sql) or die('Query failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($getid); + $numplayers = $rs[0]; + $newplayers = $numplayers+1; + $sql = "UPDATE pqs_mission SET numplayers='$newplayers' WHERE MissionID=$missionid"; + mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + + $sql = "INSERT INTO pqs_queue (callsign, mech, missionid) VALUES ('$callsign','$mech',$missionid)"; + mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + + mysqli_close($link); +} + +if (isset($_POST['editgame'])) { + $newtype = $_POST['newtype']; + $newmap = $_POST['newmap']; + $missionid = $_GET['missionid']; + + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + $sql = "UPDATE pqs_mission SET GameType='$newtype', map='$newmap' WHERE MissionID=$missionid"; + mysqli_query($link, $sql) or die('Update player in Queue failed: ' . mysqli_error($link)); + + mysqli_close($link); +} + +if (isset($_GET['action'])) { + $action = $_GET['action']; + if (isset($_GET['playerid'])) $playerid = $_GET['playerid']; + if (isset($_GET['missionid'])) $missionid = $_GET['missionid']; + if (isset($_GET['callsign'])) $callsign = $_GET['callsign']; + if (isset($_GET['mech'])) $mech = $_GET['mech']; + if (isset($_GET['oldmap'])) $oldmap = $_GET['oldmap']; + if (isset($_GET['oldtype'])) $oldtype = $_GET['oldtype']; + $callsign=str_replace("'", "'", $line[0]); + $nextmission = $missionid + 1; + switch ($action) { + case "edit": + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + $sql = "SELECT * FROM pqs_queue WHERE ID = $playerid"; + $result = mysqli_query($link, $sql) or die('Select player from Queue failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($result); + $callsign = $rs[0]; + $mech = $rs[1]; + + echo "
"; + echo "
"; + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "
Edit Player $callsign
CallsignMech
"; + echo ""; + echo ""; + echo ""; + echo "
"; + echo "
"; + + mysqli_close($link); + break; + + case "delete": + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + $sql = "SELECT COUNT(CallSign) FROM pqs_queue"; + $result = mysqli_query($link, $sql) or die('Delete player from Queue failed: ' . mysqli_error($link)); + $line = mysqli_fetch_array($result); + $queuecount = $line[0]; + + $sql = "DELETE FROM pqs_queue WHERE id = $playerid"; + $result = mysqli_query($link, $sql) or die('Delete player from Queue failed: ' . mysqli_error($link)); + $sql = "UPDATE pqs_mission SET numplayers = numplayers - 1 WHERE missionid = $missionid"; + $result = mysqli_query($link, $sql) or die('Update mission after delete player failed: ' . mysqli_error($link)); + + mysqli_close($link); + break; + + case "add": + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + $sql = "SELECT * FROM pqs_queue WHERE ID = $playerid"; + $result = mysqli_query($link, $sql) or die('Delete player from Queue failed: ' . mysqli_error($link)); + $rs = mysqli_fetch_array($result); + $callsign = str_replace("'", "'", $rs[0]); + $mech = $rs[1]; + $merc = $rs[4]; + $missionid = $rs[3]; + echo "
"; + echo ""; + echo "
"; + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "
Add $callsign to multiple missions
# Missions:
"; + echo "
"; + mysqli_close($link); + break; + + case "editgame": + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + echo "
"; + echo ""; + echo "
"; + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + echo "
Edit : $missionid "; + echo ""; + echo ""; + echo ""; + echo "
"; + echo "
"; + + mysqli_close($link); + + break; + } +} + +echo ""; +echo ""; +echo ""; + +// add player form +if($missionid==0){ + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + $query = 'SELECT min(MissionID) FROM pqs_queue'; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $line = mysqli_fetch_array($result); + $missionid = $line[0]; + } +echo ""; +echo "
Clear Current Queue   |   "; +echo "Open History Window   |   "; +echo "Lock Mission   |   "; +echo "Back to Current Queue"; +echo "
"; +echo "
"; +echo "
"; +echo "
"; +echo ""; + + +echo ""; +echo "
Back to CurrentM: $missionidCS: "; +echo "
"; +echo "
"; + +// search form +echo "
"; +echo "
"; + +echo "
"; +echo ""; +echo ""; +echo "
Search in Mission(s)"; +echo "
"; +echo ""; +echo "
"; + +// create missions +echo "
"; +echo "
"; + +echo "
"; +echo ""; +echo ""; +echo "
Build Missions "; +echo "
"; +echo ""; +echo "
"; + +// search results // +if(isset($_GET['search'])){ + if (isset($_GET['callsign'])){ + $cs = str_replace("'", "&;", $_GET['callsign']); + if($cs == ''){$cs = 'unknown';} + } + + echo "
"; + echo ""; + echo ""; + + // fetch data // + $link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); + mysqli_select_db($link, 'pqs') or die('Could not select database'); + + // get last commit time and mission id + $query = "SELECT max(MissionID), max(UNIX_TIMESTAMP(ctime)) FROM pqs_pastmissions"; + $getlct = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $rs2 = mysqli_fetch_array($getlct); + $lastmission = $rs2[0]; + if(is_null($lastmission)){$lastmission = 0;} + $lastCommitTime = $rs2[1];// utc -H*mm*sc + if(is_null($lastCommitTime)){$lastCommitTime = time();}//-(6*60*60);} + + // get time per game // + $query = "SELECT timepergame, timetoreset FROM pqs_gameconfig"; + $gettpg = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + $rs1 = mysqli_fetch_array($gettpg); + $tpg = $rs1[0]+$rs1[1]; + + $query = "SELECT * FROM pqs_queue WHERE CallSign LIKE '$cs' ORDER BY MissionID"; + $result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + + while ($line = mysqli_fetch_array($result)) { + + $mtd = ($line[3] - $lastmission) * $tpg; + $d=strtotime("+$mtd Minutes",$lastCommitTime); + $etd = date("h:i", $d); + + echo ""; + } + echo ""; + echo "
Mission(s) : $cs
CallSignMissionETDMechEdit/Delete
$line[0]$line[3]$etd$line[1]"; + echo "  "; + echo "  "; + + echo "
 
"; +} + +echo ""; +?> + + diff --git a/search.php b/search.php new file mode 100644 index 0000000..2bfadc5 --- /dev/null +++ b/search.php @@ -0,0 +1,87 @@ + + +PQS - Search + + + + + +"; +echo "
"; +echo "
"; +echo ""; +echo ""; +echo ""; +echo ""; +echo "
Search for Player in Mission(s)
Callsign
"; +echo "
"; +///////////////// + +echo "
"; +echo ""; +//echo ""; +echo ""; + +$link = mysqli_connect('localhost', 'pqs', 'pqs') or die('Could not connect: ' . mysqli_error($link)); +mysqli_select_db($link, 'pqs') or die('Could not select database'); + +// get last commit time and mission id +$query = "SELECT max(MissionID), max(UNIX_TIMESTAMP(ctime)) FROM pqs_pastmissions"; +$getlct = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); +$rs2 = mysqli_fetch_array($getlct); +$lastmission = $rs2[0]; +if(is_null($lastmission)){$lastmission = 0;} +$lastCommitTime = $rs2[1];//-(6*60*60); +if(is_null($lastCommitTime)){$lastCommitTime = time();}//-(6*60*60);} +//echo"$lastCommitTime"; +//$d=strtotime("+$mtd Minutes",$lastCommitTime); +//$etd = date("h:i", $d); + +// get time per game // +$query = "SELECT timepergame, timetoreset FROM pqs_gameconfig"; +$gettpg = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); +$rs1 = mysqli_fetch_array($gettpg); +$tpg = $rs1[0]+$rs1[1]; + +// fetch data // +$query = "SELECT * FROM pqs_queue WHERE CallSign LIKE '$cs'"; +$result = mysqli_query($link, $query) or die('Query failed: ' . mysqli_error($link)); + +while ($line = mysqli_fetch_array($result)) { + + $mtd = ($line[3] - $lastmission) * $tpg; + $d=strtotime("+$mtd Minutes",$lastCommitTime); + $etd = date("h:i", $d); + + echo ""; +} +echo ""; +echo "
Mission(s) : $cs
CallSignMissionETDMechEdit/Delete
CallSignMissionETDMech
$line[0]$line[3]$etd$line[1]"; +// echo "  "; +// echo "  "; + + echo "
 
"; + +mysqli_free_result($result); +mysqli_close($link); +echo ""; +?> + + diff --git a/smallcombinedqueue.php b/smallcombinedqueue.php new file mode 100644 index 0000000..d401fac --- /dev/null +++ b/smallcombinedqueue.php @@ -0,0 +1,75 @@ + + +PQS - Player Queue + + + + + +"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +echo "
 
 
 
 
 
"; +echo ""; +echo ""; +echo ""; +echo "
 
 
"; +?> + diff --git a/time.php b/time.php new file mode 100644 index 0000000..151ccbb --- /dev/null +++ b/time.php @@ -0,0 +1,37 @@ +format('D M d Y H:i:s e'); + echo "

Current PQS Time:

"; + echo "

{$date}

"; + +if (isset($_GET['submit'])) {$submit=$_GET['submit'];}else{$submit='';} +if ($submit=='update'){ + + $settime = $_GET['lct']; + $settime2 = round($settime/1000); + $settime3 = "@".$settime2; + +echo exec("sudo date -s $settime3 > /dev/null &"); +}; + +?> + +

Local computer time:

+

+ +
+ +

+

+ + +