From: Maxious Date: Thu, 19 Apr 2012 12:07:08 +0000 Subject: fix servicealert editor due to "end" field X-Git-Url: http://maxious.lambdacomplex.org/git/?p=busui.git&a=commitdiff&h=d86046138da234caf6ebf433246ae671f31541e1 --- fix servicealert editor due to "end" field --- --- /dev/null +++ b/.gitignore @@ -1,1 +1,9 @@ +/labs/tiles/12 +/labs/tiles/13 +/labs/tiles/14 +/labs/tiles/15 +/labs/tiles/16 +/labs/tiles/17 +/labs/tiles/19 +/nbproject/private/ --- /dev/null +++ b/.gitmodules @@ -1,1 +1,16 @@ +[submodule "js/flotr2"] + path = js/flotr2 + url = https://github.com/HumbleSoftware/Flotr2.git +[submodule "js/FlashCanvas"] + path = js/FlashCanvas + url = https://github.com/timcameronryan/FlashCanvas +[submodule "lib/amon-php"] + path = lib/amon-php + url = https://github.com/martinrusev/amon-php.git +[submodule "js/tesseract"] + path = js/tesseract + url = https://github.com/square/tesseract.git +[submodule "js/d3"] + path = js/d3 + url = https://github.com/mbostock/d3.git --- /dev/null +++ b/Boxfile @@ -1,1 +1,7 @@ +web1: + php_extensions: + - pgsql + - pdo + - pdo_pgsql + - curl --- a/about.php +++ b/about.php @@ -1,31 +1,57 @@

-Busness Time - An ACT bus timetable webapp
-Based on the maxious-canberra-transit-feed (download, -last updated )
-Source code for the transit -feed and this -site available from github.
-Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service
-
-Feedback encouraged; contact maxious@lambdacomplex.org
+ Busness Time - An ACT bus timetable webapp
+ Based on the maxious-canberra-transit-feed (download, + last updated )
+ Source code for the transit + feed and this + site available from github.
+ Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service
+ Suburb geocoding based on Australian Bureau of Statistics data.
+ Street geocoding based on work by OpenStreetMap contributors

-Some icons by Joseph Wain / glyphish.com
-
-Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip. -Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, -express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided -"as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. -All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, -change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site -without prior notice. - + Feedback encouraged; contact maxious@lambdacomplex.org
+
+ Some icons by Joseph Wain / glyphish.com
+ Native clients also available for iPhone (cbrTimetable by Sandor Kolotenko + , ACT Buses by David Sullivan, Bus Trips ACT by Molson Chengalath) + , Android (MyBus 2.0 by Imagine Team, GetMe2 Canberra by +Colin Thompson , TransitTimes+ by Zervaas Enterprises) + and Windows Phone 7 (TransHub Canberra by Soul Solutions). +
+ +
+
+ Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://www.action.act.gov.au before your trip. + Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, + express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided + "as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. + All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, + change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site + without prior notice. + --- a/aws/awsStartup.sh +++ /dev/null @@ -1,39 +1,1 @@ -#!/bin/bash -#this script should be run from a fresh git checkout from github -#ami base must have yum install lighttpd-fastcgi, git, tomcat6 -#php-cli php-gd tomcat6-webapps tomcat6-admin-webapps svn maven2 -#postgres postgres-server php-pg -#http://www.how2forge.org/installing-lighttpd-with-php5-and-mysql-support-on-fedora-12 -cp /root/aws.php /tmp/ -mkdir /var/www/lib/staticmaplite/cache -chcon -h system_u:object_r:httpd_sys_content_t /var/www -chcon -R -h root:object_r:httpd_sys_content_t /var/www/* -chcon -R -t httpd_sys_content_rw_t /var/www/lib/staticmaplite/cache -chmod -R 777 /var/www/lib/staticmaplite/cache -chcon -R -t httpd_sys_content_rw_t /var/www/labs/tiles -chmod -R 777 /var/www/labs/tiles -wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \ --O /var/www/cbrfeed.zip - -createdb transitdata -createlang -d transitdata plpgsql -psql -d transitdata -f /var/www/lib/postgis.sql -# curl https://github.com/maxious/ACTBus-ui/raw/master/transitdata.cbrfeed.sql.gz -o transitdata.cbrfeed.sql.gz -#made with pg_dump transitdata | gzip -c > transitdata.cbrfeed.sql.gz -gunzip /var/www/transitdata.cbrfeed.sql.gz -psql -d transitdata -f /var/www/transitdata.cbrfeed.sql -#createuser transitdata -SDRP -#password transitdata -#psql -d transitdata -c \"GRANT SELECT ON TABLE agency,calendar,calendar_dates,routes,stop_times,stops,trips TO transitdata;\" -php /var/www/updatedb.php - -wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \ --O /tmp/Graph.obj -rm -rfv /usr/share/tomcat6/webapps/opentripplanner* -wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-webapp.war \ --O /usr/share/tomcat6/webapps/opentripplanner-webapp.war -wget http://s3-ap-southeast-1.amazonaws.com/busresources/opentripplanner-api-webapp.war \ --O /usr/share/tomcat6/webapps/opentripplanner-api-webapp.war -/etc/init.d/tomcat6 restart - --- a/aws/compress.conf +++ /dev/null @@ -1,33 +1,1 @@ -####################################################################### -## -## Output Compression -## -------------------- -## -## see http://www.lighttpd.net/documentation/compress.html -## -server.modules += ( "mod_compress" ) -## -## where should the compressed files be cached? -## see the base config for the declaration of the variable. -## -## This directory should be changed per vhost otherwise you can -## run into trouble with overlapping filenames -## -compress.cache-dir = cache_dir + "/compress" - -## -## FileTypes to compress. -## -#compress.filetype = ("text/plain", "text/html") -compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml") - -## -## Maximum filesize that will be compressed. -## Default is 0, which means unlimited file size. -## -#compress.max-filesize = 0 - -## -####################################################################### - --- a/aws/expire.conf +++ /dev/null @@ -1,29 +1,1 @@ -####################################################################### -## -## Expire Module -## --------------- -## -## See http://www.lighttpd.net/documentation/expire.html -## -server.modules += ( "mod_expire" ) -## -## assignes a expiration to all files below the specified path. The -## specification of the time is made up of: -## -## -## -#expire.url = ( -# "/buggy/" => "access 2 hours", -# "/images/" => "access plus 1 seconds 2 minutes" -#) -etag.use-mtime = "enable" -etag.use-inode = "disable" -static-file.etags = "enable" -$HTTP["url"] =~ "\.(css|js|png|jpg|ico|gif)$" { - expire.url = ( "" => "access 7 days" ) -} - -## -####################################################################### - --- a/aws/fastcgi.conf +++ /dev/null @@ -1,144 +1,1 @@ -####################################################################### -## -## FastCGI Module -## --------------- -## -## http://www.lighttpd.net/documentation/fastcgi.html -## -server.modules += ( "mod_fastcgi" ) -fastcgi.server = ( ".php" => - ( "localhost" => - ( - "socket" => -"/var/run/lighttpd/php-fastcgi.socket", - "bin-path" => "/usr/bin/php-cgi" - ) - ) - ) -## -## PHP Example -## For PHP don't forget to set cgi.fix_pathinfo = 1 in the php.ini. -## -## The number of php processes you will get can be easily calculated: -## -## num-procs = max-procs * ( 1 + PHP_FCGI_CHILDREN ) -## -## for the php-num-procs example it means you will get 17*5 = 85 php -## processes. you always should need this high number for your very -## busy sites. And if you have a lot of RAM. :) -## -#fastcgi.server = ( ".php" => -# ( "php-local" => -# ( -# "socket" => socket_dir + "/php-fastcgi-1.socket", -# "bin-path" => server_root + "/php-cgi", -# "max-procs" => 1, -# "broken-scriptfilename" => "enable", -# ) -# ), -# ( "php-tcp" => -# ( -# "host" => "127.0.0.1", -# "port" => 9999, -# "check-local" => "disable", -# "broken-scriptfilename" => "enable", -# ) -# ), -# -# ( "php-num-procs" => -# ( -# "socket" => socket_dir + "/php-fastcgi-2.socket", -# "bin-path" => server_root + "/php-cgi", -# "bin-environment" => ( -# "PHP_FCGI_CHILDREN" => "16", -# "PHP_FCGI_MAX_REQUESTS" => "10000", -# ), -# "max-procs" => 5, -# "broken-scriptfilename" => "enable", -# ) -# ), -# ) -## -## Ruby on Rails Example -## -## Normally you only run one Rails application on one vhost. -## -#$HTTP["host"] == "rails1.example.com" { -# server.document-root = server_root + "/rails/someapp/public" -# server.error-handler-404 = "/dispatch.fcgi" -# fastcgi.server = ( ".fcgi" => -# ("someapp" => -# ( "socket" => socket_dir + "/someapp-fcgi.socket", -# "bin-path" => server_root + "/rails/someapp/public/dispatch.fcgi", -# "bin-environment" => ( -# "RAILS_ENV" => "production", -# "TMP" => home_dir + "/rails/someapp", -# ), -# ) -# ) -# ) -#} - -## -## Another example with multiple rails applications on one vhost. -## -## http://blog.lighttpd.net/articles/2005/11/23/lighttpd-1-4-8-and-multiple-rails-apps -## -#$HTTP["host"] == "rails2.example.com" { -# $HTTP["url"] =~ "^/someapp1" { -# server.document-root = server_root + "/rails/someapp1/public" -# server.error-handler-404 = "/dispatch.fcgi" -# fastcgi.server = ( ".fcgi" => -# ("someapp1" => -# ( "socket" => socket_dir + "/someapp1-fcgi.socket", -# "bin-path" => server_root + "/rails/someapp1/public/dispatch.fcgi", -# "bin-environment" => ( -# "RAILS_ENV" => "production", -# "TMP" => home_dir + "/rails/someapp1", -# ), -# "strip-request-uri" => "/someapp1/" -# ) -# ) -# ) -# } -# -# $HTTP["url"] =~ "^/someapp2" { -# server.document-root = server_root + "/rails/someapp2/public" -# server.error-handler-404 = "/dispatch.fcgi" -# fastcgi.server = ( ".fcgi" => -# ("someapp2" => -# ( "socket" => socket_dir + "/someapp2-fcgi.socket", -# "bin-path" => server_root + "/rails/someapp2/public/dispatch.fcgi", -# "bin-environment" => ( -# "RAILS_ENV" => "production", -# "TMP" => home_dir + "/rails/someapp2", -# ), -# "strip-request-uri" => "/someapp2/" -# ) -# ) -# ) -# } -#} - -## chrooted webserver + external PHP -## -## $ spawn-fcgi -f /usr/bin/php-cgi -p 2000 -a 127.0.0.1 -C 8 -## -## webserver chrooted to /srv/www/ -## php running outside the chroot -# -#fastcgi.server = ( -# ".php" => (( -# "host" => "127.0.0.1", -# "port" => "2000", -# "docroot" => "/srv/www/servers/www.example.org/htdocs/" -# ))) -# -#server.chroot = "/srv/www" -#server.document-root = "/servers/wwww.example.org/htdocs/" -# - -## -####################################################################### - --- a/aws/modules.conf +++ /dev/null @@ -1,173 +1,1 @@ -####################################################################### -## -## Modules to load -## ----------------- -## -## at least mod_access and mod_accesslog should be loaded -## all other module should only be loaded if really neccesary -## -## - saves some time -## - saves memory -## -## the default module set contains: -## -## "mod_indexfile", "mod_dirlisting", "mod_staticfile" -## -## you dont have to include those modules in your list -## -## Modules, which are pulled in via conf.d/*.conf -## -## NOTE: the order of modules is important. -## -## - mod_accesslog -> conf.d/access_log.conf -## - mod_compress -> conf.d/compress.conf -## - mod_status -> conf.d/status.conf -## - mod_webdav -> conf.d/webdav.conf -## - mod_cml -> conf.d/cml.conf -## - mod_evhost -> conf.d/evhost.conf -## - mod_simple_vhost -> conf.d/simple_vhost.conf -## - mod_mysql_vhost -> conf.d/mysql_vhost.conf -## - mod_trigger_b4_dl -> conf.d/trigger_b4_dl.conf -## - mod_userdir -> conf.d/userdir.conf -## - mod_rrdtool -> conf.d/rrdtool.conf -## - mod_ssi -> conf.d/ssi.conf -## - mod_cgi -> conf.d/cgi.conf -## - mod_scgi -> conf.d/scgi.conf -## - mod_fastcgi -> conf.d/fastcgi.conf -## - mod_proxy -> conf.d/proxy.conf -## - mod_secdownload -> conf.d/secdownload.conf -## - mod_expire -> conf.d/expire.conf -## -server.modules = ( - "mod_access", -# "mod_alias", -# "mod_auth", -# "mod_evasive", -# "mod_redirect", -# "mod_rewrite", -# "mod_setenv", -# "mod_usertrack", -) - -## -####################################################################### - -####################################################################### -## -## Config for various Modules -## - -## -## mod_ssi -## -#include "conf.d/ssi.conf" - -## -## mod_status -## -#include "conf.d/status.conf" - -## -## mod_webdav -## -#include "conf.d/webdav.conf" - -## -## mod_compress -## -include "conf.d/compress.conf" - -## -## mod_userdir -## -#include "conf.d/userdir.conf" - -## -## mod_magnet -## -#include "conf.d/magnet.conf" - -## -## mod_cml -## -#include "conf.d/cml.conf" - -## -## mod_rrdtool -## -#include "conf.d/rrdtool.conf" - -## -## mod_proxy -## -#include "conf.d/proxy.conf" - -## -## mod_expire -## -include "conf.d/expire.conf" - -## -## mod_secdownload -## -#include "conf.d/secdownload.conf" - -## -####################################################################### - -####################################################################### -## -## CGI modules -## - -## -## SCGI (mod_scgi) -## -#include "conf.d/scgi.conf" - -## -## FastCGI (mod_fastcgi) -## -include "conf.d/fastcgi.conf" - -## -## plain old CGI (mod_cgi) -## -#include "conf.d/cgi.conf" - -## -####################################################################### - -####################################################################### -## -## VHost Modules -## -## Only load ONE of them! -## ======================== -## - -## -## You can use conditionals for vhosts aswell. -## -## see http://www.lighttpd.net/documentation/configuration.html -## - -## -## mod_evhost -## -#include "conf.d/evhost.conf" - -## -## mod_simple_vhost -## -#include "conf.d/simple_vhost.conf" - -## -## mod_mysql_vhost -## -#include "conf.d/mysql_vhost.conf" - -## -####################################################################### - --- a/aws/pg_hba.conf +++ /dev/null @@ -1,77 +1,1 @@ -# PostgreSQL Client Authentication Configuration File -# =================================================== -# -# Refer to the "Client Authentication" section in the -# PostgreSQL documentation for a complete description -# of this file. A short synopsis follows. -# -# This file controls: which hosts are allowed to connect, how clients -# are authenticated, which PostgreSQL user names they can use, which -# databases they can access. Records take one of these forms: -# -# local DATABASE USER METHOD [OPTIONS] -# host DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] -# hostssl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] -# hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTIONS] -# -# (The uppercase items must be replaced by actual values.) -# -# The first field is the connection type: "local" is a Unix-domain socket, -# "host" is either a plain or SSL-encrypted TCP/IP socket, "hostssl" is an -# SSL-encrypted TCP/IP socket, and "hostnossl" is a plain TCP/IP socket. -# -# DATABASE can be "all", "sameuser", "samerole", a database name, or -# a comma-separated list thereof. -# -# USER can be "all", a user name, a group name prefixed with "+", or -# a comma-separated list thereof. In both the DATABASE and USER fields -# you can also write a file name prefixed with "@" to include names from -# a separate file. -# -# CIDR-ADDRESS specifies the set of hosts the record matches. -# It is made up of an IP address and a CIDR mask that is an integer -# (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that specifies -# the number of significant bits in the mask. Alternatively, you can write -# an IP address and netmask in separate columns to specify the set of hosts. -# -# METHOD can be "trust", "reject", "md5", "password", "gss", "sspi", "krb5", -# "ident", "pam", "ldap" or "cert". Note that "password" sends passwords -# in clear text; "md5" is preferred since it sends encrypted passwords. -# -# OPTIONS are a set of options for the authentication in the format -# NAME=VALUE. The available options depend on the different authentication -# methods - refer to the "Client Authentication" section in the documentation -# for a list of which options are available for which authentication methods. -# -# Database and user names containing spaces, commas, quotes and other special -# characters must be quoted. Quoting one of the keywords "all", "sameuser" or -# "samerole" makes the name lose its special character, and just match a -# database or username with that name. -# -# This file is read on server startup and when the postmaster receives -# a SIGHUP signal. If you edit the file on a running system, you have -# to SIGHUP the postmaster for the changes to take effect. You can use -# "pg_ctl reload" to do that. -# Put your actual configuration here -# ---------------------------------- -# -# If you want to allow non-local connections, you need to add more -# "host" records. In that case you will also need to make PostgreSQL listen -# on a non-local interface via the listen_addresses configuration parameter, -# or via the -i or -h command line switches. -# - - - -# TYPE DATABASE USER CIDR-ADDRESS METHOD - -# "local" is for Unix domain socket connections only -local all all trust -# IPv4 local connections: -host all all 127.0.0.1/32 trust -# IPv6 local connections: -host all all ::1/128 trust -#Allow any IP to connect, with a password: -host all all 0.0.0.0 0.0.0.0 md5 - --- a/aws/php.ini +++ /dev/null @@ -1,1662 +1,1 @@ -[PHP] -date.timezone = "Australia/Sydney" - -;;;;;;;;;;;;;;;;;;; -; About php.ini ; -;;;;;;;;;;;;;;;;;;; -; PHP's initialization file, generally called php.ini, is responsible for -; configuring many of the aspects of PHP's behavior. - -; PHP attempts to find and load this configuration from a number of locations. -; The following is a summary of its search order: -; 1. SAPI module specific location. -; 2. The PHPRC environment variable. (As of PHP 5.2.0) -; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0) -; 4. Current working directory (except CLI) -; 5. The web server's directory (for SAPI modules), or directory of PHP -; (otherwise in Windows) -; 6. The directory from the --with-config-file-path compile time option, or the -; Windows directory (C:\windows or C:\winnt) -; See the PHP docs for more specific information. -; http://www.php.net/manual/en/configuration.file.php - -; The syntax of the file is extremely simple. Whitespace and Lines -; beginning with a semicolon are silently ignored (as you probably guessed). -; Section headers (e.g. [Foo]) are also silently ignored, even though -; they might mean something in the future. - -; Directives following the section heading [PATH=/www/mysite] only -; apply to PHP files in the /www/mysite directory. Directives -; following the section heading [HOST=www.example.com] only apply to -; PHP files served from www.example.com. Directives set in these -; special sections cannot be overridden by user-defined INI files or -; at runtime. Currently, [PATH=] and [HOST=] sections only work under -; CGI/FastCGI. -; http://www.php.net/manual/en/ini.sections.php - -; Directives are specified using the following syntax: -; directive = value -; Directive names are *case sensitive* - foo=bar is different from FOO=bar. -; Directives are variables used to configure PHP or PHP extensions. -; There is no name validation. If PHP can't find an expected -; directive because it is not set or is mistyped, a default value will be used. - -; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one -; of the INI constants (On, Off, True, False, Yes, No and None) or an expression -; (e.g. E_ALL & ~E_NOTICE), a quoted string ("bar"), or a reference to a -; previously set variable or directive (e.g. ${foo}) - -; Expressions in the INI file are limited to bitwise operators and parentheses: -; | bitwise OR -; ^ bitwise XOR -; & bitwise AND -; ~ bitwise NOT -; ! boolean NOT - -; Boolean flags can be turned on using the values 1, On, True or Yes. -; They can be turned off using the values 0, Off, False or No. - -; An empty string can be denoted by simply not writing anything after the equal -; sign, or by using the None keyword: - -; foo = ; sets foo to an empty string -; foo = None ; sets foo to an empty string -; foo = "None" ; sets foo to the string 'None' - -; If you use constants in your value, and these constants belong to a -; dynamically loaded extension (either a PHP extension or a Zend extension), -; you may only use these constants *after* the line that loads the extension. - -;;;;;;;;;;;;;;;;;;; -; About this file ; -;;;;;;;;;;;;;;;;;;; -; PHP comes packaged with two INI files. One that is recommended to be used -; in production environments and one that is recommended to be used in -; development environments. - -; php.ini-production contains settings which hold security, performance and -; best practices at its core. But please be aware, these settings may break -; compatibility with older or less security conscience applications. We -; recommending using the production ini in production and testing environments. - -; php.ini-development is very similar to its production variant, except it's -; much more verbose when it comes to errors. We recommending using the -; development version only in development environments as errors shown to -; application users can inadvertently leak otherwise secure information. - -; This 2 files are provided, by RPM, in /usr/share/doc/php-common-*/ -; File used by RPM (the /etc/php.ini) is mainly the php.ini-production - -;;;;;;;;;;;;;;;;;;; -; Quick Reference ; -;;;;;;;;;;;;;;;;;;; -; The following are all the settings which are different in either the production -; or development versions of the INIs with respect to PHP's default behavior. -; Please see the actual settings later in the document for more details as to why -; we recommend these changes in PHP's behavior. - -; allow_call_time_pass_reference -; Default Value: On -; Development Value: Off -; Production Value: Off - -; display_errors -; Default Value: On -; Development Value: On -; Production Value: Off - -; display_startup_errors -; Default Value: Off -; Development Value: On -; Production Value: Off - -; error_reporting -; Default Value: E_ALL & ~E_NOTICE -; Development Value: E_ALL | E_STRICT -; Production Value: E_ALL & ~E_DEPRECATED - -; html_errors -; Default Value: On -; Development Value: On -; Production value: Off - -; log_errors -; Default Value: Off -; Development Value: On -; Production Value: On - -; magic_quotes_gpc -; Default Value: On -; Development Value: Off -; Production Value: Off - -; max_input_time -; Default Value: -1 (Unlimited) -; Development Value: 60 (60 seconds) -; Production Value: 60 (60 seconds) - -; output_buffering -; Default Value: Off -; Development Value: 4096 -; Production Value: 4096 - -; register_argc_argv -; Default Value: On -; Development Value: Off -; Production Value: Off - -; register_long_arrays -; Default Value: On -; Development Value: Off -; Production Value: Off - -; request_order -; Default Value: None -; Development Value: "GP" -; Production Value: "GP" - -; session.bug_compat_42 -; Default Value: On -; Development Value: On -; Production Value: Off - -; session.bug_compat_warn -; Default Value: On -; Development Value: On -; Production Value: Off - -; session.gc_divisor -; Default Value: 100 -; Development Value: 1000 -; Production Value: 1000 - -; session.hash_bits_per_character -; Default Value: 4 -; Development Value: 5 -; Production Value: 5 - -; short_open_tag -; Default Value: On -; Development Value: Off -; Production Value: Off - -; track_errors -; Default Value: Off -; Development Value: On -; Production Value: Off - -; url_rewriter.tags -; Default Value: "a=href,area=href,frame=src,form=,fieldset=" -; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry" - -; variables_order -; Default Value: "EGPCS" -; Development Value: "GPCS" -; Production Value: "GPCS" - -;;;;;;;;;;;;;;;;;;;; -; php.ini Options ; -;;;;;;;;;;;;;;;;;;;; -; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini" -;user_ini.filename = ".user.ini" - -; To disable this feature set this option to empty value -;user_ini.filename = - -; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes) -;user_ini.cache_ttl = 300 - -;;;;;;;;;;;;;;;;;;;; -; Language Options ; -;;;;;;;;;;;;;;;;;;;; - -; Enable the PHP scripting language engine under Apache. -; http://www.php.net/manual/en/apache.configuration.php#ini.engine -engine = On - -; This directive determines whether or not PHP will recognize code between -; tags as PHP source which should be processed as such. It's been -; recommended for several years that you not use the short tag "short cut" and -; instead to use the full tag combination. With the wide spread use -; of XML and use of these tags by other languages, the server can become easily -; confused and end up parsing the wrong code in the wrong context. But because -; this short cut has been a feature for such a long time, it's currently still -; supported for backwards compatibility, but we recommend you don't use them. -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://www.php.net/manual/en/ini.core.php#ini.short-open-tag -short_open_tag = Off - -; Allow ASP-style <% %> tags. -; http://www.php.net/manual/en/ini.core.php#ini.asp-tags -asp_tags = Off - -; The number of significant digits displayed in floating point numbers. -; http://www.php.net/manual/en/ini.core.php#ini.precision -precision = 14 - -; Enforce year 2000 compliance (will cause problems with non-compliant browsers) -; http://www.php.net/manual/en/ini.core.php#ini.y2k-compliance -y2k_compliance = On - -; Output buffering is a mechanism for controlling how much output data -; (excluding headers and cookies) PHP should keep internally before pushing that -; data to the client. If your application's output exceeds this setting, PHP -; will send that data in chunks of roughly the size you specify. -; Turning on this setting and managing its maximum buffer size can yield some -; interesting side-effects depending on your application and web server. -; You may be able to send headers and cookies after you've already sent output -; through print or echo. You also may see performance benefits if your server is -; emitting less packets due to buffered output versus PHP streaming the output -; as it gets it. On production servers, 4096 bytes is a good setting for performance -; reasons. -; Note: Output buffering can also be controlled via Output Buffering Control -; functions. -; Possible Values: -; On = Enabled and buffer is unlimited. (Use with caution) -; Off = Disabled -; Integer = Enables the buffer and sets its maximum size in bytes. -; Default Value: Off -; Development Value: 4096 -; Production Value: 4096 -; http://www.php.net/manual/en/outcontrol.configuration.php#ini.output-buffering -output_buffering = 4096 - -; You can redirect all of the output of your scripts to a function. For -; example, if you set output_handler to "mb_output_handler", character -; encoding will be transparently converted to the specified encoding. -; Setting any output handler automatically turns on output buffering. -; Note: People who wrote portable scripts should not depend on this ini -; directive. Instead, explicitly set the output handler using ob_start(). -; Using this ini directive may cause problems unless you know what script -; is doing. -; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler" -; and you cannot use both "ob_gzhandler" and "zlib.output_compression". -; Note: output_handler must be empty if this is set 'On' !!!! -; Instead you must use zlib.output_handler. -; http://www.php.net/manual/en/outcontrol.configuration.php#ini.output-handler -;output_handler = - -; Transparent output compression using the zlib library -; Valid values for this option are 'off', 'on', or a specific buffer size -; to be used for compression (default is 4KB) -; Note: Resulting chunk size may vary due to nature of compression. PHP -; outputs chunks that are few hundreds bytes each as a result of -; compression. If you prefer a larger chunk size for better -; performance, enable output_buffering in addition. -; Note: You need to use zlib.output_handler instead of the standard -; output_handler, or otherwise the output will be corrupted. -; http://www.php.net/manual/en/zlib.configuration.php#ini.zlib.output-compression -zlib.output_compression = on - -; http://www.php.net/manual/en/zlib.configuration.php#ini.zlib.output-compression-level -;zlib.output_compression_level = -1 - -; You cannot specify additional output handlers if zlib.output_compression -; is activated here. This setting does the same as output_handler but in -; a different order. -; http://www.php.net/manual/en/zlib.configuration.php#ini.zlib.output-handler -;zlib.output_handler = - -; Implicit flush tells PHP to tell the output layer to flush itself -; automatically after every output block. This is equivalent to calling the -; PHP function flush() after each and every call to print() or echo() and each -; and every HTML block. Turning this option on has serious performance -; implications and is generally recommended for debugging purposes only. -; http://www.php.net/manual/en/outcontrol.configuration.php#ini.implicit-flush -implicit_flush = Off - -; The unserialize callback function will be called (with the undefined class' -; name as parameter), if the unserializer finds an undefined class -; which should be instantiated. A warning appears if the specified function is -; not defined, or if the function doesn't include/implement the missing class. -; So only set this entry, if you really want to implement such a -; callback-function. -unserialize_callback_func = - -; When floats & doubles are serialized store serialize_precision significant -; digits after the floating point. The default value ensures that when floats -; are decoded with unserialize, the data will remain the same. -serialize_precision = 100 - -; This directive allows you to enable and disable warnings which PHP will issue -; if you pass a value by reference at function call time. Passing values by -; reference at function call time is a deprecated feature which will be removed -; from PHP at some point in the near future. The acceptable method for passing a -; value by reference to a function is by declaring the reference in the functions -; definition, not at call time. This directive does not disable this feature, it -; only determines whether PHP will warn you about it or not. These warnings -; should enabled in development environments only. -; Default Value: On (Suppress warnings) -; Development Value: Off (Issue warnings) -; Production Value: Off (Issue warnings) -; http://www.php.net/manual/en/ini.core.php#ini.allow-call-time-pass-reference -allow_call_time_pass_reference = Off - -; Safe Mode -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode -safe_mode = Off - -; By default, Safe Mode does a UID compare check when -; opening files. If you want to relax this to a GID compare, -; then turn on safe_mode_gid. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-gid -safe_mode_gid = Off - -; When safe_mode is on, UID/GID checks are bypassed when -; including files from this directory and its subdirectories. -; (directory must also be in include_path or full path must -; be used when including) -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-include-dir -safe_mode_include_dir = - -; When safe_mode is on, only executables located in the safe_mode_exec_dir -; will be allowed to be executed via the exec family of functions. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-exec-dir -safe_mode_exec_dir = - -; Setting certain environment variables may be a potential security breach. -; This directive contains a comma-delimited list of prefixes. In Safe Mode, -; the user may only alter environment variables whose names begin with the -; prefixes supplied here. By default, users will only be able to set -; environment variables that begin with PHP_ (e.g. PHP_FOO=BAR). -; Note: If this directive is empty, PHP will let the user modify ANY -; environment variable! -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-allowed-env-vars -safe_mode_allowed_env_vars = PHP_ - -; This directive contains a comma-delimited list of environment variables that -; the end user won't be able to change using putenv(). These variables will be -; protected even if safe_mode_allowed_env_vars is set to allow to change them. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.safe-mode-protected-env-vars -safe_mode_protected_env_vars = LD_LIBRARY_PATH - -; open_basedir, if set, limits all file operations to the defined directory -; and below. This directive makes most sense if used in a per-directory -; or per-virtualhost web server configuration file. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.open-basedir -;open_basedir = - -; This directive allows you to disable certain functions for security reasons. -; It receives a comma-delimited list of function names. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.disable-functions -disable_functions = - -; This directive allows you to disable certain classes for security reasons. -; It receives a comma-delimited list of class names. This directive is -; *NOT* affected by whether Safe Mode is turned On or Off. -; http://www.php.net/manual/en/ini.sect.safe-mode.php#ini.disable-classes -disable_classes = - -; Colors for Syntax Highlighting mode. Anything that's acceptable in -; would work. -; http://www.php.net/manual/en/misc.configuration.php#ini.syntax-highlighting -;highlight.string = #DD0000 -;highlight.comment = #FF9900 -;highlight.keyword = #007700 -;highlight.bg = #FFFFFF -;highlight.default = #0000BB -;highlight.html = #000000 - -; If enabled, the request will be allowed to complete even if the user aborts -; the request. Consider enabling it if executing long requests, which may end up -; being interrupted by the user or a browser timing out. PHP's default behavior -; is to disable this feature. -; http://www.php.net/manual/en/misc.configuration.php#ini.ignore-user-abort -;ignore_user_abort = On - -; Determines the size of the realpath cache to be used by PHP. This value should -; be increased on systems where PHP opens many files to reflect the quantity of -; the file operations performed. -; http://www.php.net/manual/en/ini.core.php#ini.realpath-cache-size -;realpath_cache_size = 16k - -; Duration of time, in seconds for which to cache realpath information for a given -; file or directory. For systems with rarely changing files, consider increasing this -; value. -; http://www.php.net/manual/en/ini.core.php#ini.realpath-cache-ttl -;realpath_cache_ttl = 120 - -;;;;;;;;;;;;;;;;; -; Miscellaneous ; -;;;;;;;;;;;;;;;;; - -; Decides whether PHP may expose the fact that it is installed on the server -; (e.g. by adding its signature to the Web server header). It is no security -; threat in any way, but it makes it possible to determine whether you use PHP -; on your server or not. -; http://www.php.net/manual/en/ini.core.php#ini.expose-php -expose_php = On - -;;;;;;;;;;;;;;;;;;; -; Resource Limits ; -;;;;;;;;;;;;;;;;;;; - -; Maximum execution time of each script, in seconds -; http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time -max_execution_time = 30 - -; Maximum amount of time each script may spend parsing request data. It's a good -; idea to limit this time on productions servers in order to eliminate unexpectedly -; long running scripts. -; Default Value: -1 (Unlimited) -; Development Value: 60 (60 seconds) -; Production Value: 60 (60 seconds) -; http://www.php.net/manual/en/info.configuration.php#ini.max-input-time -max_input_time = 60 - -; Maximum input variable nesting level -; http://www.php.net/manual/en/info.configuration.php#ini.max-input-nesting-level -;max_input_nesting_level = 64 - -; Maximum amount of memory a script may consume (128MB) -; http://www.php.net/manual/en/ini.core.php#ini.memory-limit -memory_limit = 128M - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Error handling and logging ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; This directive informs PHP of which errors, warnings and notices you would like -; it to take action for. The recommended way of setting values for this -; directive is through the use of the error level constants and bitwise -; operators. The error level constants are below here for convenience as well as -; some common settings and their meanings. -; By default, PHP is set to take action on all errors, notices and warnings EXCEPT -; those related to E_NOTICE and E_STRICT, which together cover best practices and -; recommended coding standards in PHP. For performance reasons, this is the -; recommend error reporting setting. Your production server shouldn't be wasting -; resources complaining about best practices and coding standards. That's what -; development servers and development settings are for. -; Note: The php.ini-development file has this setting as E_ALL | E_STRICT. This -; means it pretty much reports everything which is exactly what you want during -; development and early testing. -; -; Error Level Constants: -; E_ALL - All errors and warnings (includes E_STRICT as of PHP 6.0.0) -; E_ERROR - fatal run-time errors -; E_RECOVERABLE_ERROR - almost fatal run-time errors -; E_WARNING - run-time warnings (non-fatal errors) -; E_PARSE - compile-time parse errors -; E_NOTICE - run-time notices (these are warnings which often result -; from a bug in your code, but it's possible that it was -; intentional (e.g., using an uninitialized variable and -; relying on the fact it's automatically initialized to an -; empty string) -; E_STRICT - run-time notices, enable to have PHP suggest changes -; to your code which will ensure the best interoperability -; and forward compatibility of your code -; E_CORE_ERROR - fatal errors that occur during PHP's initial startup -; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's -; initial startup -; E_COMPILE_ERROR - fatal compile-time errors -; E_COMPILE_WARNING - compile-time warnings (non-fatal errors) -; E_USER_ERROR - user-generated error message -; E_USER_WARNING - user-generated warning message -; E_USER_NOTICE - user-generated notice message -; E_DEPRECATED - warn about code that will not work in future versions -; of PHP -; E_USER_DEPRECATED - user-generated deprecation warnings -; -; Common Values: -; E_ALL & ~E_NOTICE (Show all errors, except for notices and coding standards warnings.) -; E_ALL & ~E_NOTICE | E_STRICT (Show all errors, except for notices) -; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors) -; E_ALL | E_STRICT (Show all errors, warnings and notices including coding standards.) -; Default Value: E_ALL & ~E_NOTICE -; Development Value: E_ALL | E_STRICT -; Production Value: E_ALL & ~E_DEPRECATED -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-reporting -error_reporting = E_ALL & ~E_DEPRECATED - -; This directive controls whether or not and where PHP will output errors, -; notices and warnings too. Error output is very useful during development, but -; it could be very dangerous in production environments. Depending on the code -; which is triggering the error, sensitive information could potentially leak -; out of your application such as database usernames and passwords or worse. -; It's recommended that errors be logged on production servers rather than -; having the errors sent to STDOUT. -; Possible Values: -; Off = Do not display any errors -; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) -; On or stdout = Display errors to STDOUT -; Default Value: On -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors -display_errors = Off - -; The display of errors which occur during PHP's startup sequence are handled -; separately from display_errors. PHP's default behavior is to suppress those -; errors from clients. Turning the display of startup errors on can be useful in -; debugging configuration problems. But, it's strongly recommended that you -; leave this setting off on production servers. -; Default Value: Off -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-startup-errors -display_startup_errors = Off - -; Besides displaying errors, PHP can also log errors to locations such as a -; server-specific log, STDERR, or a location specified by the error_log -; directive found below. While errors should not be displayed on productions -; servers they should still be monitored and logging is a great way to do that. -; Default Value: Off -; Development Value: On -; Production Value: On -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.log-errors -log_errors = On - -; Set maximum length of log_errors. In error_log information about the source is -; added. The default is 1024 and 0 allows to not apply any maximum length at all. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.log-errors-max-len -log_errors_max_len = 1024 - -; Do not log repeated messages. Repeated errors must occur in same file on same -; line unless ignore_repeated_source is set true. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.ignore-repeated-errors -ignore_repeated_errors = Off - -; Ignore source of message when ignoring repeated messages. When this setting -; is On you will not log errors with repeated messages from different files or -; source lines. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.ignore-repeated-source -ignore_repeated_source = Off - -; If this parameter is set to Off, then memory leaks will not be shown (on -; stdout or in the log). This has only effect in a debug compile, and if -; error reporting includes E_WARNING in the allowed list -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.report-memleaks -report_memleaks = On - -; This setting is on by default. -;report_zend_debug = 0 - -; Store the last error/warning message in $php_errormsg (boolean). Setting this value -; to On can assist in debugging and is appropriate for development servers. It should -; however be disabled on production servers. -; Default Value: Off -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.track-errors -track_errors = Off - -; Turn off normal error reporting and emit XML-RPC error XML -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.xmlrpc-errors -;xmlrpc_errors = 0 - -; An XML-RPC faultCode -;xmlrpc_error_number = 0 - -; When PHP displays or logs an error, it has the capability of inserting html -; links to documentation related to that error. This directive controls whether -; those HTML links appear in error messages or not. For performance and security -; reasons, it's recommended you disable this on production servers. -; Default Value: On -; Development Value: On -; Production value: Off -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.html-errors -html_errors = Off - -; If html_errors is set On PHP produces clickable error messages that direct -; to a page describing the error or function causing the error in detail. -; You can download a copy of the PHP manual from http://www.php.net/docs.php -; and change docref_root to the base URL of your local copy including the -; leading '/'. You must also specify the file extension being used including -; the dot. PHP's default behavior is to leave these settings empty. -; Note: Never use this feature for production boxes. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.docref-root -; Examples -;docref_root = "/phpmanual/" - -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.docref-ext -;docref_ext = .html - -; String to output before an error message. PHP's default behavior is to leave -; this setting blank. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-prepend-string -; Example: -;error_prepend_string = "" - -; String to output after an error message. PHP's default behavior is to leave -; this setting blank. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-append-string -; Example: -;error_append_string = "" - -; Log errors to specified file. PHP's default behavior is to leave this value -; empty. -; http://www.php.net/manual/en/errorfunc.configuration.php#ini.error-log -; Example: -;error_log = php_errors.log -; Log errors to syslog (Event Log on NT, not valid in Windows 95). -;error_log = syslog - -;;;;;;;;;;;;;;;;; -; Data Handling ; -;;;;;;;;;;;;;;;;; - -; Note - track_vars is ALWAYS enabled as of PHP 4.0.3 - -; The separator used in PHP generated URLs to separate arguments. -; PHP's default setting is "&". -; http://www.php.net/manual/en/ini.core.php#ini.arg-separator.output -; Example: -;arg_separator.output = "&" - -; List of separator(s) used by PHP to parse input URLs into variables. -; PHP's default setting is "&". -; NOTE: Every character in this directive is considered as separator! -; http://www.php.net/manual/en/ini.core.php#ini.arg-separator.input -; Example: -;arg_separator.input = ";&" - -; This directive determines which super global arrays are registered when PHP -; starts up. If the register_globals directive is enabled, it also determines -; what order variables are populated into the global space. G,P,C,E & S are -; abbreviations for the following respective super globals: GET, POST, COOKIE, -; ENV and SERVER. There is a performance penalty paid for the registration of -; these arrays and because ENV is not as commonly used as the others, ENV is -; is not recommended on productions servers. You can still get access to -; the environment variables through getenv() should you need to. -; Default Value: "EGPCS" -; Development Value: "GPCS" -; Production Value: "GPCS"; -; http://www.php.net/manual/en/ini.core.php#ini.variables-order -variables_order = "GPCS" - -; This directive determines which super global data (G,P,C,E & S) should -; be registered into the super global array REQUEST. If so, it also determines -; the order in which that data is registered. The values for this directive are -; specified in the same manner as the variables_order directive, EXCEPT one. -; Leaving this value empty will cause PHP to use the value set in the -; variables_order directive. It does not mean it will leave the super globals -; array REQUEST empty. -; Default Value: None -; Development Value: "GP" -; Production Value: "GP" -; http://www.php.net/manual/en/ini.core.php#ini.request-order -request_order = "GP" - -; Whether or not to register the EGPCS variables as global variables. You may -; want to turn this off if you don't want to clutter your scripts' global scope -; with user data. This makes most sense when coupled with track_vars - in which -; case you can access all of the GPC variables through the $HTTP_*_VARS[], -; variables. -; You should do your best to write your scripts so that they do not require -; register_globals to be on; Using form variables as globals can easily lead -; to possible security problems, if the code is not very well thought of. -; http://www.php.net/manual/en/ini.core.php#ini.register-globals -register_globals = Off - -; Determines whether the deprecated long $HTTP_*_VARS type predefined variables -; are registered by PHP or not. As they are deprecated, we obviously don't -; recommend you use them. They are on by default for compatibility reasons but -; they are not recommended on production servers. -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://www.php.net/manual/en/ini.core.php#ini.register-long-arrays -register_long_arrays = Off - -; This directive determines whether PHP registers $argv & $argc each time it -; runs. $argv contains an array of all the arguments passed to PHP when a script -; is invoked. $argc contains an integer representing the number of arguments -; that were passed when the script was invoked. These arrays are extremely -; useful when running scripts from the command line. When this directive is -; enabled, registering these variables consumes CPU cycles and memory each time -; a script is executed. For performance reasons, this feature should be disabled -; on production servers. -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://www.php.net/manual/en/ini.core.php#ini.register-argc-argv -register_argc_argv = Off - -; When enabled, the SERVER and ENV variables are created when they're first -; used (Just In Time) instead of when the script starts. If these variables -; are not used within a script, having this directive on will result in a -; performance gain. The PHP directives register_globals, register_long_arrays, -; and register_argc_argv must be disabled for this directive to have any affect. -; http://www.php.net/manual/en/ini.core.php#ini.auto-globals-jit -auto_globals_jit = On - -; Maximum size of POST data that PHP will accept. -; http://www.php.net/manual/en/ini.core.php#ini.post-max-size -post_max_size = 8M - -; Magic quotes are a preprocessing feature of PHP where PHP will attempt to -; escape any character sequences in GET, POST, COOKIE and ENV data which might -; otherwise corrupt data being placed in resources such as databases before -; making that data available to you. Because of character encoding issues and -; non-standard SQL implementations across many databases, it's not currently -; possible for this feature to be 100% accurate. PHP's default behavior is to -; enable the feature. We strongly recommend you use the escaping mechanisms -; designed specifically for the database your using instead of relying on this -; feature. Also note, this feature has been deprecated as of PHP 5.3.0 and is -; scheduled for removal in PHP 6. -; Default Value: On -; Development Value: Off -; Production Value: Off -; http://www.php.net/manual/en/info.configuration.php#ini.magic-quotes-gpc -magic_quotes_gpc = Off - -; Magic quotes for runtime-generated data, e.g. data from SQL, from exec(), etc. -; http://www.php.net/manual/en/info.configuration.php#ini.magic-quotes-runtime -magic_quotes_runtime = Off - -; Use Sybase-style magic quotes (escape ' with '' instead of \'). -; http://www.php.net/manual/en/sybase.configuration.php#ini.magic-quotes-sybase -magic_quotes_sybase = Off - -; Automatically add files before PHP document. -; http://www.php.net/manual/en/ini.core.php#ini.auto-prepend-file -auto_prepend_file = - -; Automatically add files after PHP document. -; http://www.php.net/manual/en/ini.core.php#ini.auto-append-file -auto_append_file = - -; As of 4.0b4, PHP always outputs a character encoding by default in -; the Content-type: header. To disable sending of the charset, simply -; set it to be empty. -; -; PHP's built-in default is text/html -; http://www.php.net/manual/en/ini.core.php#ini.default-mimetype -default_mimetype = "text/html" - -; PHP's default character set is set to empty. -; http://www.php.net/manual/en/ini.core.php#ini.default-charset -;default_charset = "iso-8859-1" - -; Always populate the $HTTP_RAW_POST_DATA variable. PHP's default behavior is -; to disable this feature. -; http://www.php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data -;always_populate_raw_post_data = On - -;;;;;;;;;;;;;;;;;;;;;;;;; -; Paths and Directories ; -;;;;;;;;;;;;;;;;;;;;;;;;; - -; UNIX: "/path1:/path2" -;include_path = ".:/php/includes" -; -; Windows: "\path1;\path2" -;include_path = ".;c:\php\includes" -; -; PHP's default setting for include_path is ".;/path/to/php/pear" -; http://www.php.net/manual/en/ini.core.php#ini.include-path - -; The root of the PHP pages, used only if nonempty. -; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root -; if you are running php as a CGI under any web server (other than IIS) -; see documentation for security issues. The alternate is to use the -; cgi.force_redirect configuration below -; http://www.php.net/manual/en/ini.core.php#ini.doc-root -doc_root = - -; The directory under which PHP opens the script using /~username used only -; if nonempty. -; http://www.php.net/manual/en/ini.core.php#ini.user-dir -user_dir = - -; Directory in which the loadable extensions (modules) reside. -; http://www.php.net/manual/en/ini.core.php#ini.extension-dir -; extension_dir = "./" - -; Whether or not to enable the dl() function. The dl() function does NOT work -; properly in multithreaded servers, such as IIS or Zeus, and is automatically -; disabled on them. -; http://www.php.net/manual/en/info.configuration.php#ini.enable-dl -enable_dl = Off - -; cgi.force_redirect is necessary to provide security running PHP as a CGI under -; most web servers. Left undefined, PHP turns this on by default. You can -; turn it off here AT YOUR OWN RISK -; **You CAN safely turn this off for IIS, in fact, you MUST.** -; http://www.php.net/manual/en/ini.core.php#ini.cgi.force-redirect -;cgi.force_redirect = 1 - -; if cgi.nph is enabled it will force cgi to always sent Status: 200 with -; every request. PHP's default behavior is to disable this feature. -;cgi.nph = 1 - -; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape -; (iPlanet) web servers, you MAY need to set an environment variable name that PHP -; will look for to know it is OK to continue execution. Setting this variable MAY -; cause security issues, KNOW WHAT YOU ARE DOING FIRST. -; http://www.php.net/manual/en/ini.core.php#ini.cgi.redirect-status-env -;cgi.redirect_status_env = ; - -; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's -; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok -; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting -; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting -; of zero causes PHP to behave as before. Default is 1. You should fix your scripts -; to use SCRIPT_FILENAME rather than PATH_TRANSLATED. -; http://www.php.net/manual/en/ini.core.php#ini.cgi.fix-pathinfo -cgi.fix_pathinfo=1 - -; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate -; security tokens of the calling client. This allows IIS to define the -; security context that the request runs under. mod_fastcgi under Apache -; does not currently support this feature (03/17/2002) -; Set to 1 if running under IIS. Default is zero. -; http://www.php.net/manual/en/ini.core.php#ini.fastcgi.impersonate -;fastcgi.impersonate = 1; - -; Disable logging through FastCGI connection. PHP's default behavior is to enable -; this feature. -;fastcgi.logging = 0 - -; cgi.rfc2616_headers configuration option tells PHP what type of headers to -; use when sending HTTP response code. If it's set 0 PHP sends Status: header that -; is supported by Apache. When this option is set to 1 PHP will send -; RFC2616 compliant header. -; Default is zero. -; http://www.php.net/manual/en/ini.core.php#ini.cgi.rfc2616-headers -;cgi.rfc2616_headers = 0 - -;;;;;;;;;;;;;;;; -; File Uploads ; -;;;;;;;;;;;;;;;; - -; Whether to allow HTTP file uploads. -; http://www.php.net/manual/en/ini.core.php#ini.file-uploads -file_uploads = On - -; Temporary directory for HTTP uploaded files (will use system default if not -; specified). -; http://www.php.net/manual/en/ini.core.php#ini.upload-tmp-dir -;upload_tmp_dir = - -; Maximum allowed size for uploaded files. -; http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize -upload_max_filesize = 2M - -;;;;;;;;;;;;;;;;;; -; Fopen wrappers ; -;;;;;;;;;;;;;;;;;; - -; Whether to allow the treatment of URLs (like http:// or ftp://) as files. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen -allow_url_fopen = On - -; Whether to allow include/require to open URLs (like http:// or ftp://) as files. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-include -allow_url_include = Off - -; Define the anonymous ftp password (your email address). PHP's default setting -; for this is empty. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.from -;from="john@doe.com" - -; Define the User-Agent string. PHP's default setting for this is empty. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.user-agent -;user_agent="PHP" - -; Default timeout for socket based streams (seconds) -; http://www.php.net/manual/en/filesystem.configuration.php#ini.default-socket-timeout -default_socket_timeout = 60 - -; If your scripts have to deal with files from Macintosh systems, -; or you are running on a Mac and need to deal with files from -; unix or win32 systems, setting this flag will cause PHP to -; automatically detect the EOL character in those files so that -; fgets() and file() will work regardless of the source of the file. -; http://www.php.net/manual/en/filesystem.configuration.php#ini.auto-detect-line-endings -;auto_detect_line_endings = Off - -;;;;;;;;;;;;;;;;;;;;;; -; Dynamic Extensions ; -;;;;;;;;;;;;;;;;;;;;;; - -; If you wish to have an extension loaded automatically, use the following -; syntax: -; -; extension=modulename.extension -; -; For example -; -; extension=msql.so -; -; ... or with a path: -; -; extension=/path/to/extension/msql.so -; -; If you only provide the name of the extension, PHP will look for it in its -; default extension directory. - -;;;; -; Note: packaged extension modules are now loaded via the .ini files -; found in the directory /etc/php.d; these are loaded by default. -;;;; - - -;;;;;;;;;;;;;;;;;;; -; Module Settings ; -;;;;;;;;;;;;;;;;;;; - -[Date] -; Defines the default timezone used by the date functions -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone -;date.timezone = - -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-latitude -;date.default_latitude = 31.7667 - -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-longitude -;date.default_longitude = 35.2333 - -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.sunrise-zenith -;date.sunrise_zenith = 90.583333 - -; http://www.php.net/manual/en/datetime.configuration.php#ini.date.sunset-zenith -;date.sunset_zenith = 90.583333 - -[filter] -; http://www.php.net/manual/en/filter.configuration.php#ini.filter.default -;filter.default = unsafe_raw - -; http://www.php.net/manual/en/filter.configuration.php#ini.filter.default-flags -;filter.default_flags = - -[iconv] -;iconv.input_encoding = ISO-8859-1 -;iconv.internal_encoding = ISO-8859-1 -;iconv.output_encoding = ISO-8859-1 - -[intl] -;intl.default_locale = - -[sqlite] -; http://www.php.net/manual/en/sqlite.configuration.php#ini.sqlite.assoc-case -;sqlite.assoc_case = 0 - -[sqlite3] -;sqlite3.extension_dir = - -[Pcre] -;PCRE library backtracking limit. -; http://www.php.net/manual/en/pcre.configuration.php#ini.pcre.backtrack-limit -;pcre.backtrack_limit=100000 - -;PCRE library recursion limit. -;Please note that if you set this value to a high number you may consume all -;the available process stack and eventually crash PHP (due to reaching the -;stack size limit imposed by the Operating System). -; http://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit -;pcre.recursion_limit=100000 - -[Pdo] -; Whether to pool ODBC connections. Can be one of "strict", "relaxed" or "off" -; http://www.php.net/manual/en/ref.pdo-odbc.php#ini.pdo-odbc.connection-pooling -;pdo_odbc.connection_pooling=strict - -[Phar] -; http://www.php.net/manual/en/phar.configuration.php#ini.phar.readonly -;phar.readonly = On - -; http://www.php.net/manual/en/phar.configuration.php#ini.phar.require-hash -;phar.require_hash = On - -;phar.cache_list = - -[Syslog] -; Whether or not to define the various syslog variables (e.g. $LOG_PID, -; $LOG_CRON, etc.). Turning it off is a good idea performance-wise. In -; runtime, you can define these variables by calling define_syslog_variables(). -; http://www.php.net/manual/en/network.configuration.php#ini.define-syslog-variables -define_syslog_variables = Off - -[mail function] -; For Win32 only. -; http://www.php.net/manual/en/mail.configuration.php#ini.smtp -SMTP = localhost -; http://www.php.net/manual/en/mail.configuration.php#ini.smtp-port -smtp_port = 25 - -; For Win32 only. -; http://www.php.net/manual/en/mail.configuration.php#ini.sendmail-from -;sendmail_from = me@example.com - -; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). -; http://www.php.net/manual/en/mail.configuration.php#ini.sendmail-path -sendmail_path = /usr/sbin/sendmail -t -i - -; Force the addition of the specified parameters to be passed as extra parameters -; to the sendmail binary. These parameters will always replace the value of -; the 5th parameter to mail(), even in safe mode. -;mail.force_extra_parameters = - -; Add X-PHP-Originaiting-Script: that will include uid of the script followed by the filename -mail.add_x_header = On - -; Log all mail() calls including the full path of the script, line #, to address and headers -;mail.log = - -[SQL] -; http://www.php.net/manual/en/ini.core.php#ini.sql.safe-mode -sql.safe_mode = Off - -[ODBC] -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.default-db -;odbc.default_db = Not yet implemented - -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.default-user -;odbc.default_user = Not yet implemented - -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.default-pw -;odbc.default_pw = Not yet implemented - -; Allow or prevent persistent links. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.allow-persistent -odbc.allow_persistent = On - -; Check that a connection is still valid before reuse. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.check-persistent -odbc.check_persistent = On - -; Maximum number of persistent links. -1 means no limit. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.max-persistent -odbc.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.max-links -odbc.max_links = -1 - -; Handling of LONG fields. Returns number of bytes to variables. 0 means -; passthru. -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.defaultlrl -odbc.defaultlrl = 4096 - -; Handling of binary data. 0 means passthru, 1 return as is, 2 convert to char. -; See the documentation on odbc_binmode and odbc_longreadlen for an explanation -; of uodbc.defaultlrl and uodbc.defaultbinmode -; http://www.php.net/manual/en/odbc.configuration.php#ini.uodbc.defaultbinmode -odbc.defaultbinmode = 1 - -;birdstep.max_links = -1 - -[MySQL] -; Allow or prevent persistent links. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.allow-persistent -mysql.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.max-persistent -mysql.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.max-links -mysql.max_links = -1 - -; Default port number for mysql_connect(). If unset, mysql_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-port -mysql.default_port = - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-socket -mysql.default_socket = - -; Default host for mysql_connect() (doesn't apply in safe mode). -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-host -mysql.default_host = - -; Default user for mysql_connect() (doesn't apply in safe mode). -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-user -mysql.default_user = - -; Default password for mysql_connect() (doesn't apply in safe mode). -; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysql.default_password") -; and reveal this password! And of course, any users with read access to this -; file will be able to reveal the password as well. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.default-password -mysql.default_password = - -; Maximum time (in seconds) for connect timeout. -1 means no limit -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.connect-timeout -mysql.connect_timeout = 60 - -; Trace mode. When trace_mode is active (=On), warnings for table/index scans and -; SQL-Errors will be displayed. -; http://www.php.net/manual/en/mysql.configuration.php#ini.mysql.trace-mode -mysql.trace_mode = Off - -[MySQLi] - -; Maximum number of links. -1 means no limit. -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.max-links -mysqli.max_links = -1 - -; Default port number for mysqli_connect(). If unset, mysqli_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the -; compile-time value defined MYSQL_PORT (in that order). Win32 will only look -; at MYSQL_PORT. -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-port -mysqli.default_port = 3306 - -; Default socket name for local MySQL connects. If empty, uses the built-in -; MySQL defaults. -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-socket -mysqli.default_socket = - -; Default host for mysql_connect() (doesn't apply in safe mode). -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-host -mysqli.default_host = - -; Default user for mysql_connect() (doesn't apply in safe mode). -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-user -mysqli.default_user = - -; Default password for mysqli_connect() (doesn't apply in safe mode). -; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw") -; and reveal this password! And of course, any users with read access to this -; file will be able to reveal the password as well. -; http://www.php.net/manual/en/mysqli.configuration.php#ini.mysqli.default-pw -mysqli.default_pw = - -; Allow or prevent reconnect -mysqli.reconnect = Off - -[PostgresSQL] -; Allow or prevent persistent links. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.allow-persistent -pgsql.allow_persistent = On - -; Detect broken persistent links always with pg_pconnect(). -; Auto reset feature requires a little overheads. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.auto-reset-persistent -pgsql.auto_reset_persistent = Off - -; Maximum number of persistent links. -1 means no limit. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.max-persistent -pgsql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.max-links -pgsql.max_links = -1 - -; Ignore PostgreSQL backends Notice message or not. -; Notice message logging require a little overheads. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.ignore-notice -pgsql.ignore_notice = 0 - -; Log PostgreSQL backends Noitce message or not. -; Unless pgsql.ignore_notice=0, module cannot log notice message. -; http://www.php.net/manual/en/pgsql.configuration.php#ini.pgsql.log-notice -pgsql.log_notice = 0 - -[Sybase-CT] -; Allow or prevent persistent links. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.allow-persistent -sybct.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.max-persistent -sybct.max_persistent = -1 - -; Maximum number of links (persistent + non-persistent). -1 means no limit. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.max-links -sybct.max_links = -1 - -; Minimum server message severity to display. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.min-server-severity -sybct.min_server_severity = 10 - -; Minimum client message severity to display. -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.min-client-severity -sybct.min_client_severity = 10 - -; Set per-context timeout -; http://www.php.net/manual/en/sybase.configuration.php#ini.sybct.timeout -;sybct.timeout= - -;sybct.packet_size - -[bcmath] -; Number of decimal digits for all bcmath functions. -; http://www.php.net/manual/en/bc.configuration.php#ini.bcmath.scale -bcmath.scale = 0 - -[browscap] -; http://www.php.net/manual/en/misc.configuration.php#ini.browscap -;browscap = extra/browscap.ini - -[Session] -; Handler used to store/retrieve data. -; http://www.php.net/manual/en/session.configuration.php#ini.session.save-handler -session.save_handler = files - -; Argument passed to save_handler. In the case of files, this is the path -; where data files are stored. Note: Windows users have to change this -; variable in order to use PHP's session functions. -; -; As of PHP 4.0.1, you can define the path as: -; -; session.save_path = "N;/path" -; -; where N is an integer. Instead of storing all the session files in -; /path, what this will do is use subdirectories N-levels deep, and -; store the session data in those directories. This is useful if you -; or your OS have problems with lots of files in one directory, and is -; a more efficient layout for servers that handle lots of sessions. -; -; NOTE 1: PHP will not create this directory structure automatically. -; You can use the script in the ext/session dir for that purpose. -; NOTE 2: See the section on garbage collection below if you choose to -; use subdirectories for session storage -; -; The file storage module creates files using mode 600 by default. -; You can change that by using -; -; session.save_path = "N;MODE;/path" -; -; where MODE is the octal representation of the mode. Note that this -; does not overwrite the process's umask. -; http://www.php.net/manual/en/session.configuration.php#ini.session.save-path -session.save_path = "/tmp" - -; Whether to use cookies. -; http://www.php.net/manual/en/session.configuration.php#ini.session.use-cookies -session.use_cookies = 1 - -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-secure -;session.cookie_secure = - -; This option forces PHP to fetch and use a cookie for storing and maintaining -; the session id. We encourage this operation as it's very helpful in combatting -; session hijacking when not specifying and managing your own session id. It is -; not the end all be all of session hijacking defense, but it's a good start. -; http://www.php.net/manual/en/session.configuration.php#ini.session.use-only-cookies -session.use_only_cookies = 1 - -; Name of the session (used as cookie name). -; http://www.php.net/manual/en/session.configuration.php#ini.session.name -session.name = PHPSESSID - -; Initialize session on request startup. -; http://www.php.net/manual/en/session.configuration.php#ini.session.auto-start -session.auto_start = 0 - -; Lifetime in seconds of cookie or, if 0, until browser is restarted. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime -session.cookie_lifetime = 0 - -; The path for which the cookie is valid. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-path -session.cookie_path = / - -; The domain for which the cookie is valid. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-domain -session.cookie_domain = - -; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-httponly -session.cookie_httponly = - -; Handler used to serialize data. php is the standard serializer of PHP. -; http://www.php.net/manual/en/session.configuration.php#ini.session.serialize-handler -session.serialize_handler = php - -; Defines the probability that the 'garbage collection' process is started -; on every session initialization. The probability is calculated by using -; gc_probability/gc_divisor. Where session.gc_probability is the numerator -; and gc_divisor is the denominator in the equation. Setting this value to 1 -; when the session.gc_divisor value is 100 will give you approximately a 1% chance -; the gc will run on any give request. -; Default Value: 1 -; Development Value: 1 -; Production Value: 1 -; http://www.php.net/manual/en/session.configuration.php#ini.session.gc-probability -session.gc_probability = 1 - -; Defines the probability that the 'garbage collection' process is started on every -; session initialization. The probability is calculated by using the following equation: -; gc_probability/gc_divisor. Where session.gc_probability is the numerator and -; session.gc_divisor is the denominator in the equation. Setting this value to 1 -; when the session.gc_divisor value is 100 will give you approximately a 1% chance -; the gc will run on any give request. Increasing this value to 1000 will give you -; a 0.1% chance the gc will run on any give request. For high volume production servers, -; this is a more efficient approach. -; Default Value: 100 -; Development Value: 1000 -; Production Value: 1000 -; http://www.php.net/manual/en/session.configuration.php#ini.session.gc-divisor -session.gc_divisor = 1000 - -; After this number of seconds, stored data will be seen as 'garbage' and -; cleaned up by the garbage collection process. -; http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime -session.gc_maxlifetime = 1440 - -; NOTE: If you are using the subdirectory option for storing session files -; (see session.save_path above), then garbage collection does *not* -; happen automatically. You will need to do your own garbage -; collection through a shell script, cron entry, or some other method. -; For example, the following script would is the equivalent of -; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): -; cd /path/to/sessions; find -cmin +24 | xargs rm - -; PHP 4.2 and less have an undocumented feature/bug that allows you to -; to initialize a session variable in the global scope, even when register_globals -; is disabled. PHP 4.3 and later will warn you, if this feature is used. -; You can disable the feature and the warning separately. At this time, -; the warning is only displayed, if bug_compat_42 is enabled. This feature -; introduces some serious security problems if not handled correctly. It's -; recommended that you do not use this feature on production servers. But you -; should enable this on development servers and enable the warning as well. If you -; do not enable the feature on development servers, you won't be warned when it's -; used and debugging errors caused by this can be difficult to track down. -; Default Value: On -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/session.configuration.php#ini.session.bug-compat-42 -session.bug_compat_42 = Off - -; This setting controls whether or not you are warned by PHP when initializing a -; session value into the global space. session.bug_compat_42 must be enabled before -; these warnings can be issued by PHP. See the directive above for more information. -; Default Value: On -; Development Value: On -; Production Value: Off -; http://www.php.net/manual/en/session.configuration.php#ini.session.bug-compat-warn -session.bug_compat_warn = Off - -; Check HTTP Referer to invalidate externally stored URLs containing ids. -; HTTP_REFERER has to contain this substring for the session to be -; considered as valid. -; http://www.php.net/manual/en/session.configuration.php#ini.session.referer-check -session.referer_check = - -; How many bytes to read from the file. -; http://www.php.net/manual/en/session.configuration.php#ini.session.entropy-length -session.entropy_length = 0 - -; Specified here to create the session id. -; http://www.php.net/manual/en/session.configuration.php#ini.session.entropy-file -;session.entropy_file = /dev/urandom -session.entropy_file = - -; http://www.php.net/manual/en/session.configuration.php#ini.session.entropy-length -;session.entropy_length = 16 - -; Set to {nocache,private,public,} to determine HTTP caching aspects -; or leave this empty to avoid sending anti-caching headers. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cache-limiter -session.cache_limiter = nocache - -; Document expires after n minutes. -; http://www.php.net/manual/en/session.configuration.php#ini.session.cache-expire -session.cache_expire = 180 - -; trans sid support is disabled by default. -; Use of trans sid may risk your users security. -; Use this option with caution. -; - User may send URL contains active session ID -; to other person via. email/irc/etc. -; - URL that contains active session ID may be stored -; in publically accessible computer. -; - User may access your site with the same session ID -; always using URL stored in browser's history or bookmarks. -; http://www.php.net/manual/en/session.configuration.php#ini.session.use-trans-sid -session.use_trans_sid = 0 - -; Select a hash function for use in generating session ids. -; Possible Values -; 0 (MD5 128 bits) -; 1 (SHA-1 160 bits) -; http://www.php.net/manual/en/session.configuration.php#ini.session.hash-function -session.hash_function = 0 - -; Define how many bits are stored in each character when converting -; the binary hash data to something readable. -; Possible values: -; 4 (4 bits: 0-9, a-f) -; 5 (5 bits: 0-9, a-v) -; 6 (6 bits: 0-9, a-z, A-Z, "-", ",") -; Default Value: 4 -; Development Value: 5 -; Production Value: 5 -; http://www.php.net/manual/en/session.configuration.php#ini.session.hash-bits-per-character -session.hash_bits_per_character = 5 - -; The URL rewriter will look for URLs in a defined set of HTML tags. -; form/fieldset are special; if you include them here, the rewriter will -; add a hidden field with the info which is otherwise appended -; to URLs. If you want XHTML conformity, remove the form entry. -; Note that all valid entries require a "=", even if no value follows. -; Default Value: "a=href,area=href,frame=src,form=,fieldset=" -; Development Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; Production Value: "a=href,area=href,frame=src,input=src,form=fakeentry" -; http://www.php.net/manual/en/session.configuration.php#ini.url-rewriter.tags -url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" - -[MSSQL] -; Allow or prevent persistent links. -mssql.allow_persistent = On - -; Maximum number of persistent links. -1 means no limit. -mssql.max_persistent = -1 - -; Maximum number of links (persistent+non persistent). -1 means no limit. -mssql.max_links = -1 - -; Minimum error severity to display. -mssql.min_error_severity = 10 - -; Minimum message severity to display. -mssql.min_message_severity = 10 - -; Compatibility mode with old versions of PHP 3.0. -mssql.compatability_mode = Off - -; Connect timeout -;mssql.connect_timeout = 5 - -; Query timeout -;mssql.timeout = 60 - -; Valid range 0 - 2147483647. Default = 4096. -;mssql.textlimit = 4096 - -; Valid range 0 - 2147483647. Default = 4096. -;mssql.textsize = 4096 - -; Limits the number of records in each batch. 0 = all records in one batch. -;mssql.batchsize = 0 - -; Specify how datetime and datetim4 columns are returned -; On => Returns data converted to SQL server settings -; Off => Returns values as YYYY-MM-DD hh:mm:ss -;mssql.datetimeconvert = On - -; Use NT authentication when connecting to the server -mssql.secure_connection = Off - -; Specify max number of processes. -1 = library default -; msdlib defaults to 25 -; FreeTDS defaults to 4096 -;mssql.max_procs = -1 - -; Specify client character set. -; If empty or not set the client charset from freetds.comf is used -; This is only used when compiled with FreeTDS -;mssql.charset = "ISO-8859-1" - -[Assertion] -; Assert(expr); active by default. -; http://www.php.net/manual/en/info.configuration.php#ini.assert.active -;assert.active = On - -; Issue a PHP warning for each failed assertion. -; http://www.php.net/manual/en/info.configuration.php#ini.assert.warning -;assert.warning = On - -; Don't bail out by default. -; http://www.php.net/manual/en/info.configuration.php#ini.assert.bail -;assert.bail = Off - -; User-function to be called if an assertion fails. -; http://www.php.net/manual/en/info.configuration.php#ini.assert.callback -;assert.callback = 0 - -; Eval the expression with current error_reporting(). Set to true if you want -; error_reporting(0) around the eval(). -; http://www.php.net/manual/en/info.configuration.php#ini.assert.quiet-eval -;assert.quiet_eval = 0 - -[COM] -; path to a file containing GUIDs, IIDs or filenames of files with TypeLibs -; http://www.php.net/manual/en/com.configuration.php#ini.com.typelib-file -;com.typelib_file = - -; allow Distributed-COM calls -; http://www.php.net/manual/en/com.configuration.php#ini.com.allow-dcom -;com.allow_dcom = true - -; autoregister constants of a components typlib on com_load() -; http://www.php.net/manual/en/com.configuration.php#ini.com.autoregister-typelib -;com.autoregister_typelib = true - -; register constants casesensitive -; http://www.php.net/manual/en/com.configuration.php#ini.com.autoregister-casesensitive -;com.autoregister_casesensitive = false - -; show warnings on duplicate constant registrations -; http://www.php.net/manual/en/com.configuration.php#ini.com.autoregister-verbose -;com.autoregister_verbose = true - -[mbstring] -; language for internal character representation. -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.language -;mbstring.language = Japanese - -; internal/script encoding. -; Some encoding cannot work as internal encoding. -; (e.g. SJIS, BIG5, ISO-2022-*) -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.internal-encoding -;mbstring.internal_encoding = EUC-JP - -; http input encoding. -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.http-input -;mbstring.http_input = auto - -; http output encoding. mb_output_handler must be -; registered as output buffer to function -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.http-output -;mbstring.http_output = SJIS - -; enable automatic encoding translation according to -; mbstring.internal_encoding setting. Input chars are -; converted to internal encoding by setting this to On. -; Note: Do _not_ use automatic encoding translation for -; portable libs/applications. -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.encoding-translation -;mbstring.encoding_translation = Off - -; automatic encoding detection order. -; auto means -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.detect-order -;mbstring.detect_order = auto - -; substitute_character used when character cannot be converted -; one from another -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.substitute-character -;mbstring.substitute_character = none; - -; overload(replace) single byte functions by mbstring functions. -; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(), -; etc. Possible values are 0,1,2,4 or combination of them. -; For example, 7 for overload everything. -; 0: No overload -; 1: Overload mail() function -; 2: Overload str*() functions -; 4: Overload ereg*() functions -; http://www.php.net/manual/en/mbstring.configuration.php#ini.mbstring.func-overload -;mbstring.func_overload = 0 - -; enable strict encoding detection. -;mbstring.strict_detection = Off - -; This directive specifies the regex pattern of content types for which mb_output_handler() -; is activated. -; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml) -;mbstring.http_output_conv_mimetype= - -[gd] -; Tell the jpeg decode to ignore warnings and try to create -; a gd image. The warning will then be displayed as notices -; disabled by default -; http://www.php.net/manual/en/image.configuration.php#ini.image.jpeg-ignore-warning -;gd.jpeg_ignore_warning = 0 - -[exif] -; Exif UNICODE user comments are handled as UCS-2BE/UCS-2LE and JIS as JIS. -; With mbstring support this will automatically be converted into the encoding -; given by corresponding encode setting. When empty mbstring.internal_encoding -; is used. For the decode settings you can distinguish between motorola and -; intel byte order. A decode setting cannot be empty. -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.encode-unicode -;exif.encode_unicode = ISO-8859-15 - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.decode-unicode-motorola -;exif.decode_unicode_motorola = UCS-2BE - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.decode-unicode-intel -;exif.decode_unicode_intel = UCS-2LE - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.encode-jis -;exif.encode_jis = - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.decode-jis-motorola -;exif.decode_jis_motorola = JIS - -; http://www.php.net/manual/en/exif.configuration.php#ini.exif.decode-jis-intel -;exif.decode_jis_intel = JIS - -[Tidy] -; The path to a default tidy configuration file to use when using tidy -; http://www.php.net/manual/en/tidy.configuration.php#ini.tidy.default-config -;tidy.default_config = /usr/local/lib/php/default.tcfg - -; Should tidy clean and repair output automatically? -; WARNING: Do not use this option if you are generating non-html content -; such as dynamic images -; http://www.php.net/manual/en/tidy.configuration.php#ini.tidy.clean-output -tidy.clean_output = Off - -[soap] -; Enables or disables WSDL caching feature. -; http://www.php.net/manual/en/soap.configuration.php#ini.soap.wsdl-cache-enabled -soap.wsdl_cache_enabled=1 - -; Sets the directory name where SOAP extension will put cache files. -; http://www.php.net/manual/en/soap.configuration.php#ini.soap.wsdl-cache-dir -soap.wsdl_cache_dir="/tmp" - -; (time to live) Sets the number of second while cached file will be used -; instead of original one. -; http://www.php.net/manual/en/soap.configuration.php#ini.soap.wsdl-cache-ttl -soap.wsdl_cache_ttl=86400 - -[sysvshm] -; A default size of the shared memory segment -;sysvshm.init_mem = 10000 - - -; Local Variables: -; tab-width: 4 -; End: - --- a/aws/postgresql.conf +++ /dev/null @@ -1,502 +1,1 @@ -# ----------------------------- -# PostgreSQL configuration file -# ----------------------------- -# -# This file consists of lines of the form: -# -# name = value -# -# (The "=" is optional.) Whitespace may be used. Comments are introduced with -# "#" anywhere on a line. The complete list of parameter names and allowed -# values can be found in the PostgreSQL documentation. -# -# The commented-out settings shown in this file represent the default values. -# Re-commenting a setting is NOT sufficient to revert it to the default value; -# you need to reload the server. -# -# This file is read on server startup and when the server receives a SIGHUP -# signal. If you edit the file on a running system, you have to SIGHUP the -# server for the changes to take effect, or use "pg_ctl reload". Some -# parameters, which are marked below, require a server shutdown and restart to -# take effect. -# -# Any parameter can also be given as a command-line option to the server, e.g., -# "postgres -c log_connections=on". Some parameters can be changed at run time -# with the "SET" SQL command. -# -# Memory units: kB = kilobytes Time units: ms = milliseconds -# MB = megabytes s = seconds -# GB = gigabytes min = minutes -# h = hours -# d = days - -#------------------------------------------------------------------------------ -# FILE LOCATIONS -#------------------------------------------------------------------------------ - -# The default values of these variables are driven from the -D command-line -# option or PGDATA environment variable, represented here as ConfigDir. - -#data_directory = 'ConfigDir' # use data in another directory - # (change requires restart) -#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file - # (change requires restart) -#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file - # (change requires restart) - -# If external_pid_file is not explicitly set, no extra PID file is written. -#external_pid_file = '(none)' # write an extra PID file - # (change requires restart) - - -#------------------------------------------------------------------------------ -# CONNECTIONS AND AUTHENTICATION -#------------------------------------------------------------------------------ - -# - Connection Settings - - -listen_addresses = '*' # what IP address(es) to listen on; - # comma-separated list of addresses; - # defaults to 'localhost', '*' = all - # (change requires restart) -#port = 5432 # (change requires restart) -max_connections = 100 # (change requires restart) -# Note: Increasing max_connections costs ~400 bytes of shared memory per -# connection slot, plus lock space (see max_locks_per_transaction). -#superuser_reserved_connections = 3 # (change requires restart) -#unix_socket_directory = '' # (change requires restart) -#unix_socket_group = '' # (change requires restart) -#unix_socket_permissions = 0777 # begin with 0 to use octal notation - # (change requires restart) -#bonjour_name = '' # defaults to the computer name - # (change requires restart) - -# - Security and Authentication - - -#authentication_timeout = 1min # 1s-600s -#ssl = off # (change requires restart) -#ssl_ciphers = 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH' # allowed SSL ciphers - # (change requires restart) -#ssl_renegotiation_limit = 512MB # amount of data between renegotiations -#password_encryption = on -#db_user_namespace = off - -# Kerberos and GSSAPI -#krb_server_keyfile = '' -#krb_srvname = 'postgres' # (Kerberos only) -#krb_caseins_users = off - -# - TCP Keepalives - -# see "man 7 tcp" for details - -#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; - # 0 selects the system default -#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; - # 0 selects the system default -#tcp_keepalives_count = 0 # TCP_KEEPCNT; - # 0 selects the system default - - -#------------------------------------------------------------------------------ -# RESOURCE USAGE (except WAL) -#------------------------------------------------------------------------------ - -# - Memory - - -shared_buffers = 32MB # min 128kB - # (change requires restart) -#temp_buffers = 8MB # min 800kB -#max_prepared_transactions = 0 # zero disables the feature - # (change requires restart) -# Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory -# per transaction slot, plus lock space (see max_locks_per_transaction). -# It is not advisable to set max_prepared_transactions nonzero unless you -# actively intend to use prepared transactions. -#work_mem = 1MB # min 64kB -#maintenance_work_mem = 16MB # min 1MB -#max_stack_depth = 2MB # min 100kB - -# - Kernel Resource Usage - - -#max_files_per_process = 1000 # min 25 - # (change requires restart) -#shared_preload_libraries = '' # (change requires restart) - -# - Cost-Based Vacuum Delay - - -#vacuum_cost_delay = 0ms # 0-100 milliseconds -#vacuum_cost_page_hit = 1 # 0-10000 credits -#vacuum_cost_page_miss = 10 # 0-10000 credits -#vacuum_cost_page_dirty = 20 # 0-10000 credits -#vacuum_cost_limit = 200 # 1-10000 credits - -# - Background Writer - - -#bgwriter_delay = 200ms # 10-10000ms between rounds -#bgwriter_lru_maxpages = 100 # 0-1000 max buffers written/round -#bgwriter_lru_multiplier = 2.0 # 0-10.0 multipler on buffers scanned/round - -# - Asynchronous Behavior - - -#effective_io_concurrency = 1 # 1-1000. 0 disables prefetching - - -#------------------------------------------------------------------------------ -# WRITE AHEAD LOG -#------------------------------------------------------------------------------ - -# - Settings - - -#fsync = on # turns forced synchronization on or off -#synchronous_commit = on # immediate fsync at commit -#wal_sync_method = fsync # the default is the first option - # supported by the operating system: - # open_datasync - # fdatasync - # fsync - # fsync_writethrough - # open_sync -#full_page_writes = on # recover from partial page writes -#wal_buffers = 64kB # min 32kB - # (change requires restart) -#wal_writer_delay = 200ms # 1-10000 milliseconds - -#commit_delay = 0 # range 0-100000, in microseconds -#commit_siblings = 5 # range 1-1000 - -# - Checkpoints - - -#checkpoint_segments = 3 # in logfile segments, min 1, 16MB each -#checkpoint_timeout = 5min # range 30s-1h -#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 -#checkpoint_warning = 30s # 0 disables - -# - Archiving - - -#archive_mode = off # allows archiving to be done - # (change requires restart) -#archive_command = '' # command to use to archive a logfile segment -#archive_timeout = 0 # force a logfile segment switch after this - # number of seconds; 0 disables - - -#------------------------------------------------------------------------------ -# QUERY TUNING -#------------------------------------------------------------------------------ - -# - Planner Method Configuration - - -#enable_bitmapscan = on -#enable_hashagg = on -#enable_hashjoin = on -#enable_indexscan = on -#enable_mergejoin = on -#enable_nestloop = on -#enable_seqscan = on -#enable_sort = on -#enable_tidscan = on - -# - Planner Cost Constants - - -#seq_page_cost = 1.0 # measured on an arbitrary scale -#random_page_cost = 4.0 # same scale as above -#cpu_tuple_cost = 0.01 # same scale as above -#cpu_index_tuple_cost = 0.005 # same scale as above -#cpu_operator_cost = 0.0025 # same scale as above -#effective_cache_size = 128MB - -# - Genetic Query Optimizer - - -#geqo = on -#geqo_threshold = 12 -#geqo_effort = 5 # range 1-10 -#geqo_pool_size = 0 # selects default based on effort -#geqo_generations = 0 # selects default based on effort -#geqo_selection_bias = 2.0 # range 1.5-2.0 - -# - Other Planner Options - - -#default_statistics_target = 100 # range 1-10000 -#constraint_exclusion = partition # on, off, or partition -#cursor_tuple_fraction = 0.1 # range 0.0-1.0 -#from_collapse_limit = 8 -#join_collapse_limit = 8 # 1 disables collapsing of explicit - # JOIN clauses - - -#------------------------------------------------------------------------------ -# ERROR REPORTING AND LOGGING -#------------------------------------------------------------------------------ - -# - Where to Log - - -#log_destination = 'stderr' # Valid values are combinations of - # stderr, csvlog, syslog and eventlog, - # depending on platform. csvlog - # requires logging_collector to be on. - -# This is used when logging to stderr: -logging_collector = on # Enable capturing of stderr and csvlog - # into log files. Required to be on for - # csvlogs. - # (change requires restart) - -# These are only used if logging_collector is on: -log_directory = 'pg_log' # directory where log files are written, - # can be absolute or relative to PGDATA -log_filename = 'postgresql-%a.log' # log file name pattern, - # can include strftime() escapes -log_truncate_on_rotation = on # If on, an existing log file of the - # same name as the new log file will be - # truncated rather than appended to. - # But such truncation only occurs on - # time-driven rotation, not on restarts - # or size-driven rotation. Default is - # off, meaning append to existing files - # in all cases. -log_rotation_age = 1d # Automatic rotation of logfiles will - # happen after that time. 0 disables. -log_rotation_size = 0 # Automatic rotation of logfiles will - # happen after that much log output. - # 0 disables. - -# These are relevant when logging to syslog: -#syslog_facility = 'LOCAL0' -#syslog_ident = 'postgres' - -#silent_mode = off # Run server silently. - # DO NOT USE without syslog or - # logging_collector - # (change requires restart) - - -# - When to Log - - -#client_min_messages = notice # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # log - # notice - # warning - # error - -#log_min_messages = warning # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic - -#log_error_verbosity = default # terse, default, or verbose messages - -#log_min_error_statement = error # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic (effectively off) - -#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements - # and their durations, > 0 logs only - # statements running at least this number - # of milliseconds - - -# - What to Log - - -#debug_print_parse = off -#debug_print_rewritten = off -#debug_print_plan = off -#debug_pretty_print = on -#log_checkpoints = off -#log_connections = off -#log_disconnections = off -#log_duration = off -#log_hostname = off -#log_line_prefix = '' # special values: - # %u = user name - # %d = database name - # %r = remote host and port - # %h = remote host - # %p = process ID - # %t = timestamp without milliseconds - # %m = timestamp with milliseconds - # %i = command tag - # %c = session ID - # %l = session line number - # %s = session start timestamp - # %v = virtual transaction ID - # %x = transaction ID (0 if none) - # %q = stop here in non-session - # processes - # %% = '%' - # e.g. '<%u%%%d> ' -#log_lock_waits = off # log lock waits >= deadlock_timeout -#log_statement = 'none' # none, ddl, mod, all -#log_temp_files = -1 # log temporary files equal or larger - # than the specified size in kilobytes; - # -1 disables, 0 logs all temp files -#log_timezone = unknown # actually, defaults to TZ environment - # setting - - -#------------------------------------------------------------------------------ -# RUNTIME STATISTICS -#------------------------------------------------------------------------------ - -# - Query/Index Statistics Collector - - -#track_activities = on -#track_counts = on -#track_functions = none # none, pl, all -#track_activity_query_size = 1024 -#update_process_title = on -#stats_temp_directory = 'pg_stat_tmp' - - -# - Statistics Monitoring - - -#log_parser_stats = off -#log_planner_stats = off -#log_executor_stats = off -#log_statement_stats = off - - -#------------------------------------------------------------------------------ -# AUTOVACUUM PARAMETERS -#------------------------------------------------------------------------------ - -#autovacuum = on # Enable autovacuum subprocess? 'on' - # requires track_counts to also be on. -#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and - # their durations, > 0 logs only - # actions running at least this number - # of milliseconds. -#autovacuum_max_workers = 3 # max number of autovacuum subprocesses -#autovacuum_naptime = 1min # time between autovacuum runs -#autovacuum_vacuum_threshold = 50 # min number of row updates before - # vacuum -#autovacuum_analyze_threshold = 50 # min number of row updates before - # analyze -#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum -#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze -#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum - # (change requires restart) -#autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for - # autovacuum, in milliseconds; - # -1 means use vacuum_cost_delay -#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for - # autovacuum, -1 means use - # vacuum_cost_limit - - -#------------------------------------------------------------------------------ -# CLIENT CONNECTION DEFAULTS -#------------------------------------------------------------------------------ - -# - Statement Behavior - - -#search_path = '"$user",public' # schema names -#default_tablespace = '' # a tablespace name, '' uses the default -#temp_tablespaces = '' # a list of tablespace names, '' uses - # only default tablespace -#check_function_bodies = on -#default_transaction_isolation = 'read committed' -#default_transaction_read_only = off -#session_replication_role = 'origin' -#statement_timeout = 0 # in milliseconds, 0 is disabled -#vacuum_freeze_min_age = 50000000 -#vacuum_freeze_table_age = 150000000 -#xmlbinary = 'base64' -#xmloption = 'content' - -# - Locale and Formatting - - -datestyle = 'iso, mdy' -#intervalstyle = 'postgres' -#timezone = unknown # actually, defaults to TZ environment - # setting -#timezone_abbreviations = 'Default' # Select the set of available time zone - # abbreviations. Currently, there are - # Default - # Australia - # India - # You can create your own file in - # share/timezonesets/. -#extra_float_digits = 0 # min -15, max 2 -#client_encoding = sql_ascii # actually, defaults to database - # encoding - -# These settings are initialized by initdb, but they can be changed. -lc_messages = 'en_US.UTF-8' # locale for system error message - # strings -lc_monetary = 'en_US.UTF-8' # locale for monetary formatting -lc_numeric = 'en_US.UTF-8' # locale for number formatting -lc_time = 'en_US.UTF-8' # locale for time formatting - -# default configuration for text search -default_text_search_config = 'pg_catalog.english' - -# - Other Defaults - - -#dynamic_library_path = '$libdir' -#local_preload_libraries = '' - - -#------------------------------------------------------------------------------ -# LOCK MANAGEMENT -#------------------------------------------------------------------------------ - -#deadlock_timeout = 1s -#max_locks_per_transaction = 64 # min 10 - # (change requires restart) -# Note: Each lock table slot uses ~270 bytes of shared memory, and there are -# max_locks_per_transaction * (max_connections + max_prepared_transactions) -# lock table slots. - - -#------------------------------------------------------------------------------ -# VERSION/PLATFORM COMPATIBILITY -#------------------------------------------------------------------------------ - -# - Previous PostgreSQL Versions - - -#add_missing_from = off -#array_nulls = on -#backslash_quote = safe_encoding # on, off, or safe_encoding -#default_with_oids = off -#escape_string_warning = on -#regex_flavor = advanced # advanced, extended, or basic -#sql_inheritance = on -#standard_conforming_strings = off -#synchronize_seqscans = on - -# - Other Platforms and Clients - - -#transform_null_equals = off - - -#------------------------------------------------------------------------------ -# CUSTOMIZED OPTIONS -#------------------------------------------------------------------------------ - -#custom_variable_classes = '' # list of custom variable class names - --- a/aws/rc.local +++ /dev/null @@ -1,14 +1,1 @@ -#!/bin/sh -# -# This script will be executed *after* all the other init scripts. -# You can put your own initialization stuff in here if you don't -# want to do the full Sys V style init stuff. -touch /var/lock/subsys/local -cd /tmp -rm -rfv busui -git clone http://maxious.lambdacomplex.org/busui/git -sh busui/aws/awsStartup.sh - - - --- /dev/null +++ b/css/jquery-ui-1.8.12.custom.css @@ -1,1 +1,348 @@ - +/* + * jQuery UI CSS Framework 1.8.12 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.12 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } +.ui-widget-content a { color: #333333; } +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* + * jQuery UI Autocomplete 1.8.12 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.12 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} + --- a/css/jquery.mobile-1.0a4.css +++ /dev/null @@ -1,1661 +1,1 @@ -/*! - * jQuery Mobile v1.0a4 - * http://jquerymobile.com/ - * - * Copyright 2010, jQuery Project - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -* Note: Code is in draft form and is subject to change -*/ - -/* A ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-a { - border: 1px solid #2A2A2A; - background: #111111; - color: #ffffff; - font-weight: bold; - text-shadow: 0 -1px 1px #000000; - background-image: -moz-linear-gradient(top, - #3c3c3c, - #111111); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #3c3c3c), - color-stop(1, #111111)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#3c3c3c', EndColorStr='#111111')"; -} -.ui-bar-a, -.ui-bar-a input, -.ui-bar-a select, -.ui-bar-a textarea, -.ui-bar-a button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-bar-a .ui-link-inherit { - color: #fff; -} -.ui-bar-a .ui-link { - color: #7cc4e7; - font-weight: bold; -} -.ui-body-a { - border: 1px solid #2A2A2A; - background: #222222; - color: #fff; - text-shadow: 0 1px 0 #000; - font-weight: normal; - background-image: -moz-linear-gradient(top, - #666666, - #222222); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #666666), - color-stop(1, #222222)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#666666', EndColorStr='#222222)')"; -} -.ui-body-a, -.ui-body-a input, -.ui-body-a select, -.ui-body-a textarea, -.ui-body-a button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-a .ui-link-inherit { - color: #fff; -} -.ui-body-a .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-br { - border-bottom: rgb(130,130,130); - border-bottom: rgba(130,130,130,.3); - border-bottom-width: 1px; - border-bottom-style: solid; -} -.ui-btn-up-a { - border: 1px solid #222; - background: #333333; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #000; - background-image: -moz-linear-gradient(top, - #555555, - #333333); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #555555), - color-stop(1, #333333)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#555555', EndColorStr='#333333')"; -} -.ui-btn-up-a a.ui-link-inherit { - color: #fff; -} -.ui-btn-hover-a { - border: 1px solid #000; - background: #444444; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #000; - background-image: -moz-linear-gradient(top, - #666666, - #444444); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #666666), - color-stop(1, #444444)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#666666', EndColorStr='#444444')"; -} -.ui-btn-hover-a a.ui-link-inherit { - color: #fff; -} -.ui-btn-down-a { - border: 1px solid #000; - background: #3d3d3d; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #000; - background-image: -moz-linear-gradient(top, - #333333, - #5a5a5a); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #333333), - color-stop(1, #5a5a5a)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#333333', EndColorStr='#5a5a5a')"; -} -.ui-btn-down-a a.ui-link-inherit { - color: #fff; -} -.ui-btn-up-a, -.ui-btn-hover-a, -.ui-btn-down-a { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* B ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-b { - border: 1px solid #456f9a; - background: #5e87b0; - color: #fff; - font-weight: bold; - text-shadow: 0 -1px 1px #254f7a; - background-image: -moz-linear-gradient(top, - #81a8ce, - #5e87b0); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #81a8ce), - color-stop(1, #5e87b0)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#81a8ce', EndColorStr='#5e87b0')"; -} -.ui-bar-b, -.ui-bar-b input, -.ui-bar-b select, -.ui-bar-b textarea, -.ui-bar-b button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-bar-b .ui-link-inherit { - color: #fff; -} -.ui-bar-b .ui-link { - color: #7cc4e7; - font-weight: bold; -} - -.ui-body-b { - border: 1px solid #C6C6C6; - background: #cccccc; - color: #333333; - text-shadow: 0 1px 0 #fff; - font-weight: normal; - background-image: -moz-linear-gradient(top, - #e6e6e6, - #cccccc); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #e6e6e6), - color-stop(1, #cccccc)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#e6e6e6', EndColorStr='#cccccc')"; -} -.ui-body-b, -.ui-body-b input, -.ui-body-b select, -.ui-body-b textarea, -.ui-body-b button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-b .ui-link-inherit { - color: #333333; -} -.ui-body-b .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-btn-up-b { - border: 1px solid #145072; - background: #2567ab; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #145072; - background-image: -moz-linear-gradient(top, - #4e89c5, - #2567ab); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #5f9cc5), - color-stop(1, #396b9e)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#4e89c5', EndColorStr='#2567ab')"; -} -.ui-btn-up-b a.ui-link-inherit { - color: #fff; -} -.ui-btn-hover-b { - border: 1px solid #00516e; - background: #4b88b6; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #014D68; - background-image: -moz-linear-gradient(top, - #72b0d4, - #4b88b6); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #72b0d4), - color-stop(1, #4b88b6)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#72b0d4', EndColorStr='#4b88b6')"; -} -.ui-btn-hover-b a.ui-link-inherit { - color: #fff; -} -.ui-btn-down-b { - border: 1px solid #225377; - background: #4e89c5; - font-weight: bold; - color: #fff; - text-shadow: 0 -1px 1px #225377; - background-image: -moz-linear-gradient(top, - #396b9e, - #4e89c5); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #396b9e), - color-stop(1, #4e89c5)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#396b9e', EndColorStr='#4e89c5')"; -} -.ui-btn-down-b a.ui-link-inherit { - color: #fff; -} -.ui-btn-up-b, -.ui-btn-hover-b, -.ui-btn-down-b { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* C ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-c { - border: 1px solid #B3B3B3; - background: #e9eaeb; - color: #3E3E3E; - font-weight: bold; - text-shadow: 0 1px 1px #fff; - background-image: -moz-linear-gradient(top, - #f0f0f0, - #e9eaeb); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #f0f0f0), - color-stop(1, #e9eaeb)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#f0f0f0', EndColorStr='#e9eaeb')"; -} -.ui-bar-c, -.ui-bar-c input, -.ui-bar-c select, -.ui-bar-c textarea, -.ui-bar-c button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-c { - border: 1px solid #B3B3B3; - color: #333333; - text-shadow: 0 1px 0 #fff; - background: #f0f0f0; - background-image: -moz-linear-gradient(top, - #eeeeee, - #dddddd); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #eeeeee), - color-stop(1, #dddddd)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#dddddd')"; -} -.ui-body-c, -.ui-body-c input, -.ui-body-c select, -.ui-body-c textarea, -.ui-body-c button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-c .ui-link-inherit { - color: #333333; -} -.ui-body-c .ui-link { - color: #2489CE; - font-weight: bold; -} - -.ui-btn-up-c { - border: 1px solid #ccc; - background: #eee; - font-weight: bold; - color: #444; - text-shadow: 0 1px 1px #f6f6f6; - background-image: -moz-linear-gradient(top, - #fefefe, - #eeeeee); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fdfdfd), - color-stop(1, #eeeeee)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fdfdfd', EndColorStr='#eeeeee')"; -} -.ui-btn-up-c a.ui-link-inherit { - color: #2F3E46; -} - -.ui-btn-hover-c { - border: 1px solid #bbb; - background: #dadada; - font-weight: bold; - color: #101010; - text-shadow: 0 1px 1px #fff; - background-image: -moz-linear-gradient(top, - #ededed, - #dadada); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #ededed), - color-stop(1, #dadada)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ededed', EndColorStr='#dadada')"; -} -.ui-btn-hover-c a.ui-link-inherit { - color: #2F3E46; -} -.ui-btn-down-c { - border: 1px solid #808080; - background: #fdfdfd; - font-weight: bold; - color: #111111; - text-shadow: 0 1px 1px #ffffff; - background-image: -moz-linear-gradient(top, - #eeeeee, - #fdfdfd); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #eeeeee), - color-stop(1, #fdfdfd)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#fdfdfd')"; -} -.ui-btn-down-c a.ui-link-inherit { - color: #2F3E46; -} -.ui-btn-up-c, -.ui-btn-hover-c, -.ui-btn-down-c { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* D ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-d { - border: 1px solid #ccc; - background: #bbb; - color: #333; - text-shadow: 0 1px 0 #eee; - background-image: -moz-linear-gradient(top, - #ddd, - #bbb); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #ddd), - color-stop(1, #bbb)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#dddddd', EndColorStr='#bbbbbb')"; -} -.ui-bar-d, -.ui-bar-d input, -.ui-bar-d select, -.ui-bar-d textarea, -.ui-bar-d button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-bar-d .ui-link-inherit { - color: #333; -} -.ui-bar-d .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-body-d { - border: 1px solid #ccc; - color: #333333; - text-shadow: 0 1px 0 #fff; - background: #ffffff; -} -.ui-body-d, -.ui-body-d input, -.ui-body-d select, -.ui-body-d textarea, -.ui-body-d button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-d .ui-link-inherit { - color: #333333; -} -.ui-body-d .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-btn-up-d { - border: 1px solid #ccc; - background: #fff; - font-weight: bold; - color: #444; - text-shadow: 0 1px 1px #fff; -} -.ui-btn-up-d a.ui-link-inherit { - color: #333; -} -.ui-btn-hover-d { - border: 1px solid #aaa; - background: #eeeeee; - font-weight: bold; - color: #222; - cursor: pointer; - text-shadow: 0 1px 1px #fff; - background-image: -moz-linear-gradient(top, - #fdfdfd, - #eeeeee); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fdfdfd), - color-stop(1, #eeeeee)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fdfdfd', EndColorStr='#eeeeee')"; -} -.ui-btn-hover-d a.ui-link-inherit { - color: #222; -} -.ui-btn-down-d { - border: 1px solid #aaaaaa; - background: #ffffff; - font-weight: bold; - color: #111; - text-shadow: 0 1px 1px #ffffff; - background-image: -moz-linear-gradient(top, - #eeeeee, - #ffffff); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #eeeeee), - color-stop(1, #ffffff)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#ffffff')"; -} -.ui-btn-down-d a.ui-link-inherit { - border: 1px solid #808080; - background: #ced0d2; - font-weight: bold; - color: #111; - text-shadow: none; - background-image: -moz-linear-gradient(top, - #cccccc, - #eeeeee); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #cccccc), - color-stop(1, #eeeeee)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#cccccc', EndColorStr='#eeeeee')"; -} -.ui-btn-up-d, -.ui-btn-hover-d, -.ui-btn-down-d { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* E ------------------------------------------------------------------------------------------------------------*/ - -.ui-bar-e { - border: 1px solid #F7C942; - background: #fadb4e; - color: #333; - text-shadow: 0 1px 0 #fff; - background-image: -moz-linear-gradient(top, - #fceda7, - #fadb4e); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fceda7), - color-stop(1, #fadb4e)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fceda7', EndColorStr='#fadb4e')"; -} -.ui-bar-e, -.ui-bar-e input, -.ui-bar-e select, -.ui-bar-e textarea, -.ui-bar-d button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-bar-e .ui-link-inherit { - color: #333; -} -.ui-bar-e .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-body-e { - border: 1px solid #F7C942; - color: #333333; - text-shadow: 0 1px 0 #fff; - background: #faeb9e; - background-image: -moz-linear-gradient(top, - #fff, - #faeb9e); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fff), - color-stop(1, #faeb9e)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#faeb9e')"; -} -.ui-body-e, -.ui-body-e input, -.ui-body-e select, -.ui-body-e textarea, -.ui-body-e button { - font-family: Helvetica, Arial, sans-serif; -} -.ui-body-e .ui-link-inherit { - color: #333333; -} -.ui-body-e .ui-link { - color: #2489CE; - font-weight: bold; -} -.ui-btn-up-e { - border: 1px solid #F7C942; - background: #fadb4e; - font-weight: bold; - color: #333; - text-shadow: 0 1px 1px #fe3; - text-shadow: 0 1px 0 #fff; - background-image: -moz-linear-gradient(top, - #fceda7, - #fadb4e); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fceda7), - color-stop(1, #fadb4e)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fceda7', EndColorStr='#fadb4e')"; -} -.ui-btn-up-e a.ui-link-inherit { - color: #333; -} -.ui-btn-hover-e { - border: 1px solid #e79952; - background: #fbe26f; - font-weight: bold; - color: #111; - text-shadow: 0 1px 1px #fff; - background-image: -moz-linear-gradient(top, - #fcf0b5, - #fbe26f); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fcf0b5), - color-stop(1, #fbe26f)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fcf0b5', EndColorStr='#fbe26f')"; -} - -.ui-btn-hover-e a.ui-link-inherit { - color: #333; -} -.ui-btn-down-e { - border: 1px solid #F7C942; - background: #fceda7; - font-weight: bold; - color: #111; - text-shadow: 0 1px 1px #ffffff; - background-image: -moz-linear-gradient(top, - #fadb4e, - #fceda7); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #fadb4e), - color-stop(1, #fceda7)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fadb4e', EndColorStr='#fceda7')"; -} -.ui-btn-down-e a.ui-link-inherit { - color: #333; -} -.ui-btn-up-e, -.ui-btn-hover-e, -.ui-btn-down-e { - font-family: Helvetica, Arial, sans-serif; - text-decoration: none; -} - - -/* links within "buttons" ------------------------------------------------------------------------------------------------------------*/ - -a.ui-link-inherit { - text-decoration: none !important; -} - - -/* Active class used as the "on" state across all themes ------------------------------------------------------------------------------------------------------------*/ - -.ui-btn-active { - border: 1px solid #155678; - background: #4596ce; - font-weight: bold; - color: #fff; - cursor: pointer; - text-shadow: 0 -1px 1px #145072; - text-decoration: none; - background-image: -moz-linear-gradient(top, - #85bae4, - #5393c5); - background-image: -webkit-gradient(linear,left top,left bottom, - color-stop(0, #85bae4), - color-stop(1, #5393c5)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#85bae4', EndColorStr='#5393c5')"; - outline: none; -} -.ui-btn-active a.ui-link-inherit { - color: #fff; -} - - -/* button inner top highlight ------------------------------------------------------------------------------------------------------------*/ - -.ui-btn-inner { - border-top: 1px solid #fff; - border-color: rgba(255,255,255,.3); -} - - -/* corner rounding classes ------------------------------------------------------------------------------------------------------------*/ - -.ui-corner-tl { - -moz-border-radius-topleft: .6em; - -webkit-border-top-left-radius: .6em; - border-top-left-radius: .6em; -} -.ui-corner-tr { - -moz-border-radius-topright: .6em; - -webkit-border-top-right-radius: .6em; - border-top-right-radius: .6em; -} -.ui-corner-bl { - -moz-border-radius-bottomleft: .6em; - -webkit-border-bottom-left-radius: .6em; - border-bottom-left-radius: .6em; -} -.ui-corner-br { - -moz-border-radius-bottomright: .6em; - -webkit-border-bottom-right-radius: .6em; - border-bottom-right-radius: .6em; -} -.ui-corner-top { - -moz-border-radius-topleft: .6em; - -webkit-border-top-left-radius: .6em; - border-top-left-radius: .6em; - -moz-border-radius-topright: .6em; - -webkit-border-top-right-radius: .6em; - border-top-right-radius: .6em; -} -.ui-corner-bottom { - -moz-border-radius-bottomleft: .6em; - -webkit-border-bottom-left-radius: .6em; - border-bottom-left-radius: .6em; - -moz-border-radius-bottomright: .6em; - -webkit-border-bottom-right-radius: .6em; - border-bottom-right-radius: .6em; - } -.ui-corner-right { - -moz-border-radius-topright: .6em; - -webkit-border-top-right-radius: .6em; - border-top-right-radius: .6em; - -moz-border-radius-bottomright: .6em; - -webkit-border-bottom-right-radius: .6em; - border-bottom-right-radius: .6em; -} -.ui-corner-left { - -moz-border-radius-topleft: .6em; - -webkit-border-top-left-radius: .6em; - border-top-left-radius: .6em; - -moz-border-radius-bottomleft: .6em; - -webkit-border-bottom-left-radius: .6em; - border-bottom-left-radius: .6em; -} -.ui-corner-all { - -moz-border-radius: .6em; - -webkit-border-radius: .6em; - border-radius: .6em; -} - - - -/* Interaction cues ------------------------------------------------------------------------------------------------------------*/ -.ui-disabled { - opacity: .3; -} -.ui-disabled, -.ui-disabled a { - cursor: default !important; -} - -/* Icons ------------------------------------------------------------------------------------------------------------*/ - -.ui-icon { - background: #666; - background: rgba(0,0,0,.4); - background-image: url(images/icons-18-white.png); - background-repeat: no-repeat; - -moz-border-radius: 9px; - -webkit-border-radius: 9px; - border-radius: 9px; -} - - -/* Alt icon color ------------------------------------------------------------------------------------------------------------*/ - -.ui-icon-alt { - background: #fff; - background: rgba(255,255,255,.3); - background-image: url(images/icons-18-black.png); - background-repeat: no-repeat; -} - -/* HD/"retina" sprite ------------------------------------------------------------------------------------------------------------*/ - -@media only screen and (-webkit-min-device-pixel-ratio: 1.5), - only screen and (min--moz-device-pixel-ratio: 1.5), - only screen and (min-resolution: 240dpi) { - - .ui-icon-plus, .ui-icon-minus, .ui-icon-delete, .ui-icon-arrow-r, - .ui-icon-arrow-l, .ui-icon-arrow-u, .ui-icon-arrow-d, .ui-icon-check, - .ui-icon-gear, .ui-icon-refresh, .ui-icon-forward, .ui-icon-back, - .ui-icon-grid, .ui-icon-star, .ui-icon-alert, .ui-icon-info, .ui-icon-home, .ui-icon-search, - .ui-icon-checkbox-off, .ui-icon-checkbox-on, .ui-icon-radio-off, .ui-icon-radio-on { - background-image: url(images/icons-36-white.png); - -moz-background-size: 776px 18px; - -o-background-size: 776px 18px; - -webkit-background-size: 776px 18px; - background-size: 776px 18px; - } - .ui-icon-alt { - background-image: url(images/icons-36-black.png); - } -} - -/* plus minus */ -.ui-icon-plus { - background-position: -0 50%; -} -.ui-icon-minus { - background-position: -36px 50%; -} - -/* delete/close */ -.ui-icon-delete { - background-position: -72px 50%; -} - -/* arrows */ -.ui-icon-arrow-r { - background-position: -108px 50%; -} -.ui-icon-arrow-l { - background-position: -144px 50%; -} -.ui-icon-arrow-u { - background-position: -180px 50%; -} -.ui-icon-arrow-d { - background-position: -216px 50%; -} - -/* misc */ -.ui-icon-check { - background-position: -252px 50%; -} -.ui-icon-gear { - background-position: -288px 50%; -} -.ui-icon-refresh { - background-position: -324px 50%; -} -.ui-icon-forward { - background-position: -360px 50%; -} -.ui-icon-back { - background-position: -396px 50%; -} -.ui-icon-grid { - background-position: -432px 50%; -} -.ui-icon-star { - background-position: -468px 50%; -} -.ui-icon-alert { - background-position: -504px 50%; -} -.ui-icon-info { - background-position: -540px 50%; -} -.ui-icon-home { - background-position: -576px 50%; -} -.ui-icon-search { - background-position: -612px 50%; -} -.ui-icon-checkbox-off { - background-position: -684px 50%; -} -.ui-icon-checkbox-on { - background-position: -648px 50%; -} -.ui-icon-radio-off { - background-position: -756px 50%; -} -.ui-icon-radio-on { - background-position: -720px 50%; -} - - -/* checks,radios */ -.ui-icon-checkbox-off, -.ui-icon-checkbox-on, -.ui-icon-radio-off, -.ui-icon-radio-on { - background-color: transparent; - -moz-border-radius: 0; - -webkit-border-radius: 0; - border-radius: 0; -} -.ui-icon-searchfield { - background-image: url(images/icon-search-black.png); - background-size: 16px 16px; -} - -/* loading icon */ -.ui-icon-loading { - background-image: url(images/ajax-loader.png); - width: 40px; - height: 40px; - -moz-border-radius: 20px; - -webkit-border-radius: 20px; - border-radius: 20px; - background-size: 35px 35px; -} - - -/* Button corner classes ------------------------------------------------------------------------------------------------------------*/ - -.ui-btn-corner-tl { - -moz-border-radius-topleft: 1em; - -webkit-border-top-left-radius: 1em; - border-top-left-radius: 1em; -} -.ui-btn-corner-tr { - -moz-border-radius-topright: 1em; - -webkit-border-top-right-radius: 1em; - border-top-right-radius: 1em; -} -.ui-btn-corner-bl { - -moz-border-radius-bottomleft: 1em; - -webkit-border-bottom-left-radius: 1em; - border-bottom-left-radius: 1em; -} -.ui-btn-corner-br { - -moz-border-radius-bottomright: 1em; - -webkit-border-bottom-right-radius: 1em; - border-bottom-right-radius: 1em; -} -.ui-btn-corner-top { - -moz-border-radius-topleft: 1em; - -webkit-border-top-left-radius: 1em; - border-top-left-radius: 1em; - -moz-border-radius-topright: 1em; - -webkit-border-top-right-radius: 1em; - border-top-right-radius: 1em; -} -.ui-btn-corner-bottom { - -moz-border-radius-bottomleft: 1em; - -webkit-border-bottom-left-radius: 1em; - border-bottom-left-radius: 1em; - -moz-border-radius-bottomright: 1em; - -webkit-border-bottom-right-radius: 1em; - border-bottom-right-radius: 1em; -} -.ui-btn-corner-right { - -moz-border-radius-topright: 1em; - -webkit-border-top-right-radius: 1em; - border-top-right-radius: 1em; - -moz-border-radius-bottomright: 1em; - -webkit-border-bottom-right-radius: 1em; - border-bottom-right-radius: 1em; -} -.ui-btn-corner-left { - -moz-border-radius-topleft: 1em; - -webkit-border-top-left-radius: 1em; - border-top-left-radius: 1em; - -moz-border-radius-bottomleft: 1em; - -webkit-border-bottom-left-radius: 1em; - border-bottom-left-radius: 1em; -} -.ui-btn-corner-all { - -moz-border-radius: 1em; - -webkit-border-radius: 1em; - border-radius: 1em; -} - -/* radius clip workaround for cleaning up corner trapping */ -.ui-corner-tl, -.ui-corner-tr, -.ui-corner-bl, -.ui-corner-br, -.ui-corner-top, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-left, -.ui-corner-all, -.ui-btn-corner-tl, -.ui-btn-corner-tr, -.ui-btn-corner-bl, -.ui-btn-corner-br, -.ui-btn-corner-top, -.ui-btn-corner-bottom, -.ui-btn-corner-right, -.ui-btn-corner-left, -.ui-btn-corner-all { - -webkit-background-clip: padding-box; - -moz-background-clip: padding-box; - background-clip: padding-box; -} - -/* Overlay / modal ------------------------------------------------------------------------------------------------------------*/ - -.ui-overlay { - background: #666; - opacity: .5; - filter: Alpha(Opacity=50); - position: absolute; - width: 100%; - height: 100%; -} -.ui-overlay-shadow { - -moz-box-shadow: 0px 0px 12px rgba(0,0,0,.6); - -webkit-box-shadow: 0px 0px 12px rgba(0,0,0,.6); - box-shadow: 0px 0px 12px rgba(0,0,0,.6); -} -.ui-shadow { - -moz-box-shadow: 0px 1px 4px rgba(0,0,0,.3); - -webkit-box-shadow: 0px 1px 4px rgba(0,0,0,.3); - box-shadow: 0px 1px 4px rgba(0,0,0,.3); -} -.ui-bar-a .ui-shadow, -.ui-bar-b .ui-shadow , -.ui-bar-c .ui-shadow { - -moz-box-shadow: 0px 1px 0 rgba(255,255,255,.3); - -webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.3); - box-shadow: 0px 1px 0 rgba(255,255,255,.3); -} -.ui-shadow-inset { - -moz-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); - -webkit-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); - box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); -} -.ui-icon-shadow { - -moz-box-shadow: 0px 1px 0 rgba(255,255,255,.4); - -webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.4); - box-shadow: 0px 1px 0 rgba(255,255,255,.4); -} - - -/* Focus state - set here for specificity ------------------------------------------------------------------------------------------------------------*/ - -.ui-focus { - -moz-box-shadow: 0px 0px 12px #387bbe; - -webkit-box-shadow: 0px 0px 12px #387bbe; - box-shadow: 0px 0px 12px #387bbe; -} - -/* unset box shadow in browsers that don't do it right ------------------------------------------------------------------------------------------------------------*/ - -.ui-mobile-nosupport-boxshadow * { - -moz-box-shadow: none !important; - -webkit-box-shadow: none !important; - box-shadow: none !important; -} - -/* ...and bring back focus */ -.ui-mobile-nosupport-boxshadow .ui-focus { - outline-width: 2px; -}/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -* Note: Code is in draft form and is subject to change -*/ - -/* some unsets - more probably needed */ -.ui-mobile, .ui-mobile body { height: 100%; } -.ui-mobile fieldset, .ui-page { padding: 0; margin: 0; } -.ui-mobile a img, .ui-mobile fieldset { border: 0; } - -/* responsive page widths */ -.ui-mobile-viewport { margin: 0; overflow-x: hidden; -webkit-text-size-adjust: none; -ms-text-size-adjust:none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } - -/* "page" containers - full-screen views, one should always be in view post-pageload */ -.ui-mobile [data-role=page], .ui-mobile [data-role=dialog], .ui-page { top: 0; left: 0; width: 100%; min-height: 100%; position: absolute; display: none; border: 0; } -.ui-mobile .ui-page-active { display: block; overflow: visible; } - -/*orientations from js are available */ -.portrait, -.portrait .ui-page { min-height: 100%; } -.landscape, -.landscape .ui-page { min-height: 100%; } - -/* loading screen */ -.ui-loading .ui-mobile-viewport { overflow: hidden !important; } -.ui-loading .ui-loader { display: block; } -.ui-loading .ui-page { overflow: hidden; } -.ui-loader { display: none; position: absolute; opacity: .85; z-index: 10; left: 50%; width: 200px; margin-left: -130px; margin-top: -35px; padding: 10px 30px; } -.ui-loader h1 { font-size: 15px; text-align: center; } -.ui-loader .ui-icon { position: static; display: block; opacity: .9; margin: 0 auto; width: 35px; height: 35px; background-color: transparent; } - -/*fouc*/ -.ui-mobile-rendering > * { visibility: hidden; } - -/*headers, content panels*/ -.ui-bar, .ui-body { position: relative; padding: .4em 15px; overflow: hidden; display: block; clear:both; } -.ui-bar { font-size: 16px; margin: 0; } -.ui-bar h1, .ui-bar h2, .ui-bar h3, .ui-bar h4, .ui-bar h5, .ui-bar h6 { margin: 0; padding: 0; font-size: 16px; display: inline-block; } - -.ui-header, .ui-footer { display: block; } -.ui-page .ui-header, .ui-page .ui-footer { position: relative; } -.ui-header .ui-btn-left { position: absolute; left: 10px; top: .4em; } -.ui-header .ui-btn-right { position: absolute; right: 10px; top: .4em; } -.ui-header .ui-title, .ui-footer .ui-title { text-align: center; font-size: 16px; display: block; margin: .6em 90px .8em; padding: 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; outline: 0 !important; } - -/*content area*/ -.ui-content { border-width: 0; overflow: visible; overflow-x: hidden; padding: 15px; } -.ui-page-fullscreen .ui-content { padding:0; } - -/* icons sizing */ -.ui-icon { width: 18px; height: 18px; } - -/* fullscreen class on ui-content div */ -.ui-fullscreen { } -.ui-fullscreen img { max-width: 100%; } - -/* non-js content hiding */ -.ui-nojs { position: absolute; left: -9999px; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.spin { - -webkit-transform: rotate(360deg); - -webkit-animation-name: spin; - -webkit-animation-duration: 1s; - -webkit-animation-iteration-count: infinite; -} -@-webkit-keyframes spin { - from {-webkit-transform: rotate(0deg);} - to {-webkit-transform: rotate(360deg);} -} - -/* Transitions from jQtouch (with small modifications): http://www.jqtouch.com/ -Built by David Kaneda and maintained by Jonathan Stark. -*/ -.in, .out { - -webkit-animation-timing-function: ease-in-out; - -webkit-animation-duration: 350ms; -} - -.slide.in { - -webkit-transform: translateX(0); - -webkit-animation-name: slideinfromright; -} - -.slide.out { - -webkit-transform: translateX(-100%); - -webkit-animation-name: slideouttoleft; -} - -.slide.in.reverse { - -webkit-transform: translateX(0); - -webkit-animation-name: slideinfromleft; -} - -.slide.out.reverse { - -webkit-transform: translateX(100%); - -webkit-animation-name: slideouttoright; -} - -.slideup.in { - -webkit-transform: translateY(0); - -webkit-animation-name: slideinfrombottom; - z-index: 10; -} - -.slideup.out { - -webkit-animation-name: dontmove; - z-index: 0; -} - -.slideup.out.reverse { - -webkit-transform: translateY(100%); - z-index: 10; - -webkit-animation-name: slideouttobottom; -} - -.slideup.in.reverse { - z-index: 0; - -webkit-animation-name: dontmove; -} -.slidedown.in { - -webkit-transform: translateY(0); - -webkit-animation-name: slideinfromtop; - z-index: 10; -} - -.slidedown.out { - -webkit-animation-name: dontmove; - z-index: 0; -} - -.slidedown.out.reverse { - -webkit-transform: translateY(-100%); - z-index: 10; - -webkit-animation-name: slideouttotop; -} - -.slidedown.in.reverse { - z-index: 0; - -webkit-animation-name: dontmove; -} - -@-webkit-keyframes slideinfromright { - from { -webkit-transform: translateX(100%); } - to { -webkit-transform: translateX(0); } -} - -@-webkit-keyframes slideinfromleft { - from { -webkit-transform: translateX(-100%); } - to { -webkit-transform: translateX(0); } -} - -@-webkit-keyframes slideouttoleft { - from { -webkit-transform: translateX(0); } - to { -webkit-transform: translateX(-100%); } -} - -@-webkit-keyframes slideouttoright { - from { -webkit-transform: translateX(0); } - to { -webkit-transform: translateX(100%); } -} - - -@-webkit-keyframes slideinfromtop { - from { -webkit-transform: translateY(-100%); } - to { -webkit-transform: translateY(0); } -} - -@-webkit-keyframes slideinfrombottom { - from { -webkit-transform: translateY(100%); } - to { -webkit-transform: translateY(0); } -} - -@-webkit-keyframes slideouttobottom { - from { -webkit-transform: translateY(0); } - to { -webkit-transform: translateY(100%); } -} - -@-webkit-keyframes slideouttotop { - from { -webkit-transform: translateY(0); } - to { -webkit-transform: translateY(-100%); } -} -@-webkit-keyframes fadein { - from { opacity: 0; } - to { opacity: 1; } -} - -@-webkit-keyframes fadeout { - from { opacity: 1; } - to { opacity: 0; } -} - -.fade.in { - opacity: 1; - z-index: 10; - -webkit-animation-name: fadein; -} -.fade.out { - z-index: 0; - -webkit-animation-name: fadeout; -} - -/* The properties in this body rule are only necessary for the 'flip' transition. - * We need specify the perspective to create a projection matrix. This will add - * some depth as the element flips. The depth number represents the distance of - * the viewer from the z-plane. According to the CSS3 spec, 1000 is a moderate - * value. - */ -.ui-mobile-viewport-perspective { - -webkit-perspective: 1000; - position: absolute; -} - -.ui-mobile-viewport-transitioning, -.ui-mobile-viewport-transitioning .ui-page { - width: 100%; - height: 100%; - overflow: hidden; -} - -.flip { - -webkit-animation-duration: .65s; - -webkit-backface-visibility:hidden; - -webkit-transform:translateX(0); /* Needed to work around an iOS 3.1 bug that causes listview thumbs to disappear when -webkit-visibility:hidden is used. */ -} - -.flip.in { - -webkit-transform: rotateY(0) scale(1); - -webkit-animation-name: flipinfromleft; -} - -.flip.out { - -webkit-transform: rotateY(-180deg) scale(.8); - -webkit-animation-name: flipouttoleft; -} - -/* Shake it all about */ - -.flip.in.reverse { - -webkit-transform: rotateY(0) scale(1); - -webkit-animation-name: flipinfromright; -} - -.flip.out.reverse { - -webkit-transform: rotateY(180deg) scale(.8); - -webkit-animation-name: flipouttoright; -} - -@-webkit-keyframes flipinfromright { - from { -webkit-transform: rotateY(-180deg) scale(.8); } - to { -webkit-transform: rotateY(0) scale(1); } -} - -@-webkit-keyframes flipinfromleft { - from { -webkit-transform: rotateY(180deg) scale(.8); } - to { -webkit-transform: rotateY(0) scale(1); } -} - -@-webkit-keyframes flipouttoleft { - from { -webkit-transform: rotateY(0) scale(1); } - to { -webkit-transform: rotateY(-180deg) scale(.8); } -} - -@-webkit-keyframes flipouttoright { - from { -webkit-transform: rotateY(0) scale(1); } - to { -webkit-transform: rotateY(180deg) scale(.8); } -} - - -/* Hackish, but reliable. */ - -@-webkit-keyframes dontmove { - from { opacity: 1; } - to { opacity: 1; } -} - -.pop { - -webkit-transform-origin: 50% 50%; -} - -.pop.in { - -webkit-transform: scale(1); - opacity: 1; - -webkit-animation-name: popin; - z-index: 10; -} - -.pop.out.reverse { - -webkit-transform: scale(.2); - opacity: 0; - -webkit-animation-name: popout; - z-index: 10; -} - -.pop.in.reverse { - z-index: 0; - -webkit-animation-name: dontmove; -} - -@-webkit-keyframes popin { - from { - -webkit-transform: scale(.2); - opacity: 0; - } - to { - -webkit-transform: scale(1); - opacity: 1; - } -} - -@-webkit-keyframes popout { - from { - -webkit-transform: scale(1); - opacity: 1; - } - to { - -webkit-transform: scale(.2); - opacity: 0; - } -}/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ - -/* content configurations. */ -.ui-grid-a, .ui-grid-b, .ui-grid-c, .ui-grid-d { overflow: hidden; } -.ui-block-a, .ui-block-b, .ui-block-c, .ui-block-d, .ui-block-e { margin: 0; padding: 0; border: 0; float: left; min-height:1px;} - -/* grid solo: 100 - single item fallback */ -.ui-grid-solo .ui-block-a { width: 100%; float: none; } - -/* grid a: 50/50 */ -.ui-grid-a .ui-block-a, .ui-grid-a .ui-block-b { width: 50%; } -.ui-grid-a .ui-block-a { clear: left; } - -/* grid b: 33/33/33 */ -.ui-grid-b .ui-block-a, .ui-grid-b .ui-block-b, .ui-grid-b .ui-block-c { width: 33.333%; } -.ui-grid-b .ui-block-a { clear: left; } - -/* grid c: 25/25/25/25 */ -.ui-grid-c .ui-block-a, .ui-grid-c .ui-block-b, .ui-grid-c .ui-block-c, .ui-grid-c .ui-block-d { width: 25%; } -.ui-grid-c .ui-block-a { clear: left; } - -/* grid d: 20/20/20/20/20 */ -.ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e { width: 20%; } -.ui-grid-d .ui-block-a { clear: left; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -/* fixed page header & footer configuration */ -.ui-header, .ui-footer, .ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { position: absolute; overflow: hidden; width: 100%; border-left-width: 0; border-right-width: 0; } -.ui-header-fixed, .ui-footer-fixed { - z-index: 1000; - -webkit-transform: translateZ(0); /* Force header/footer rendering to go through the same rendering pipeline as native page scrolling. */ -} -.ui-footer-duplicate, .ui-page-fullscreen .ui-fixed-inline { display: none; } -.ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { opacity: .9; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-navbar { overflow: hidden; } -.ui-navbar ul, .ui-navbar-expanded ul { list-style:none; padding: 0; margin: 0; position: relative; display: block; border: 0;} -.ui-navbar-collapsed ul { float: left; width: 75%; margin-right: -2px; } -.ui-navbar-collapsed .ui-navbar-toggle { float: left; width: 25%; } -.ui-navbar li.ui-navbar-truncate { position: absolute; left: -9999px; top: -9999px; } -.ui-navbar li .ui-btn, .ui-navbar .ui-navbar-toggle .ui-btn { display: block; font-size: 12px; text-align: center; margin: 0; border-right-width: 0; } -.ui-navbar li .ui-btn { margin-right: -1px; } -.ui-navbar li .ui-btn:last-child { margin-right: 0; } -.ui-header .ui-navbar li .ui-btn, .ui-header .ui-navbar .ui-navbar-toggle .ui-btn, -.ui-footer .ui-navbar li .ui-btn, .ui-footer .ui-navbar .ui-navbar-toggle .ui-btn { border-top-width: 0; border-bottom-width: 0; } -.ui-navbar .ui-btn-inner { padding-left: 2px; padding-right: 2px; } -.ui-navbar-noicons li .ui-btn .ui-btn-inner, .ui-navbar-noicons .ui-navbar-toggle .ui-btn-inner { padding-top: .8em; padding-bottom: .9em; } -/*expanded page styles*/ -.ui-navbar-expanded .ui-btn { margin: 0; font-size: 14px; } -.ui-navbar-expanded .ui-btn-inner { padding-left: 5px; padding-right: 5px; } -.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner { padding: 45px 5px 15px; text-align: center; } -.ui-navbar-expanded .ui-btn-icon-top .ui-icon { top: 15px; } -.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner { padding: 15px 5px 45px; text-align: center; } -.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon { bottom: 15px; } -.ui-navbar-expanded li .ui-btn .ui-btn-inner { min-height: 2.5em; } -.ui-navbar-expanded .ui-navbar-noicons .ui-btn .ui-btn-inner { padding-top: 1.8em; padding-bottom: 1.9em; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-btn { display: block; text-align: center; cursor:pointer; position: relative; margin: .5em 5px; padding: 0; } -.ui-btn:focus, .ui-btn:active { outline: none; } -.ui-header .ui-btn, .ui-footer .ui-btn, .ui-bar .ui-btn { display: inline-block; font-size: 13px; margin: 0; } -.ui-btn-inline { display: inline-block; } -.ui-btn-inner { padding: .6em 25px; display: block; height: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; position: relative; } -.ui-header .ui-btn-inner, .ui-footer .ui-btn-inner, .ui-bar .ui-btn-inner { padding: .4em 8px .5em; } -.ui-btn-icon-notext { display: inline-block; width: 20px; height: 20px; padding: 2px 1px 2px 3px; text-indent: -9999px; } -.ui-btn-icon-notext .ui-btn-inner { padding: 0; } -.ui-btn-icon-notext .ui-btn-text { position: absolute; left: -999px; } -.ui-btn-icon-left .ui-btn-inner { padding-left: 33px; } -.ui-header .ui-btn-icon-left .ui-btn-inner, -.ui-footer .ui-btn-icon-left .ui-btn-inner, -.ui-bar .ui-btn-icon-left .ui-btn-inner { padding-left: 27px; } -.ui-btn-icon-right .ui-btn-inner { padding-right: 33px; } -.ui-header .ui-btn-icon-right .ui-btn-inner, -.ui-footer .ui-btn-icon-right .ui-btn-inner, -.ui-bar .ui-btn-icon-right .ui-btn-inner { padding-right: 27px; } -.ui-btn-icon-top .ui-btn-inner { padding-top: 33px; } -.ui-header .ui-btn-icon-top .ui-btn-inner, -.ui-footer .ui-btn-icon-top .ui-btn-inner, -.ui-bar .ui-btn-icon-top .ui-btn-inner { padding-top: 27px; } -.ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 33px; } -.ui-header .ui-btn-icon-bottom .ui-btn-inner, -.ui-footer .ui-btn-icon-bottom .ui-btn-inner, -.ui-bar .ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 27px; } - -/*btn icon positioning*/ -.ui-btn-icon-notext .ui-icon { display: block; } -.ui-btn-icon-left .ui-icon, .ui-btn-icon-right .ui-icon { position: absolute; top: 50%; margin-top: -9px; } -.ui-btn-icon-top .ui-icon, .ui-btn-icon-bottom .ui-icon { position: absolute; left: 50%; margin-left: -9px; } -.ui-btn-icon-left .ui-icon { left: 10px; } -.ui-btn-icon-right .ui-icon {right: 10px; } -.ui-header .ui-btn-icon-left .ui-icon, -.ui-footer .ui-btn-icon-left .ui-icon, -.ui-bar .ui-btn-icon-left .ui-icon { left: 4px; } -.ui-header .ui-btn-icon-right .ui-icon, -.ui-footer .ui-btn-icon-right .ui-icon, -.ui-bar .ui-btn-icon-right .ui-icon { right: 4px; } -.ui-header .ui-btn-icon-top .ui-icon, -.ui-footer .ui-btn-icon-top .ui-icon, -.ui-bar .ui-btn-icon-top .ui-icon { top: 4px; } -.ui-header .ui-btn-icon-bottom .ui-icon, -.ui-footer .ui-btn-icon-bottom .ui-icon, -.ui-bar .ui-btn-icon-bottom .ui-icon { bottom: 4px; } -.ui-btn-icon-top .ui-icon { top: 5px; } -.ui-btn-icon-bottom .ui-icon { bottom: 5px; } -/*hiding native button,inputs */ -.ui-btn-hidden { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: button; opacity: 0; cursor: pointer; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-collapsible-contain { margin: .5em 0; } -.ui-collapsible-heading { font-size: 16px; display: block; margin: 0 -8px; padding: 0; border-width: 0 0 1px 0; position: relative; } -.ui-collapsible-heading a { text-align: left; margin: 0; } -.ui-collapsible-heading a .ui-btn-inner { padding-left: 40px; } -.ui-collapsible-heading a span.ui-btn { position: absolute; left: 6px; top: 50%; margin: -12px 0 0 0; width: 20px; height: 20px; padding: 1px 0px 1px 2px; text-indent: -9999px; } -.ui-collapsible-heading a span.ui-btn .ui-btn-inner { padding: 0; } -.ui-collapsible-heading a span.ui-btn .ui-icon { left: 0; margin-top: -10px; } -.ui-collapsible-heading-status { position:absolute; left:-9999px; } -.ui-collapsible-content { display: block; padding: 10px 0 10px 8px; } -.ui-collapsible-content-collapsed { display: none; } - -.ui-collapsible-set { margin: .5em 0; } -.ui-collapsible-set .ui-collapsible-contain { margin: -1px 0 0; } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-controlgroup, fieldset.ui-controlgroup { padding: 0; margin: .5em 0 1em; } -.ui-bar .ui-controlgroup { margin: 0 .3em; } -.ui-controlgroup-label { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; } -.ui-controlgroup-controls { display: block; width: 95%;} -.ui-controlgroup li { list-style: none; } -.ui-controlgroup-vertical .ui-btn, -.ui-controlgroup-vertical .ui-checkbox, .ui-controlgroup-vertical .ui-radio { margin: 0; border-bottom-width: 0; } -.ui-controlgroup-vertical .ui-controlgroup-last { border-bottom-width: 1px; } -.ui-controlgroup-horizontal { padding: 0; } -.ui-controlgroup-horizontal .ui-btn, -.ui-controlgroup-horizontal .ui-checkbox, .ui-controlgroup-horizontal .ui-radio { display: inline-block; margin: 0 -5px 0 0; } -.ui-controlgroup-horizontal .ui-checkbox, .ui-controlgroup-horizontal .ui-radio { display: inline; } -.ui-controlgroup-horizontal .ui-checkbox .ui-btn, .ui-controlgroup-horizontal .ui-radio .ui-btn, -.ui-controlgroup-horizontal .ui-checkbox:last-child, .ui-controlgroup-horizontal .ui-radio:last-child { margin-right: 0; } -.ui-controlgroup-horizontal .ui-controlgroup-last { margin-right: 0; } -.ui-controlgroup .ui-checkbox label, .ui-controlgroup .ui-radio label { font-size: 16px; } -/* conflicts with listview.. -.ui-controlgroup .ui-btn-icon-notext { width: 30px; height: 30px; text-indent: -9999px; } -.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner { padding: 5px 6px 5px 5px; } -*/ - -.min-width-480px .ui-controlgroup-label { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0; } -.min-width-480px .ui-controlgroup-controls { width: 60%; display: inline-block; } /* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-dialog { min-height: 480px; } -.ui-dialog .ui-header, .ui-dialog .ui-content, .ui-dialog .ui-footer { margin: 15px; position: relative; } -.ui-dialog .ui-header, .ui-dialog .ui-footer { z-index: 10; width: auto; } -.ui-dialog .ui-content, .ui-dialog .ui-footer { margin-top: -15px; }/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-checkbox, .ui-radio { position:relative; margin: .2em 0 .5em; z-index: 1; } -.ui-checkbox .ui-btn, .ui-radio .ui-btn { margin: 0; text-align: left; z-index: 2; } -.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner { padding-left: 45px; } -.ui-checkbox .ui-btn-icon-right .ui-btn-inner, .ui-radio .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } -.ui-checkbox .ui-btn-icon-left .ui-icon, .ui-radio .ui-btn-icon-left .ui-icon {left: 15px; } -.ui-checkbox .ui-btn-icon-right .ui-icon, .ui-radio .ui-btn-icon-right .ui-icon {right: 15px; } -/* input, label positioning */ -.ui-checkbox input,.ui-radio input { position:absolute; left:20px; top:50%; width: 10px; height: 10px; margin:-5px 0 0 0; outline: 0 !important; z-index: 1; }/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-field-contain { background: none; padding: 1.5em 0; margin: 0; border-bottom-width: 1px; overflow: visible; } -.ui-field-contain:first-child { border-top-width: 0; } -.min-width-480px .ui-field-contain { border-width: 0; padding: 0; margin: 1em 0; }/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-select { display: block; position: relative; } -.ui-select select { position: absolute; left: -9999px; top: -9999px; } -.ui-select .ui-btn { overflow: hidden; } -.ui-select .ui-btn select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; height: 100%; opacity: 0; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); } -.ui-select .ui-btn select.ui-select-nativeonly { opacity: 1; } - -.ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } -.ui-select .ui-btn-icon-right .ui-icon { right: 15px; } - -/* labels */ -label.ui-select { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; display: block; } - -/*listbox*/ -.ui-select .ui-btn-text, .ui-selectmenu .ui-btn-text { display: inline-block; min-height: 1em; } -.ui-select .ui-btn-text { text-overflow: ellipsis; overflow: hidden; display: block;} - -.ui-selectmenu { position: absolute; padding: 0; z-index: 100 !important; width: 80%; max-width: 350px; padding: 6px; } -.ui-selectmenu .ui-listview { margin: 0; } -.ui-selectmenu .ui-btn.ui-li-divider { cursor: default; } -.ui-selectmenu-hidden { top: -9999px; left: -9999px; } -.ui-selectmenu-screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 99; } -.ui-screen-hidden, .ui-selectmenu-list .ui-li .ui-icon { display: none; } -.ui-selectmenu-list .ui-li .ui-icon { display: block; } -.ui-li.ui-selectmenu-placeholder { display: none; } -.ui-selectmenu .ui-header .ui-title { margin: 0.6em 46px 0.8em; } - -.min-width-480px label.ui-select { display: inline-block; width: 20%; margin: 0 2% 0 0; } -.min-width-480px .ui-select { width: 60%; display: inline-block; } - -/* when no placeholder is defined in a multiple select, the header height doesn't even extend past the close button. this shim's content in there */ -.ui-selectmenu .ui-header h1:after { content: '.'; visibility: hidden; }/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -label.ui-input-text { font-size: 16px; line-height: 1.4; display: block; font-weight: normal; margin: 0 0 .3em; } -input.ui-input-text, textarea.ui-input-text { background-image: none; padding: .4em; line-height: 1.4; font-size: 16px; display: block; width: 95%; } -input.ui-input-text { -webkit-appearance: none; } -textarea.ui-input-text { height: 50px; -webkit-transition: height 200ms linear; -moz-transition: height 200ms linear; -o-transition: height 200ms linear; transition: height 200ms linear; } -.ui-input-search { padding: 0 30px; width: 77%; background-position: 8px 50%; background-repeat: no-repeat; position: relative; } -.ui-input-search input.ui-input-text { border: none; width: 98%; padding: .4em 0; margin: 0; display: block; background: transparent none; outline: 0 !important; } -.ui-input-search .ui-input-clear { position: absolute; right: 0; top: 50%; margin-top: -14px; } -.ui-input-search .ui-input-clear-hidden { display: none; } - -/* orientation adjustments - incomplete!*/ -.min-width-480px label.ui-input-text { vertical-align: top; } -.min-width-480px label.ui-input-text { display: inline-block; width: 20%; margin: 0 2% 0 0; } -.min-width-480px input.ui-input-text, -.min-width-480px textarea.ui-input-text, -.min-width-480px .ui-input-search { width: 60%; display: inline-block; } -.min-width-480px .ui-input-search { width: 50%; } -.min-width-480px .ui-input-search input.ui-input-text { width: 98%; /*echos rule from above*/ } -/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -.ui-listview { margin: 0; counter-reset: listnumbering; } -.ui-content .ui-listview { margin: -15px; } -.ui-content .ui-listview-inset { margin: 1em 0; } -.ui-listview, .ui-li { list-style:none; padding:0; } -.ui-li, .ui-li.ui-field-contain { display: block; margin:0; position: relative; overflow: visible; text-align: left; border-width: 0; border-top-width: 1px; } -.ui-li .ui-btn-text a.ui-link-inherit { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } -.ui-li-divider, .ui-li-static { padding: .5em 15px; font-size: 14px; font-weight: bold; } -.ui-li-divider { counter-reset: listnumbering; } -ol.ui-listview .ui-link-inherit:before, ol.ui-listview .ui-li-static:before, .ui-li-dec { font-size: .8em; display: inline-block; padding-right: .3em; font-weight: normal;counter-increment: listnumbering; content: counter(listnumbering) ". "; } -ol.ui-listview .ui-li-jsnumbering:before { content: "" !important; } /* to avoid chance of duplication */ -.ui-listview-inset .ui-li { border-right-width: 1px; border-left-width: 1px; } -.ui-li:last-child, .ui-li.ui-field-contain:last-child { border-bottom-width: 1px; } -.ui-li>.ui-btn-inner { display: block; position: relative; padding: 0; } -.ui-li .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li { padding: .7em 75px .7em 15px; display: block; } -.ui-li-has-thumb .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-thumb { min-height: 60px; padding-left: 100px; } -.ui-li-has-icon .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-icon { min-height: 20px; padding-left: 40px; } -.ui-li-heading { font-size: 16px; font-weight: bold; display: block; margin: .6em 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } -.ui-li-desc { font-size: 12px; font-weight: normal; display: block; margin: -.5em 0 .6em; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } -.ui-li-thumb, .ui-li-icon { position: absolute; left: 1px; top: 0; max-height: 80px; max-width: 80px; } -.ui-li-icon { max-height: 40px; max-width: 40px; left: 10px; top: .9em; } -.ui-li-thumb, .ui-li-icon, .ui-li-content { float: left; margin-right: 10px; } - -.ui-li-aside { float: right; width: 50%; text-align: right; margin: .3em 0; } -.min-width-480px .ui-li-aside { width: 45%; } -.ui-li-divider { cursor: default; } -.ui-li-has-alt .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-alt { padding-right: 95px; } -.ui-li-count { position: absolute; font-size: 11px; font-weight: bold; padding: .2em .5em; top: 50%; margin-top: -.9em; right: 38px; } -.ui-li-divider .ui-li-count, .ui-li-static .ui-li-count { right: 10px; } -.ui-li-has-alt .ui-li-count { right: 55px; } -.ui-li-link-alt { position: absolute; width: 40px; height: 100%; border-width: 0; border-left-width: 1px; top: 0; right: 0; margin: 0; padding: 0; } -.ui-li-link-alt .ui-btn { overflow: hidden; position: absolute; right: 8px; top: 50%; margin: -11px 0 0 0; border-bottom-width: 1px; } -.ui-li-link-alt .ui-btn-inner { padding: 0; position: static; } -.ui-li-link-alt .ui-btn .ui-icon { right: 50%; margin-right: -9px; } - -.ui-listview-filter { border-width: 0; overflow: hidden; margin: -15px -15px 15px -15px } -.ui-listview-filter .ui-input-search { margin: 5px; width: auto; display: block; } - -.ui-listview-filter-inset { margin: -15px -5px -15px -5px; background: transparent; } - -/* Odd iPad positioning issue. */ -@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { - .ui-li .ui-btn-text { overflow: visible; } -}/* -* jQuery Mobile Framework -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. -*/ -label.ui-slider { display: block; } -input.ui-slider-input, .min-width-480px input.ui-slider-input { display: inline-block; width: 50px; } -select.ui-slider-switch { display: none; } -div.ui-slider { position: relative; display: inline-block; overflow: visible; height: 15px; padding: 0; margin: 0 2% 0 20px; top: 4px; width: 66%; } -a.ui-slider-handle { position: absolute; z-index: 10; top: 50%; width: 28px; height: 28px; margin-top: -15px; margin-left: -15px; } -a.ui-slider-handle .ui-btn-inner { padding-left: 0; padding-right: 0; } -.min-width-480px label.ui-slider { display: inline-block; width: 20%; margin: 0 2% 0 0; } -.min-width-480px div.ui-slider { width: 45%; } - -div.ui-slider-switch { height: 32px; overflow: hidden; margin-left: 0; } -div.ui-slider-inneroffset { margin-left: 50%; position: absolute; top: 1px; height: 100%; width: 50%; } -div.ui-slider-handle-snapping { -webkit-transition: left 100ms linear; } -div.ui-slider-labelbg { position: absolute; top:0; margin: 0; border-width: 0; } -div.ui-slider-switch div.ui-slider-labelbg-a { width: 60%; height: 100%; left: 0; } -div.ui-slider-switch div.ui-slider-labelbg-b { width: 60%; height: 100%; right: 0; } -.ui-slider-switch-a div.ui-slider-labelbg-a, .ui-slider-switch-b div.ui-slider-labelbg-b { z-index: -1; } -.ui-slider-switch-a div.ui-slider-labelbg-b, .ui-slider-switch-b div.ui-slider-labelbg-a { z-index: 0; } - -div.ui-slider-switch a.ui-slider-handle { z-index: 20; width: 101%; height: 32px; margin-top: -18px; margin-left: -101%; } -span.ui-slider-label { width: 100%; position: absolute;height: 32px; font-size: 16px; text-align: center; line-height: 2; background: none; border-color: transparent; } -span.ui-slider-label-a { left: -100%; margin-right: -1px } -span.ui-slider-label-b { right: -100%; margin-left: -1px } - --- /dev/null +++ b/css/jquery.mobile-1.1.0.min.css @@ -1,1 +1,2 @@ - +/*! jQuery Mobile v1.1.0 db342b1f315c282692791aa870455901fdb46a55 jquerymobile.com | jquery.org/license */ +.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:bold;text-shadow:0 -1px 1px #000;background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#111));background-image:-webkit-linear-gradient(#3c3c3c,#111);background-image:-moz-linear-gradient(#3c3c3c,#111);background-image:-ms-linear-gradient(#3c3c3c,#111);background-image:-o-linear-gradient(#3c3c3c,#111);background-image:linear-gradient(#3c3c3c,#111)}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a .ui-link{color:#7cc4e7;font-weight:bold}.ui-bar-a .ui-link:hover{color:#2489ce}.ui-bar-a .ui-link:active{color:#2489ce}.ui-bar-a .ui-link:visited{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 1px #111;font-weight:normal;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#222));background-image:-webkit-linear-gradient(#444,#222);background-image:-moz-linear-gradient(#444,#222);background-image:-ms-linear-gradient(#444,#222);background-image:-o-linear-gradient(#444,#222);background-image:linear-gradient(#444,#222)}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:bold}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-body-a .ui-link:visited{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#2d2d2d));background-image:-webkit-linear-gradient(#444,#2d2d2d);background-image:-moz-linear-gradient(#444,#2d2d2d);background-image:-ms-linear-gradient(#444,#2d2d2d);background-image:-o-linear-gradient(#444,#2d2d2d);background-image:linear-gradient(#444,#2d2d2d)}.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#555),to(#383838));background-image:-webkit-linear-gradient(#555,#383838);background-image:-moz-linear-gradient(#555,#383838);background-image:-ms-linear-gradient(#555,#383838);background-image:-o-linear-gradient(#555,#383838);background-image:linear-gradient(#555,#383838)}.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:bold;color:#fff;text-shadow:0 1px 1px #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#202020),to(#2c2c2c));background-image:-webkit-linear-gradient(#202020,#2c2c2c);background-image:-moz-linear-gradient(#202020,#2c2c2c);background-image:-ms-linear-gradient(#202020,#2c2c2c);background-image:-o-linear-gradient(#202020,#2c2c2c);background-image:linear-gradient(#202020,#2c2c2c)}.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:bold;text-shadow:0 1px 1px #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#497bae));background-image:-webkit-linear-gradient(#6facd5,#497bae);background-image:-moz-linear-gradient(#6facd5,#497bae);background-image:-ms-linear-gradient(#6facd5,#497bae);background-image:-o-linear-gradient(#6facd5,#497bae);background-image:linear-gradient(#6facd5,#497bae)}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b .ui-link{color:#ddf0f8;font-weight:bold}.ui-bar-b .ui-link:hover{color:#ddf0f8}.ui-bar-b .ui-link:active{color:#ddf0f8}.ui-bar-b .ui-link:visited{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:normal;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#ccc));background-image:-webkit-linear-gradient(#ddd,#ccc);background-image:-moz-linear-gradient(#ddd,#ccc);background-image:-ms-linear-gradient(#ddd,#ccc);background-image:-o-linear-gradient(#ddd,#ccc);background-image:linear-gradient(#ddd,#ccc)}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:bold}.ui-body-b .ui-link:hover{color:#2489ce}.ui-body-b .ui-link:active{color:#2489ce}.ui-body-b .ui-link:visited{color:#2489ce}.ui-btn-up-b{border:1px solid #044062;background:#396b9e;font-weight:bold;color:#fff;text-shadow:0 1px 1px #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#5f9cc5),to(#396b9e));background-image:-webkit-linear-gradient(#5f9cc5,#396b9e);background-image:-moz-linear-gradient(#5f9cc5,#396b9e);background-image:-ms-linear-gradient(#5f9cc5,#396b9e);background-image:-o-linear-gradient(#5f9cc5,#396b9e);background-image:linear-gradient(#5f9cc5,#396b9e)}.ui-btn-up-b a.ui-link-inherit{color:#fff}.ui-btn-hover-b{border:1px solid #00415e;background:#4b88b6;font-weight:bold;color:#fff;text-shadow:0 1px 1px #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#4272a4));background-image:-webkit-linear-gradient(#6facd5,#4272a4);background-image:-moz-linear-gradient(#6facd5,#4272a4);background-image:-ms-linear-gradient(#6facd5,#4272a4);background-image:-o-linear-gradient(#6facd5,#4272a4);background-image:linear-gradient(#6facd5,#4272a4)}.ui-btn-hover-b a.ui-link-inherit{color:#fff}.ui-btn-down-b{border:1px solid #225377;background:#4e89c5;font-weight:bold;color:#fff;text-shadow:0 1px 1px #194b7e;background-image:-webkit-gradient(linear,left top,left bottom,from(#295b8e),to(#3e79b5));background-image:-webkit-linear-gradient(#295b8e,#3e79b5);background-image:-moz-linear-gradient(#295b8e,#3e79b5);background-image:-ms-linear-gradient(#295b8e,#3e79b5);background-image:-o-linear-gradient(#295b8e,#3e79b5);background-image:linear-gradient(#295b8e,#3e79b5)}.ui-btn-down-b a.ui-link-inherit{color:#fff}.ui-btn-up-b,.ui-btn-hover-b,.ui-btn-down-b{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-c{border:1px solid #b3b3b3;background:#eee;color:#3e3e3e;font-weight:bold;text-shadow:0 1px 1px #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#ddd));background-image:-webkit-linear-gradient(#f0f0f0,#ddd);background-image:-moz-linear-gradient(#f0f0f0,#ddd);background-image:-ms-linear-gradient(#f0f0f0,#ddd);background-image:-o-linear-gradient(#f0f0f0,#ddd);background-image:linear-gradient(#f0f0f0,#ddd)}.ui-bar-c .ui-link-inherit{color:#3e3e3e}.ui-bar-c .ui-link{color:#7cc4e7;font-weight:bold}.ui-bar-c .ui-link:hover{color:#2489ce}.ui-bar-c .ui-link:active{color:#2489ce}.ui-bar-c .ui-link:visited{color:#2489ce}.ui-bar-c,.ui-bar-c input,.ui-bar-c select,.ui-bar-c textarea,.ui-bar-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c,.ui-overlay-c{border:1px solid #aaa;color:#333;text-shadow:0 1px 0 #fff;background:#f9f9f9;background-image:-webkit-gradient(linear,left top,left bottom,from(#f9f9f9),to(#eee));background-image:-webkit-linear-gradient(#f9f9f9,#eee);background-image:-moz-linear-gradient(#f9f9f9,#eee);background-image:-ms-linear-gradient(#f9f9f9,#eee);background-image:-o-linear-gradient(#f9f9f9,#eee);background-image:linear-gradient(#f9f9f9,#eee)}.ui-overlay-c{background-image:none;border-width:0}.ui-body-c,.ui-body-c input,.ui-body-c select,.ui-body-c textarea,.ui-body-c button{font-family:Helvetica,Arial,sans-serif}.ui-body-c .ui-link-inherit{color:#333}.ui-body-c .ui-link{color:#2489ce;font-weight:bold}.ui-body-c .ui-link:hover{color:#2489ce}.ui-body-c .ui-link:active{color:#2489ce}.ui-body-c .ui-link:visited{color:#2489ce}.ui-btn-up-c{border:1px solid #ccc;background:#eee;font-weight:bold;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f1f1f1));background-image:-webkit-linear-gradient(#fff,#f1f1f1);background-image:-moz-linear-gradient(#fff,#f1f1f1);background-image:-ms-linear-gradient(#fff,#f1f1f1);background-image:-o-linear-gradient(#fff,#f1f1f1);background-image:linear-gradient(#fff,#f1f1f1)}.ui-btn-up-c a.ui-link-inherit{color:#2f3e46}.ui-btn-hover-c{border:1px solid #bbb;background:#dfdfdf;font-weight:bold;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f6f6f6),to(#e0e0e0));background-image:-webkit-linear-gradient(#f9f9f9,#e0e0e0);background-image:-moz-linear-gradient(#f6f6f6,#e0e0e0);background-image:-ms-linear-gradient(#f6f6f6,#e0e0e0);background-image:-o-linear-gradient(#f6f6f6,#e0e0e0);background-image:linear-gradient(#f6f6f6,#e0e0e0)}.ui-btn-hover-c a.ui-link-inherit{color:#2f3e46}.ui-btn-down-c{border:1px solid #bbb;background:#d6d6d6;font-weight:bold;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#d0d0d0),to(#dfdfdf));background-image:-webkit-linear-gradient(#d0d0d0,#dfdfdf);background-image:-moz-linear-gradient(#d0d0d0,#dfdfdf);background-image:-ms-linear-gradient(#d0d0d0,#dfdfdf);background-image:-o-linear-gradient(#d0d0d0,#dfdfdf);background-image:linear-gradient(#d0d0d0,#dfdfdf)}.ui-btn-down-c a.ui-link-inherit{color:#2f3e46}.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-d{border:1px solid #bbb;background:#bbb;color:#333;text-shadow:0 1px 0 #eee;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#bbb));background-image:-webkit-linear-gradient(#ddd,#bbb);background-image:-moz-linear-gradient(#ddd,#bbb);background-image:-ms-linear-gradient(#ddd,#bbb);background-image:-o-linear-gradient(#ddd,#bbb);background-image:linear-gradient(#ddd,#bbb)}.ui-bar-d,.ui-bar-d input,.ui-bar-d select,.ui-bar-d textarea,.ui-bar-d button{font-family:Helvetica,Arial,sans-serif}.ui-bar-d .ui-link-inherit{color:#333}.ui-bar-d .ui-link{color:#2489ce;font-weight:bold}.ui-bar-d .ui-link:hover{color:#2489ce}.ui-bar-d .ui-link:active{color:#2489ce}.ui-bar-d .ui-link:visited{color:#2489ce}.ui-body-d,.ui-overlay-d{border:1px solid #bbb;color:#333;text-shadow:0 1px 0 #fff;background:#fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#fff));background-image:-webkit-linear-gradient(#fff,#fff);background-image:-moz-linear-gradient(#fff,#fff);background-image:-ms-linear-gradient(#fff,#fff);background-image:-o-linear-gradient(#fff,#fff);background-image:linear-gradient(#fff,#fff)}.ui-overlay-d{background-image:none;border-width:0}.ui-body-d,.ui-body-d input,.ui-body-d select,.ui-body-d textarea,.ui-body-d button{font-family:Helvetica,Arial,sans-serif}.ui-body-d .ui-link-inherit{color:#333}.ui-body-d .ui-link{color:#2489ce;font-weight:bold}.ui-body-d .ui-link:hover{color:#2489ce}.ui-body-d .ui-link:active{color:#2489ce}.ui-body-d .ui-link:visited{color:#2489ce}.ui-btn-up-d{border:1px solid #bbb;background:#fff;font-weight:bold;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#f6f6f6));background-image:-webkit-linear-gradient(#fafafa,#f6f6f6);background-image:-moz-linear-gradient(#fafafa,#f6f6f6);background-image:-ms-linear-gradient(#fafafa,#f6f6f6);background-image:-o-linear-gradient(#fafafa,#f6f6f6);background-image:linear-gradient(#fafafa,#f6f6f6)}.ui-btn-up-d a.ui-link-inherit{color:#333}.ui-btn-hover-d{border:1px solid #aaa;background:#eee;font-weight:bold;color:#333;cursor:pointer;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#eee),to(#fff));background-image:-webkit-linear-gradient(#eee,#fff);background-image:-moz-linear-gradient(#eee,#fff);background-image:-ms-linear-gradient(#eee,#fff);background-image:-o-linear-gradient(#eee,#fff);background-image:linear-gradient(#eee,#fff)}.ui-btn-hover-d a.ui-link-inherit{color:#333}.ui-btn-down-d{border:1px solid #aaa;background:#eee;font-weight:bold;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#e5e5e5),to(#f2f2f2));background-image:-webkit-linear-gradient(#e5e5e5,#f2f2f2);background-image:-moz-linear-gradient(#e5e5e5,#f2f2f2);background-image:-ms-linear-gradient(#e5e5e5,#f2f2f2);background-image:-o-linear-gradient(#e5e5e5,#f2f2f2);background-image:linear-gradient(#e5e5e5,#f2f2f2)}.ui-btn-down-d a.ui-link-inherit{color:#333}.ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-e{border:1px solid #f7c942;background:#fadb4e;color:#333;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fceda7),to(#fbef7e));background-image:-webkit-linear-gradient(#fceda7,#fbef7e);background-image:-moz-linear-gradient(#fceda7,#fbef7e);background-image:-ms-linear-gradient(#fceda7,#fbef7e);background-image:-o-linear-gradient(#fceda7,#fbef7e);background-image:linear-gradient(#fceda7,#fbef7e)}.ui-bar-e,.ui-bar-e input,.ui-bar-e select,.ui-bar-e textarea,.ui-bar-e button{font-family:Helvetica,Arial,sans-serif}.ui-bar-e .ui-link-inherit{color:#333}.ui-bar-e .ui-link{color:#2489ce;font-weight:bold}.ui-bar-e .ui-link:hover{color:#2489ce}.ui-bar-e .ui-link:active{color:#2489ce}.ui-bar-e .ui-link:visited{color:#2489ce}.ui-body-e,.ui-overlay-e{border:1px solid #f7c942;color:#222;text-shadow:0 1px 0 #fff;background:#fff9df;background-image:-webkit-gradient(linear,left top,left bottom,from(#fffadf),to(#fff3a5));background-image:-webkit-linear-gradient(#fffadf,#fff3a5);background-image:-moz-linear-gradient(#fffadf,#fff3a5);background-image:-ms-linear-gradient(#fffadf,#fff3a5);background-image:-o-linear-gradient(#fffadf,#fff3a5);background-image:linear-gradient(#fffadf,#fff3a5)}.ui-overlay-e{background-image:none;border-width:0}.ui-body-e,.ui-body-e input,.ui-body-e select,.ui-body-e textarea,.ui-body-e button{font-family:Helvetica,Arial,sans-serif}.ui-body-e .ui-link-inherit{color:#333}.ui-body-e .ui-link{color:#2489ce;font-weight:bold}.ui-body-e .ui-link:hover{color:#2489ce}.ui-body-e .ui-link:active{color:#2489ce}.ui-body-e .ui-link:visited{color:#2489ce}.ui-btn-up-e{border:1px solid #f4c63f;background:#fadb4e;font-weight:bold;color:#222;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#ffefaa),to(#ffe155));background-image:-webkit-linear-gradient(#ffefaa,#ffe155);background-image:-moz-linear-gradient(#ffefaa,#ffe155);background-image:-ms-linear-gradient(#ffefaa,#ffe155);background-image:-o-linear-gradient(#ffefaa,#ffe155);background-image:linear-gradient(#ffefaa,#ffe155)}.ui-btn-up-e a.ui-link-inherit{color:#222}.ui-btn-hover-e{border:1px solid #f2c43d;background:#fbe26f;font-weight:bold;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff5ba),to(#fbdd52));background-image:-webkit-linear-gradient(#fff5ba,#fbdd52);background-image:-moz-linear-gradient(#fff5ba,#fbdd52);background-image:-ms-linear-gradient(#fff5ba,#fbdd52);background-image:-o-linear-gradient(#fff5ba,#fbdd52);background-image:linear-gradient(#fff5ba,#fbdd52)}.ui-btn-hover-e a.ui-link-inherit{color:#333}.ui-btn-down-e{border:1px solid #f2c43d;background:#fceda7;font-weight:bold;color:#111;text-shadow:0 1px 0 #fff;background-image:-webkit-gradient(linear,left top,left bottom,from(#f8d94c),to(#fadb4e));background-image:-webkit-linear-gradient(#f8d94c,#fadb4e);background-image:-moz-linear-gradient(#f8d94c,#fadb4e);background-image:-ms-linear-gradient(#f8d94c,#fadb4e);background-image:-o-linear-gradient(#f8d94c,#fadb4e);background-image:linear-gradient(#f8d94c,#fadb4e)}.ui-btn-down-e a.ui-link-inherit{color:#333}.ui-btn-up-e,.ui-btn-hover-e,.ui-btn-down-e{font-family:Helvetica,Arial,sans-serif;text-decoration:none}a.ui-link-inherit{text-decoration:none!important}.ui-btn-active{border:1px solid #2373a5;background:#5393c5;font-weight:bold;color:#fff;cursor:pointer;text-shadow:0 1px 1px #3373a5;text-decoration:none;background-image:-webkit-gradient(linear,left top,left bottom,from(#5393c5),to(#6facd5));background-image:-webkit-linear-gradient(#5393c5,#6facd5);background-image:-moz-linear-gradient(#5393c5,#6facd5);background-image:-ms-linear-gradient(#5393c5,#6facd5);background-image:-o-linear-gradient(#5393c5,#6facd5);background-image:linear-gradient(#5393c5,#6facd5);font-family:Helvetica,Arial,sans-serif}.ui-btn-active a.ui-link-inherit{color:#fff}.ui-btn-inner{border-top:1px solid #fff;border-color:rgba(255,255,255,.3)}.ui-corner-tl{-moz-border-radius-topleft:.6em;-webkit-border-top-left-radius:.6em;border-top-left-radius:.6em}.ui-corner-tr{-moz-border-radius-topright:.6em;-webkit-border-top-right-radius:.6em;border-top-right-radius:.6em}.ui-corner-bl{-moz-border-radius-bottomleft:.6em;-webkit-border-bottom-left-radius:.6em;border-bottom-left-radius:.6em}.ui-corner-br{-moz-border-radius-bottomright:.6em;-webkit-border-bottom-right-radius:.6em;border-bottom-right-radius:.6em}.ui-corner-top{-moz-border-radius-topleft:.6em;-webkit-border-top-left-radius:.6em;border-top-left-radius:.6em;-moz-border-radius-topright:.6em;-webkit-border-top-right-radius:.6em;border-top-right-radius:.6em}.ui-corner-bottom{-moz-border-radius-bottomleft:.6em;-webkit-border-bottom-left-radius:.6em;border-bottom-left-radius:.6em;-moz-border-radius-bottomright:.6em;-webkit-border-bottom-right-radius:.6em;border-bottom-right-radius:.6em}.ui-corner-right{-moz-border-radius-topright:.6em;-webkit-border-top-right-radius:.6em;border-top-right-radius:.6em;-moz-border-radius-bottomright:.6em;-webkit-border-bottom-right-radius:.6em;border-bottom-right-radius:.6em}.ui-corner-left{-moz-border-radius-topleft:.6em;-webkit-border-top-left-radius:.6em;border-top-left-radius:.6em;-moz-border-radius-bottomleft:.6em;-webkit-border-bottom-left-radius:.6em;border-bottom-left-radius:.6em}.ui-corner-all{-moz-border-radius:.6em;-webkit-border-radius:.6em;border-radius:.6em}.ui-corner-none{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.ui-br{border-bottom:#828282;border-bottom:rgba(130,130,130,.3);border-bottom-width:1px;border-bottom-style:solid}.ui-disabled{opacity:.3}.ui-disabled,.ui-disabled a{cursor:default!important;pointer-events:none}.ui-disabled .ui-btn-text{-ms-filter:"alpha(opacity=30)";filter:alpha(opacity=30);zoom:1}.ui-icon,.ui-icon-searchfield:after{background:#666;background:rgba(0,0,0,.4);background-image:url(images/icons-18-white.png);background-repeat:no-repeat;-moz-border-radius:9px;-webkit-border-radius:9px;border-radius:9px}.ui-icon-alt{background:#fff;background:rgba(255,255,255,.3);background-image:url(images/icons-18-black.png);background-repeat:no-repeat}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-resolution:240dpi){.ui-icon-plus,.ui-icon-minus,.ui-icon-delete,.ui-icon-arrow-r,.ui-icon-arrow-l,.ui-icon-arrow-u,.ui-icon-arrow-d,.ui-icon-check,.ui-icon-gear,.ui-icon-refresh,.ui-icon-forward,.ui-icon-back,.ui-icon-grid,.ui-icon-star,.ui-icon-alert,.ui-icon-info,.ui-icon-home,.ui-icon-search,.ui-icon-searchfield:after,.ui-icon-checkbox-off,.ui-icon-checkbox-on,.ui-icon-radio-off,.ui-icon-radio-on{background-image:url(images/icons-36-white.png);-moz-background-size:776px 18px;-o-background-size:776px 18px;-webkit-background-size:776px 18px;background-size:776px 18px}.ui-icon-alt{background-image:url(images/icons-36-black.png)}}.ui-icon-plus{background-position:-0 50%}.ui-icon-minus{background-position:-36px 50%}.ui-icon-delete{background-position:-72px 50%}.ui-icon-arrow-r{background-position:-108px 50%}.ui-icon-arrow-l{background-position:-144px 50%}.ui-icon-arrow-u{background-position:-180px 50%}.ui-icon-arrow-d{background-position:-216px 50%}.ui-icon-check{background-position:-252px 50%}.ui-icon-gear{background-position:-288px 50%}.ui-icon-refresh{background-position:-324px 50%}.ui-icon-forward{background-position:-360px 50%}.ui-icon-back{background-position:-396px 50%}.ui-icon-grid{background-position:-432px 50%}.ui-icon-star{background-position:-468px 50%}.ui-icon-alert{background-position:-504px 50%}.ui-icon-info{background-position:-540px 50%}.ui-icon-home{background-position:-576px 50%}.ui-icon-search,.ui-icon-searchfield:after{background-position:-612px 50%}.ui-icon-checkbox-off{background-position:-684px 50%}.ui-icon-checkbox-on{background-position:-648px 50%}.ui-icon-radio-off{background-position:-756px 50%}.ui-icon-radio-on{background-position:-720px 50%}.ui-checkbox .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.ui-icon-checkbox-off,.ui-icon-radio-off{background-color:transparent}.ui-checkbox-on .ui-icon,.ui-radio-on .ui-icon{background-color:#4596ce}.ui-icon-loading{background:url(images/ajax-loader.gif);background-size:46px 46px}.ui-btn-corner-tl{-moz-border-radius-topleft:1em;-webkit-border-top-left-radius:1em;border-top-left-radius:1em}.ui-btn-corner-tr{-moz-border-radius-topright:1em;-webkit-border-top-right-radius:1em;border-top-right-radius:1em}.ui-btn-corner-bl{-moz-border-radius-bottomleft:1em;-webkit-border-bottom-left-radius:1em;border-bottom-left-radius:1em}.ui-btn-corner-br{-moz-border-radius-bottomright:1em;-webkit-border-bottom-right-radius:1em;border-bottom-right-radius:1em}.ui-btn-corner-top{-moz-border-radius-topleft:1em;-webkit-border-top-left-radius:1em;border-top-left-radius:1em;-moz-border-radius-topright:1em;-webkit-border-top-right-radius:1em;border-top-right-radius:1em}.ui-btn-corner-bottom{-moz-border-radius-bottomleft:1em;-webkit-border-bottom-left-radius:1em;border-bottom-left-radius:1em;-moz-border-radius-bottomright:1em;-webkit-border-bottom-right-radius:1em;border-bottom-right-radius:1em}.ui-btn-corner-right{-moz-border-radius-topright:1em;-webkit-border-top-right-radius:1em;border-top-right-radius:1em;-moz-border-radius-bottomright:1em;-webkit-border-bottom-right-radius:1em;border-bottom-right-radius:1em}.ui-btn-corner-left{-moz-border-radius-topleft:1em;-webkit-border-top-left-radius:1em;border-top-left-radius:1em;-moz-border-radius-bottomleft:1em;-webkit-border-bottom-left-radius:1em;border-bottom-left-radius:1em}.ui-btn-corner-all{-moz-border-radius:1em;-webkit-border-radius:1em;border-radius:1em}.ui-corner-tl,.ui-corner-tr,.ui-corner-bl,.ui-corner-br,.ui-corner-top,.ui-corner-bottom,.ui-corner-right,.ui-corner-left,.ui-corner-all,.ui-btn-corner-tl,.ui-btn-corner-tr,.ui-btn-corner-bl,.ui-btn-corner-br,.ui-btn-corner-top,.ui-btn-corner-bottom,.ui-btn-corner-right,.ui-btn-corner-left,.ui-btn-corner-all{-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.ui-overlay{background:#666;opacity:.5;filter:Alpha(Opacity=50);position:absolute;width:100%;height:100%}.ui-overlay-shadow{-moz-box-shadow:0 0 12px rgba(0,0,0,.6);-webkit-box-shadow:0 0 12px rgba(0,0,0,.6);box-shadow:0 0 12px rgba(0,0,0,.6)}.ui-shadow{-moz-box-shadow:0 1px 4px rgba(0,0,0,.3);-webkit-box-shadow:0 1px 4px rgba(0,0,0,.3);box-shadow:0 1px 4px rgba(0,0,0,.3)}.ui-bar-a .ui-shadow,.ui-bar-b .ui-shadow,.ui-bar-c .ui-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.ui-shadow-inset{-moz-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 4px rgba(0,0,0,.2);box-shadow:inset 0 1px 4px rgba(0,0,0,.2)}.ui-icon-shadow{-moz-box-shadow:0 1px 0 rgba(255,255,255,.4);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.4);box-shadow:0 1px 0 rgba(255,255,255,.4)}.ui-btn:focus{outline:0}.ui-focus,.ui-btn:focus{-moz-box-shadow:0 0 12px #387bbe;-webkit-box-shadow:0 0 12px #387bbe;box-shadow:0 0 12px #387bbe}.ui-mobile-nosupport-boxshadow *{-moz-box-shadow:none!important;-webkit-box-shadow:none!important;box-shadow:none!important}.ui-mobile-nosupport-boxshadow .ui-focus,.ui-mobile-nosupport-boxshadow .ui-btn:focus{outline-width:1px;outline-style:dotted}.ui-mobile,.ui-mobile body{height:99.9%}.ui-mobile fieldset,.ui-page{padding:0;margin:0}.ui-mobile a img,.ui-mobile fieldset{border-width:0}.ui-mobile-viewport{margin:0;overflow-x:visible;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}body.ui-mobile-viewport,div.ui-mobile-viewport{overflow-x:hidden}.ui-mobile [data-role=page],.ui-mobile [data-role=dialog],.ui-page{top:0;left:0;width:100%;min-height:100%;position:absolute;display:none;border:0}.ui-mobile .ui-page-active{display:block;overflow:visible}.ui-page{outline:0}@media screen and (orientation:portrait){.ui-mobile,.ui-mobile .ui-page{min-height:420px}}@media screen and (orientation:landscape){.ui-mobile,.ui-mobile .ui-page{min-height:300px}}.ui-loading .ui-loader{display:block}.ui-loader{display:none;z-index:9999999;position:fixed;top:50%;box-shadow:0 1px 1px -1px #fff;left:50%;border:0}.ui-loader-default{background:0;opacity:.18;width:46px;height:46px;margin-left:-23px;margin-top:-23px}.ui-loader-verbose{width:200px;opacity:.88;height:auto;margin-left:-110px;margin-top:-43px;padding:10px}.ui-loader-default h1{font-size:0;width:0;height:0;overflow:hidden}.ui-loader-verbose h1{font-size:16px;margin:0;text-align:center}.ui-loader .ui-icon{background-color:#000;display:block;margin:0;width:44px;height:44px;padding:1px;-webkit-border-radius:36px;-moz-border-radius:36px;border-radius:36px}.ui-loader-verbose .ui-icon{margin:0 auto 10px;opacity:.75}.ui-loader-textonly{padding:15px;margin-left:-115px}.ui-loader-textonly .ui-icon{display:none}.ui-loader-fakefix{position:absolute}.ui-mobile-rendering>*{visibility:hidden}.ui-bar,.ui-body{position:relative;padding:.4em 15px;overflow:hidden;display:block;clear:both}.ui-bar{font-size:16px;margin:0}.ui-bar h1,.ui-bar h2,.ui-bar h3,.ui-bar h4,.ui-bar h5,.ui-bar h6{margin:0;padding:0;font-size:16px;display:inline-block}.ui-header,.ui-footer{position:relative;border-left-width:0;border-right-width:0}.ui-header .ui-btn-left,.ui-header .ui-btn-right,.ui-footer .ui-btn-left,.ui-footer .ui-btn-right{position:absolute;top:3px}.ui-header .ui-btn-left,.ui-footer .ui-btn-left{left:5px}.ui-header .ui-btn-right,.ui-footer .ui-btn-right{right:5px}.ui-footer .ui-btn-icon-notext,.ui-header .ui-btn-icon-notext{top:6px}.ui-header .ui-title,.ui-footer .ui-title{min-height:1.1em;text-align:center;font-size:16px;display:block;margin:.6em 30% .8em;padding:0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;outline:0!important}.ui-footer .ui-title{margin:.6em 15px .8em}.ui-content{border-width:0;overflow:visible;overflow-x:hidden;padding:15px}.ui-icon{width:18px;height:18px}.ui-nojs{position:absolute;left:-9999px}.ui-hide-label label,.ui-hidden-accessible{position:absolute!important;left:-9999px;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .ui-page{width:100%;height:100%;overflow:hidden}.in{-webkit-animation-timing-function:ease-out;-webkit-animation-duration:350ms;-moz-animation-timing-function:ease-out;-moz-animation-duration:350ms}.out{-webkit-animation-timing-function:ease-in;-webkit-animation-duration:225ms;-moz-animation-timing-function:ease-in;-moz-animation-duration:225}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@-moz-keyframes fadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeout{from{opacity:1}to{opacity:0}}@-moz-keyframes fadeout{from{opacity:1}to{opacity:0}}.fade.out{opacity:0;-webkit-animation-duration:125ms;-webkit-animation-name:fadeout;-moz-animation-duration:125ms;-moz-animation-name:fadeout}.fade.in{opacity:1;-webkit-animation-duration:225ms;-webkit-animation-name:fadein;-moz-animation-duration:225ms;-moz-animation-name:fadein}.pop{-webkit-transform-origin:50% 50%;-moz-transform-origin:50% 50%}.pop.in{-webkit-transform:scale(1);-moz-transform:scale(1);opacity:1;-webkit-animation-name:popin;-moz-animation-name:popin;-webkit-animation-duration:350ms;-moz-animation-duration:350ms}.pop.out{-webkit-animation-name:fadeout;-moz-animation-name:fadeout;opacity:0;-webkit-animation-duration:100ms;-moz-animation-duration:100ms}.pop.in.reverse{-webkit-animation-name:fadein;-moz-animation-name:fadein}.pop.out.reverse{-webkit-transform:scale(.8);-moz-transform:scale(.8);-webkit-animation-name:popout;-moz-animation-name:popout}@-webkit-keyframes popin{from{-webkit-transform:scale(.8);opacity:0}to{-webkit-transform:scale(1);opacity:1}}@-moz-keyframes popin{from{-moz-transform:scale(.8);opacity:0}to{-moz-transform:scale(1);opacity:1}}@-webkit-keyframes popout{from{-webkit-transform:scale(1);opacity:1}to{-webkit-transform:scale(.8);opacity:0}}@-moz-keyframes popout{from{-moz-transform:scale(1);opacity:1}to{-moz-transform:scale(.8);opacity:0}}@-webkit-keyframes slideinfromright{from{-webkit-transform:translateX(100%)}to{-webkit-transform:translateX(0)}}@-moz-keyframes slideinfromright{from{-moz-transform:translateX(100%)}to{-moz-transform:translateX(0)}}@-webkit-keyframes slideinfromleft{from{-webkit-transform:translateX(-100%)}to{-webkit-transform:translateX(0)}}@-moz-keyframes slideinfromleft{from{-moz-transform:translateX(-100%)}to{-moz-transform:translateX(0)}}@-webkit-keyframes slideouttoleft{from{-webkit-transform:translateX(0)}to{-webkit-transform:translateX(-100%)}}@-moz-keyframes slideouttoleft{from{-moz-transform:translateX(0)}to{-moz-transform:translateX(-100%)}}@-webkit-keyframes slideouttoright{from{-webkit-transform:translateX(0)}to{-webkit-transform:translateX(100%)}}@-moz-keyframes slideouttoright{from{-moz-transform:translateX(0)}to{-moz-transform:translateX(100%)}}.slide.out,.slide.in{-webkit-animation-timing-function:ease-out;-webkit-animation-duration:350ms;-moz-animation-timing-function:ease-out;-moz-animation-duration:350ms}.slide.out{-webkit-transform:translateX(-100%);-webkit-animation-name:slideouttoleft;-moz-transform:translateX(-100%);-moz-animation-name:slideouttoleft}.slide.in{-webkit-transform:translateX(0);-webkit-animation-name:slideinfromright;-moz-transform:translateX(0);-moz-animation-name:slideinfromright}.slide.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:slideouttoright;-moz-transform:translateX(100%);-moz-animation-name:slideouttoright}.slide.in.reverse{-webkit-transform:translateX(0);-webkit-animation-name:slideinfromleft;-moz-transform:translateX(0);-moz-animation-name:slideinfromleft}.slidefade.out{-webkit-transform:translateX(-100%);-webkit-animation-name:slideouttoleft;-moz-transform:translateX(-100%);-moz-animation-name:slideouttoleft;-webkit-animation-duration:225ms;-moz-animation-duration:225ms}.slidefade.in{-webkit-transform:translateX(0);-webkit-animation-name:fadein;-moz-transform:translateX(0);-moz-animation-name:fadein;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}.slidefade.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:slideouttoright;-moz-transform:translateX(100%);-moz-animation-name:slideouttoright;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}.slidefade.in.reverse{-webkit-transform:translateX(0);-webkit-animation-name:fadein;-moz-transform:translateX(0);-moz-animation-name:fadein;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}.slidedown.out{-webkit-animation-name:fadeout;-moz-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-duration:100ms}.slidedown.in{-webkit-transform:translateY(0);-webkit-animation-name:slideinfromtop;-moz-transform:translateY(0);-moz-animation-name:slideinfromtop;-webkit-animation-duration:250ms;-moz-animation-duration:250ms}.slidedown.in.reverse{-webkit-animation-name:fadein;-moz-animation-name:fadein;-webkit-animation-duration:150ms;-moz-animation-duration:150ms}.slidedown.out.reverse{-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-webkit-animation-name:slideouttotop;-moz-animation-name:slideouttotop;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}@-webkit-keyframes slideinfromtop{from{-webkit-transform:translateY(-100%)}to{-webkit-transform:translateY(0)}}@-moz-keyframes slideinfromtop{from{-moz-transform:translateY(-100%)}to{-moz-transform:translateY(0)}}@-webkit-keyframes slideouttotop{from{-webkit-transform:translateY(0)}to{-webkit-transform:translateY(-100%)}}@-moz-keyframes slideouttotop{from{-moz-transform:translateY(0)}to{-moz-transform:translateY(-100%)}}.slideup.out{-webkit-animation-name:fadeout;-moz-animation-name:fadeout;-webkit-animation-duration:100ms;-moz-animation-duration:100ms}.slideup.in{-webkit-transform:translateY(0);-webkit-animation-name:slideinfrombottom;-moz-transform:translateY(0);-moz-animation-name:slideinfrombottom;-webkit-animation-duration:250ms;-moz-animation-duration:250ms}.slideup.in.reverse{-webkit-animation-name:fadein;-moz-animation-name:fadein;-webkit-animation-duration:150ms;-moz-animation-duration:150ms}.slideup.out.reverse{-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-webkit-animation-name:slideouttobottom;-moz-animation-name:slideouttobottom;-webkit-animation-duration:200ms;-moz-animation-duration:200ms}@-webkit-keyframes slideinfrombottom{from{-webkit-transform:translateY(100%)}to{-webkit-transform:translateY(0)}}@-moz-keyframes slideinfrombottom{from{-moz-transform:translateY(100%)}to{-moz-transform:translateY(0)}}@-webkit-keyframes slideouttobottom{from{-webkit-transform:translateY(0)}to{-webkit-transform:translateY(100%)}}@-moz-keyframes slideouttobottom{from{-moz-transform:translateY(0)}to{-moz-transform:translateY(100%)}}.viewport-flip{-webkit-perspective:1000;-moz-perspective:1000;position:absolute}.flip{-webkit-backface-visibility:hidden;-webkit-transform:translateX(0);-moz-backface-visibility:hidden;-moz-transform:translateX(0)}.flip.out{-webkit-transform:rotateY(-90deg) scale(.9);-webkit-animation-name:flipouttoleft;-webkit-animation-duration:175ms;-moz-transform:rotateY(-90deg) scale(.9);-moz-animation-name:flipouttoleft;-moz-animation-duration:175ms}.flip.in{-webkit-animation-name:flipintoright;-webkit-animation-duration:225ms;-moz-animation-name:flipintoright;-moz-animation-duration:225ms}.flip.out.reverse{-webkit-transform:rotateY(90deg) scale(.9);-webkit-animation-name:flipouttoright;-moz-transform:rotateY(90deg) scale(.9);-moz-animation-name:flipouttoright}.flip.in.reverse{-webkit-animation-name:flipintoleft;-moz-animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(.9)}}@-moz-keyframes flipouttoleft{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(-90deg) scale(.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(.9)}}@-moz-keyframes flipouttoright{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(90deg) scale(.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoleft{from{-moz-transform:rotateY(-90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoright{from{-moz-transform:rotateY(90deg) scale(.9)}to{-moz-transform:rotateY(0)}}.viewport-turn{-webkit-perspective:1000;-moz-perspective:1000;position:absolute}.turn{-webkit-backface-visibility:hidden;-webkit-transform:translateX(0);-webkit-transform-origin:0 0;-moz-backface-visibility:hidden;-moz-transform:translateX(0);-moz-transform-origin:0 0}.turn.out{-webkit-transform:rotateY(-90deg) scale(.9);-webkit-animation-name:flipouttoleft;-moz-transform:rotateY(-90deg) scale(.9);-moz-animation-name:flipouttoleft;-webkit-animation-duration:125ms;-moz-animation-duration:125ms}.turn.in{-webkit-animation-name:flipintoright;-moz-animation-name:flipintoright;-webkit-animation-duration:250ms;-moz-animation-duration:250ms}.turn.out.reverse{-webkit-transform:rotateY(90deg) scale(.9);-webkit-animation-name:flipouttoright;-moz-transform:rotateY(90deg) scale(.9);-moz-animation-name:flipouttoright}.turn.in.reverse{-webkit-animation-name:flipintoleft;-moz-animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(.9)}}@-moz-keyframes flipouttoleft{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(-90deg) scale(.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(.9)}}@-moz-keyframes flipouttoright{from{-moz-transform:rotateY(0)}to{-moz-transform:rotateY(90deg) scale(.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoleft{from{-moz-transform:rotateY(-90deg) scale(.9)}to{-moz-transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(.9)}to{-webkit-transform:rotateY(0)}}@-moz-keyframes flipintoright{from{-moz-transform:rotateY(90deg) scale(.9)}to{-moz-transform:rotateY(0)}}.flow{-webkit-transform-origin:50% 30%;-moz-transform-origin:50% 30%;-webkit-box-shadow:0 0 20px rgba(0,0,0,.4);-moz-box-shadow:0 0 20px rgba(0,0,0,.4)}.ui-dialog.flow{-webkit-transform-origin:none;-moz-transform-origin:none;-webkit-box-shadow:none;-moz-box-shadow:none}.flow.out{-webkit-transform:translateX(-100%) scale(.7);-webkit-animation-name:flowouttoleft;-webkit-animation-timing-function:ease;-webkit-animation-duration:350ms;-moz-transform:translateX(-100%) scale(.7);-moz-animation-name:flowouttoleft;-moz-animation-timing-function:ease;-moz-animation-duration:350ms}.flow.in{-webkit-transform:translateX(0) scale(1);-webkit-animation-name:flowinfromright;-webkit-animation-timing-function:ease;-webkit-animation-duration:350ms;-moz-transform:translateX(0) scale(1);-moz-animation-name:flowinfromright;-moz-animation-timing-function:ease;-moz-animation-duration:350ms}.flow.out.reverse{-webkit-transform:translateX(100%);-webkit-animation-name:flowouttoright;-moz-transform:translateX(100%);-moz-animation-name:flowouttoright}.flow.in.reverse{-webkit-animation-name:flowinfromleft;-moz-animation-name:flowinfromleft}@-webkit-keyframes flowouttoleft{0%{-webkit-transform:translateX(0) scale(1)}60%,70%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(-100%) scale(.7)}}@-moz-keyframes flowouttoleft{0%{-moz-transform:translateX(0) scale(1)}60%,70%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(-100%) scale(.7)}}@-webkit-keyframes flowouttoright{0%{-webkit-transform:translateX(0) scale(1)}60%,70%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(100%) scale(.7)}}@-moz-keyframes flowouttoright{0%{-moz-transform:translateX(0) scale(1)}60%,70%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(100%) scale(.7)}}@-webkit-keyframes flowinfromleft{0%{-webkit-transform:translateX(-100%) scale(.7)}30%,40%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(0) scale(1)}}@-moz-keyframes flowinfromleft{0%{-moz-transform:translateX(-100%) scale(.7)}30%,40%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(0) scale(1)}}@-webkit-keyframes flowinfromright{0%{-webkit-transform:translateX(100%) scale(.7)}30%,40%{-webkit-transform:translateX(0) scale(.7)}100%{-webkit-transform:translateX(0) scale(1)}}@-moz-keyframes flowinfromright{0%{-moz-transform:translateX(100%) scale(.7)}30%,40%{-moz-transform:translateX(0) scale(.7)}100%{-moz-transform:translateX(0) scale(1)}}.ui-grid-a,.ui-grid-b,.ui-grid-c,.ui-grid-d{overflow:hidden}.ui-block-a,.ui-block-b,.ui-block-c,.ui-block-d,.ui-block-e{margin:0;padding:0;border:0;float:left;min-height:1px}.ui-grid-solo .ui-block-a{width:100%;float:none}.ui-grid-a .ui-block-a,.ui-grid-a .ui-block-b{width:50%}.ui-grid-a .ui-block-a{clear:left}.ui-grid-b .ui-block-a,.ui-grid-b .ui-block-b,.ui-grid-b .ui-block-c{width:33.333%}.ui-grid-b .ui-block-a{clear:left}.ui-grid-c .ui-block-a,.ui-grid-c .ui-block-b,.ui-grid-c .ui-block-c,.ui-grid-c .ui-block-d{width:25%}.ui-grid-c .ui-block-a{clear:left}.ui-grid-d .ui-block-a,.ui-grid-d .ui-block-b,.ui-grid-d .ui-block-c,.ui-grid-d .ui-block-d,.ui-grid-d .ui-block-e{width:20%}.ui-grid-d .ui-block-a{clear:left}.ui-header-fixed,.ui-footer-fixed{left:0;right:0;width:100%;position:fixed;z-index:1000}.ui-header-fixed{top:0}.ui-footer-fixed{bottom:0}.ui-header-fullscreen,.ui-footer-fullscreen{opacity:.9}.ui-page-header-fixed{padding-top:2.5em}.ui-page-footer-fixed{padding-bottom:3em}.ui-page-header-fullscreen .ui-content,.ui-page-footer-fullscreen .ui-content{padding:0}.ui-fixed-hidden{position:absolute}.ui-page-header-fullscreen .ui-fixed-hidden,.ui-page-footer-fullscreen .ui-fixed-hidden{left:-99999em}.ui-header-fixed .ui-btn,.ui-footer-fixed .ui-btn{z-index:10}.ui-navbar{overflow:hidden}.ui-navbar ul,.ui-navbar-expanded ul{list-style:none;padding:0;margin:0;position:relative;display:block;border:0}.ui-navbar-collapsed ul{float:left;width:75%;margin-right:-2px}.ui-navbar-collapsed .ui-navbar-toggle{float:left;width:25%}.ui-navbar li.ui-navbar-truncate{position:absolute;left:-9999px;top:-9999px}.ui-navbar li .ui-btn,.ui-navbar .ui-navbar-toggle .ui-btn{display:block;font-size:12px;text-align:center;margin:0;border-right-width:0;max-width:100%}.ui-navbar li .ui-btn{margin-right:-1px}.ui-navbar li .ui-btn:last-child{margin-right:0}.ui-header .ui-navbar li .ui-btn,.ui-header .ui-navbar .ui-navbar-toggle .ui-btn,.ui-footer .ui-navbar li .ui-btn,.ui-footer .ui-navbar .ui-navbar-toggle .ui-btn{border-top-width:0;border-bottom-width:0}.ui-navbar .ui-btn-inner{padding-left:2px;padding-right:2px}.ui-navbar-noicons li .ui-btn .ui-btn-inner,.ui-navbar-noicons .ui-navbar-toggle .ui-btn-inner{padding-top:.8em;padding-bottom:.9em}.ui-navbar-expanded .ui-btn{margin:0;font-size:14px}.ui-navbar-expanded .ui-btn-inner{padding-left:5px;padding-right:5px}.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner{padding:45px 5px 15px;text-align:center}.ui-navbar-expanded .ui-btn-icon-top .ui-icon{top:15px}.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner{padding:15px 5px 45px;text-align:center}.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon{bottom:15px}.ui-navbar-expanded li .ui-btn .ui-btn-inner{min-height:2.5em}.ui-navbar-expanded .ui-navbar-noicons .ui-btn .ui-btn-inner{padding-top:1.8em;padding-bottom:1.9em}.ui-btn{display:block;text-align:center;cursor:pointer;position:relative;margin:.5em 5px;padding:0}.ui-mini{margin:.25em 5px}.ui-btn-inner{padding:.6em 20px;min-width:.75em;display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;position:relative;zoom:1}.ui-btn input,.ui-btn button{z-index:2}.ui-btn-left,.ui-btn-right,.ui-btn-inline{display:inline-block}.ui-btn-block{display:block}.ui-header .ui-btn,.ui-footer .ui-btn{display:inline-block;margin:0}.ui-header .ui-btn-inner,.ui-footer .ui-btn-inner,.ui-mini .ui-btn-inner{font-size:12.5px;padding:.55em 11px .5em}.ui-header .ui-fullsize .ui-btn-inner,.ui-footer .ui-fullsize .ui-btn-inner{font-size:16px;padding:.6em 25px}.ui-btn-icon-notext{width:24px;height:24px}.ui-btn-icon-notext .ui-btn-inner{padding:0;height:100%}.ui-btn-icon-notext .ui-btn-inner .ui-icon{margin:2px 1px 2px 3px}.ui-btn-text{position:relative;z-index:1;width:100%}.ui-btn-icon-notext .ui-btn-text{position:absolute;left:-9999px}.ui-btn-icon-left .ui-btn-inner{padding-left:40px}.ui-btn-icon-right .ui-btn-inner{padding-right:40px}.ui-btn-icon-top .ui-btn-inner{padding-top:40px}.ui-btn-icon-bottom .ui-btn-inner{padding-bottom:40px}.ui-header .ui-btn-icon-left .ui-btn-inner,.ui-footer .ui-btn-icon-left .ui-btn-inner,.ui-mini .ui-btn-icon-left .ui-btn-inner{padding-left:30px}.ui-header .ui-btn-icon-right .ui-btn-inner,.ui-footer .ui-btn-icon-right .ui-btn-inner,.ui-mini .ui-btn-icon-right .ui-btn-inner{padding-right:30px}.ui-header .ui-btn-icon-top .ui-btn-inner,.ui-footer .ui-btn-icon-top .ui-btn-inner,.ui-mini .ui-btn-icon-top .ui-btn-inner{padding:30px 3px .5em 3px}.ui-header .ui-btn-icon-bottom .ui-btn-inner,.ui-footer .ui-btn-icon-bottom .ui-btn-inner,.ui-mini .ui-btn-icon-bottom .ui-btn-inner{padding:.55em 3px 30px 3px}.ui-btn-icon-notext .ui-icon{display:block;z-index:0}.ui-btn-icon-left .ui-btn-inner .ui-icon,.ui-btn-icon-right .ui-btn-inner .ui-icon{position:absolute;top:50%;margin-top:-9px}.ui-btn-icon-top .ui-btn-inner .ui-icon,.ui-btn-icon-bottom .ui-btn-inner .ui-icon{position:absolute;left:50%;margin-left:-9px}.ui-btn-icon-left .ui-icon{left:10px}.ui-btn-icon-right .ui-icon{right:10px}.ui-btn-icon-top .ui-icon{top:10px}.ui-btn-icon-bottom .ui-icon{top:auto;bottom:10px}.ui-header .ui-btn-icon-left .ui-icon,.ui-footer .ui-btn-icon-left .ui-icon,.ui-mini.ui-btn-icon-left .ui-icon,.ui-mini .ui-btn-icon-left .ui-icon{left:5px}.ui-header .ui-btn-icon-right .ui-icon,.ui-footer .ui-btn-icon-right .ui-icon,.ui-mini.ui-btn-icon-right .ui-icon,.ui-mini .ui-btn-icon-right .ui-icon{right:5px}.ui-header .ui-btn-icon-top .ui-icon,.ui-footer .ui-btn-icon-top .ui-icon,.ui-mini.ui-btn-icon-top .ui-icon,.ui-mini .ui-btn-icon-top .ui-icon{top:5px}.ui-header .ui-btn-icon-bottom .ui-icon,.ui-footer .ui-btn-icon-bottom .ui-icon,.ui-mini.ui-btn-icon-bottom .ui-icon,.ui-mini .ui-btn-icon-bottom .ui-icon{bottom:5px}.ui-btn-hidden{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-appearance:button;opacity:.1;cursor:pointer;background:#fff;background:rgba(255,255,255,0);filter:Alpha(Opacity=.0001);font-size:1px;border:0;text-indent:-9999px}.ui-collapsible{margin:.5em 0}.ui-collapsible-heading{font-size:16px;display:block;margin:0 -8px;padding:0;border-width:0 0 1px 0;position:relative}.ui-collapsible-heading a{text-align:left;margin:0}.ui-collapsible-heading .ui-btn-inner,.ui-collapsible-heading .ui-btn-icon-left .ui-btn-inner{padding-left:40px}.ui-collapsible-heading .ui-btn-icon-right .ui-btn-inner{padding-left:12px;padding-right:40px}.ui-collapsible-heading .ui-btn-icon-top .ui-btn-inner,.ui-collapsible-heading .ui-btn-icon-bottom .ui-btn-inner{padding-right:40px;text-align:center}.ui-collapsible-heading a span.ui-btn{position:absolute;left:6px;top:50%;margin:-12px 0 0 0;width:20px;height:20px;padding:1px 0 1px 2px;text-indent:-9999px}.ui-collapsible-heading a span.ui-btn .ui-btn-inner{padding:10px 0}.ui-collapsible-heading a span.ui-btn .ui-icon{left:0;margin-top:-10px}.ui-collapsible-heading-status{position:absolute;top:-9999px;left:0}.ui-collapsible-content{display:block;margin:0 -8px;padding:10px 16px;border-top:0;background-image:none;font-weight:normal}.ui-collapsible-content-collapsed{display:none}.ui-collapsible-set{margin:.5em 0}.ui-collapsible-set .ui-collapsible{margin:-1px 0 0}.ui-controlgroup,fieldset.ui-controlgroup{padding:0;margin:0 0 .5em;zoom:1}.ui-bar .ui-controlgroup{margin:0 .3em}.ui-controlgroup-label{font-size:16px;line-height:1.4;font-weight:normal;margin:0 0 .4em}.ui-controlgroup-controls{display:block;width:100%}.ui-controlgroup li{list-style:none}.ui-controlgroup-vertical .ui-btn,.ui-controlgroup-vertical .ui-checkbox,.ui-controlgroup-vertical .ui-radio{margin:0;border-bottom-width:0}.ui-controlgroup-controls label.ui-select{position:absolute;left:-9999px}.ui-controlgroup-vertical .ui-controlgroup-last{border-bottom-width:1px}.ui-controlgroup-horizontal{padding:0}.ui-controlgroup-horizontal .ui-btn-inner{text-align:center}.ui-controlgroup-horizontal .ui-btn,.ui-controlgroup-horizontal .ui-select{display:inline-block;margin:0 -6px 0 0}.ui-controlgroup-horizontal .ui-checkbox,.ui-controlgroup-horizontal .ui-radio{float:left;clear:none;margin:0 -1px 0 0}.ui-controlgroup-horizontal .ui-checkbox .ui-btn,.ui-controlgroup-horizontal .ui-radio .ui-btn,.ui-controlgroup-horizontal .ui-checkbox:last-child,.ui-controlgroup-horizontal .ui-radio:last-child{margin-right:0}.ui-controlgroup-horizontal .ui-controlgroup-last{margin-right:0}.ui-controlgroup .ui-checkbox label,.ui-controlgroup .ui-radio label{font-size:16px}@media all and (min-width:450px){.ui-field-contain .ui-controlgroup-label{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-controlgroup-controls{width:60%;display:inline-block}.ui-field-contain .ui-controlgroup .ui-select{width:100%}.ui-field-contain .ui-controlgroup-horizontal .ui-select{width:auto}}.ui-dialog{background:none!important}.ui-dialog-contain{width:92.5%;max-width:500px;margin:10% auto 15px auto;padding:0}.ui-dialog .ui-header{margin-top:15%;border:0;overflow:hidden}.ui-dialog .ui-header,.ui-dialog .ui-content,.ui-dialog .ui-footer{display:block;position:relative;width:auto}.ui-dialog .ui-header,.ui-dialog .ui-footer{z-index:10;padding:0}.ui-dialog .ui-footer{padding:0 15px}.ui-dialog .ui-content{padding:15px}.ui-dialog{margin-top:-15px}.ui-checkbox,.ui-radio{position:relative;clear:both;margin:.2em 0 .5em;z-index:1}.ui-checkbox .ui-btn,.ui-radio .ui-btn{margin:0;text-align:left;z-index:2}.ui-checkbox .ui-btn-inner,.ui-radio .ui-btn-inner{white-space:normal}.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner{padding-left:45px}.ui-checkbox .ui-mini.ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-mini.ui-btn-icon-left .ui-btn-inner{padding-left:36px}.ui-checkbox .ui-btn-icon-right .ui-btn-inner,.ui-radio .ui-btn-icon-right .ui-btn-inner{padding-right:45px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-btn-inner,.ui-radio .ui-mini.ui-btn-icon-right .ui-btn-inner{padding-right:36px}.ui-checkbox .ui-btn-icon-top .ui-btn-inner,.ui-radio .ui-btn-icon-top .ui-btn-inner{padding-right:0;padding-left:0;text-align:center}.ui-checkbox .ui-btn-icon-bottom .ui-btn-inner,.ui-radio .ui-btn-icon-bottom .ui-btn-inner{padding-right:0;padding-left:0;text-align:center}.ui-checkbox .ui-icon,.ui-radio .ui-icon{top:1.1em}.ui-checkbox .ui-btn-icon-left .ui-icon,.ui-radio .ui-btn-icon-left .ui-icon{left:15px}.ui-checkbox .ui-mini.ui-btn-icon-left .ui-icon,.ui-radio .ui-mini.ui-btn-icon-left .ui-icon{left:9px}.ui-checkbox .ui-btn-icon-right .ui-icon,.ui-radio .ui-btn-icon-right .ui-icon{right:15px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-icon,.ui-radio .ui-mini.ui-btn-icon-right .ui-icon{right:9px}.ui-checkbox .ui-btn-icon-top .ui-icon,.ui-radio .ui-btn-icon-top .ui-icon{top:10px}.ui-checkbox .ui-btn-icon-bottom .ui-icon,.ui-radio .ui-btn-icon-bottom .ui-icon{top:auto;bottom:10px}.ui-checkbox .ui-btn-icon-right .ui-icon,.ui-radio .ui-btn-icon-right .ui-icon{right:15px}.ui-checkbox .ui-mini.ui-btn-icon-right .ui-icon,.ui-radio .ui-mini.ui-btn-icon-right .ui-icon{right:9px}.ui-checkbox input,.ui-radio input{position:absolute;left:20px;top:50%;width:10px;height:10px;margin:-5px 0 0 0;outline:0!important;z-index:1}.ui-field-contain,fieldset.ui-field-contain{padding:.8em 0;margin:0;border-width:0 0 1px 0;overflow:visible}.ui-field-contain:first-child{border-top-width:0}.ui-header .ui-field-contain-left,.ui-header .ui-field-contain-right{position:absolute;top:0;width:25%}.ui-header .ui-field-contain-left{left:1em}.ui-header .ui-field-contain-right{right:1em}@media all and (min-width:450px){.ui-field-contain,.ui-mobile fieldset.ui-field-contain{border-width:0;padding:0;margin:1em 0}}.ui-select{display:block;position:relative}.ui-select select{position:absolute;left:-9999px;top:-9999px}.ui-select .ui-btn{overflow:hidden;opacity:1;margin:0}.ui-select .ui-btn select{cursor:pointer;-webkit-appearance:button;left:0;top:0;width:100%;min-height:1.5em;min-height:100%;height:3em;max-height:100%;opacity:0;-ms-filter:"alpha(opacity=0)";filter:alpha(opacity=0);z-index:2}.ui-select .ui-disabled{opacity:.3}@-moz-document url-prefix(){.ui-select .ui-btn select{opacity:.0001}}.ui-select .ui-btn select.ui-select-nativeonly{opacity:1;text-indent:0}.ui-select .ui-btn-icon-right .ui-btn-inner{padding-right:45px}.ui-select .ui-btn-icon-right .ui-icon{right:15px}.ui-select .ui-mini.ui-btn-icon-right .ui-icon{right:7px}label.ui-select{font-size:16px;line-height:1.4;font-weight:normal;margin:0 0 .3em;display:block}.ui-select .ui-btn-text,.ui-selectmenu .ui-btn-text{display:block;min-height:1em;overflow:hidden!important}.ui-select .ui-btn-text{text-overflow:ellipsis}.ui-selectmenu{position:absolute;padding:0;z-index:1100!important;width:80%;max-width:350px;padding:6px}.ui-selectmenu .ui-listview{margin:0}.ui-selectmenu .ui-btn.ui-li-divider{cursor:default}.ui-selectmenu-hidden{top:-9999px;left:-9999px}.ui-selectmenu-screen{position:absolute;top:0;left:0;width:100%;height:100%;z-index:99}.ui-screen-hidden,.ui-selectmenu-list .ui-li .ui-icon{display:none}.ui-selectmenu-list .ui-li .ui-icon{display:block}.ui-li.ui-selectmenu-placeholder{display:none}.ui-selectmenu .ui-header .ui-title{margin:.6em 46px .8em}@media all and (min-width:450px){.ui-field-contain label.ui-select{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain .ui-select{width:60%;display:inline-block}}.ui-selectmenu .ui-header h1:after{content:'.';visibility:hidden}label.ui-input-text{font-size:16px;line-height:1.4;display:block;font-weight:normal;margin:0 0 .3em}input.ui-input-text,textarea.ui-input-text{background-image:none;padding:.4em;line-height:1.4;font-size:16px;display:block;width:97%;outline:0}.ui-header input.ui-input-text,.ui-footer input.ui-input-text{margin-left:1.25%;padding:.4em 1%;width:95.5%}input.ui-input-text{-webkit-appearance:none}textarea.ui-input-text{height:50px;-webkit-transition:height 200ms linear;-moz-transition:height 200ms linear;-o-transition:height 200ms linear;transition:height 200ms linear}.ui-input-search{padding:0 30px;background-image:none;position:relative}.ui-icon-searchfield:after{position:absolute;left:7px;top:50%;margin-top:-9px;content:"";width:18px;height:18px;opacity:.5}.ui-input-search input.ui-input-text{border:0;width:98%;padding:.4em 0;margin:0;display:block;background:transparent none;outline:0!important}.ui-input-search .ui-input-clear{position:absolute;right:0;top:50%;margin-top:-13px}.ui-mini .ui-input-clear{right:-3px}.ui-input-search .ui-input-clear-hidden{display:none}input.ui-mini,.ui-mini input,textarea.ui-mini{font-size:14px}textarea.ui-mini{height:45px}@media all and (min-width:450px){.ui-field-contain label.ui-input-text{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain input.ui-input-text,.ui-field-contain textarea.ui-input-text,.ui-field-contain .ui-input-search{width:60%;display:inline-block}.ui-field-contain .ui-input-search{width:50%}.ui-hide-label input.ui-input-text,.ui-hide-label textarea.ui-input-text,.ui-hide-label .ui-input-search{padding:.4em;width:97%}.ui-input-search input.ui-input-text{width:98%}}.ui-listview{margin:0;counter-reset:listnumbering}.ui-content .ui-listview{margin:-15px}.ui-content .ui-listview-inset{margin:1em 0}.ui-listview,.ui-li{list-style:none;padding:0}.ui-li,.ui-li.ui-field-contain{display:block;margin:0;position:relative;overflow:visible;text-align:left;border-width:0;border-top-width:1px}.ui-li .ui-btn-text a.ui-link-inherit{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-divider,.ui-li-static{padding:.5em 15px;font-size:14px;font-weight:bold}.ui-li-divider{counter-reset:listnumbering}ol.ui-listview .ui-link-inherit:before,ol.ui-listview .ui-li-static:before,.ui-li-dec{font-size:.8em;display:inline-block;padding-right:.3em;font-weight:normal;counter-increment:listnumbering;content:counter(listnumbering) ". "}ol.ui-listview .ui-li-jsnumbering:before{content:""!important}.ui-listview-inset .ui-li{border-right-width:1px;border-left-width:1px}.ui-li:last-child,.ui-li.ui-field-contain:last-child{border-bottom-width:1px}.ui-li>.ui-btn-inner{display:block;position:relative;padding:0}.ui-li .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li{padding:.7em 15px .7em 15px;display:block}.ui-li-has-thumb .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-thumb{min-height:60px;padding-left:100px}.ui-li-has-icon .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-icon{min-height:20px;padding-left:40px}.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-count{padding-right:45px}.ui-li-has-arrow .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-arrow{padding-right:30px}.ui-li-has-arrow.ui-li-has-count .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-arrow.ui-li-has-count{padding-right:75px}.ui-li-has-count .ui-btn-text{padding-right:15px}.ui-li-heading{font-size:16px;font-weight:bold;display:block;margin:.6em 0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-desc{font-size:12px;font-weight:normal;display:block;margin:-.5em 0 .6em;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.ui-li-thumb,.ui-listview .ui-li-icon{position:absolute;left:1px;top:0;max-height:80px;max-width:80px}.ui-listview .ui-li-icon{max-height:40px;max-width:40px;left:10px;top:.9em}.ui-li-thumb,.ui-listview .ui-li-icon,.ui-li-content{float:left;margin-right:10px}.ui-li-aside{float:right;width:50%;text-align:right;margin:.3em 0}@media all and (min-width:480px){.ui-li-aside{width:45%}}.ui-li-divider{cursor:default}.ui-li-has-alt .ui-btn-inner a.ui-link-inherit,.ui-li-static.ui-li-has-alt{padding-right:95px}.ui-li-has-count .ui-li-count{position:absolute;font-size:11px;font-weight:bold;padding:.2em .5em;top:50%;margin-top:-.9em;right:48px}.ui-li-divider .ui-li-count,.ui-li-static .ui-li-count{right:10px}.ui-li-has-alt .ui-li-count{right:55px}.ui-li-link-alt{position:absolute;width:40px;height:100%;border-width:0;border-left-width:1px;top:0;right:0;margin:0;padding:0;z-index:2}.ui-li-link-alt .ui-btn{overflow:hidden;position:absolute;right:8px;top:50%;margin:-11px 0 0 0;border-bottom-width:1px;z-index:-1}.ui-li-link-alt .ui-btn-inner{padding:0;height:100%;position:absolute;width:100%;top:0;left:0}.ui-li-link-alt .ui-btn .ui-icon{right:50%;margin-right:-9px}.ui-listview * .ui-btn-inner>.ui-btn>.ui-btn-inner{border-top:0}.ui-listview-filter{border-width:0;overflow:hidden;margin:-15px -15px 15px -15px}.ui-listview-filter .ui-input-search{margin:5px;width:auto;display:block}.ui-listview-filter-inset{margin:-15px -5px -15px -5px;background:transparent}.ui-li.ui-screen-hidden{display:none}@media only screen and (min-device-width:768px) and (max-device-width:1024px){.ui-li .ui-btn-text{overflow:visible}}label.ui-slider{font-size:16px;line-height:1.4;font-weight:normal;margin:0 0 .3em;display:block}input.ui-slider-input,.ui-field-contain input.ui-slider-input{display:inline-block;width:50px}select.ui-slider-switch{display:none}div.ui-slider{position:relative;display:inline-block;overflow:visible;height:15px;padding:0;margin:0 2% 0 20px;top:4px;width:65%}div.ui-slider-mini{height:12px;margin-left:10px}div.ui-slider-bg{border:0;height:100%;padding-right:8px}.ui-controlgroup a.ui-slider-handle,a.ui-slider-handle{position:absolute;z-index:1;top:50%;width:28px;height:28px;margin-top:-15px;margin-left:-15px;outline:0}a.ui-slider-handle .ui-btn-inner{padding:0;height:100%}div.ui-slider-mini a.ui-slider-handle{height:14px;width:14px;margin:-8px 0 0 -7px}div.ui-slider-mini a.ui-slider-handle .ui-btn-inner{height:30px;width:30px;padding:0;margin:-9px 0 0 -9px}@media all and (min-width:450px){.ui-field-contain label.ui-slider{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-field-contain div.ui-slider{width:43%}.ui-field-contain div.ui-slider-switch{width:5.5em}}div.ui-slider-switch{height:32px;margin-left:0;width:5.8em}a.ui-slider-handle-snapping{-webkit-transition:left 70ms linear;-moz-transition:left 70ms linear}div.ui-slider-switch .ui-slider-handle{margin-top:1px}.ui-slider-inneroffset{margin:0 16px;position:relative;z-index:1}div.ui-slider-switch.ui-slider-mini{width:5em;height:29px}div.ui-slider-switch.ui-slider-mini .ui-slider-inneroffset{margin:0 15px 0 14px}div.ui-slider-switch.ui-slider-mini .ui-slider-handle{width:25px;height:25px;margin:1px 0 0 -13px}div.ui-slider-switch.ui-slider-mini a.ui-slider-handle .ui-btn-inner{height:30px;width:30px;padding:0;margin:0}span.ui-slider-label{position:absolute;text-align:center;width:100%;overflow:hidden;font-size:16px;top:0;line-height:2;min-height:100%;border-width:0;white-space:nowrap}.ui-slider-mini span.ui-slider-label{font-size:14px}span.ui-slider-label-a{z-index:1;left:0;text-indent:-1.5em}span.ui-slider-label-b{z-index:0;right:0;text-indent:1.5em}.ui-slider-inline{width:120px;display:inline-block} --- a/css/jquery.ui.datepicker.mobile.css +++ /dev/null @@ -1,18 +1,1 @@ -div.hasDatepicker{display:block;padding:0;overflow:visible;margin:8px 0;} -.ui-datepicker{overflow:visible;margin:0;max-width:500px;} -.ui-datepicker .ui-datepicker-header{position:relative;padding:.4em 0;border-bottom:0;font-weight:bold;} -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next{padding:1px 0 1px 2px;position:absolute;top:.5em;margin-top:0;text-indent:-9999px;} -.ui-datepicker .ui-datepicker-prev{left:6px;} -.ui-datepicker .ui-datepicker-next{right:6px;} -.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center;} -.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0;} -.ui-datepicker select.ui-datepicker-month-year{width:100%;} -.ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year{width:49%;} -.ui-datepicker table{width:100%;border-collapse:collapse;margin:0;} -.ui-datepicker td{border-width:1px;padding:0;text-align:center;} -.ui-datepicker td span, .ui-datepicker td a{display:block;padding:.2em 0;font-weight:bold;margin:0;border-width:0;text-align:center;text-decoration:none;} -.ui-datepicker-calendar th{padding-top:.3em;padding-bottom:.3em;} -.ui-datepicker-calendar th span, .ui-datepicker-calendar span.ui-state-default{opacity:.3;} -.ui-datepicker-calendar td a{padding-top:.5em;padding-bottom:.5em;} -.min-width-480px div.hasDatepicker{width:63%;display:inline-block;margin:0;} --- /dev/null +++ b/css/local.css.php @@ -1,1 +1,221 @@ - + + --- a/dotcloud/postinstall +++ b/dotcloud/postinstall @@ -3,8 +3,8 @@ curl http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \ -o /home/dotcloud/current/cbrfeed.zip -wget http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \ --O /tmp/Graph.obj +curl http://s3-ap-southeast-1.amazonaws.com/busresources/Graph.obj \ +-o /tmp/Graph.obj #db setup #curl https://github.com/maxious/ACTBus-ui/raw/master/transitdata.cbrfeed.sql.gz -o transitdata.cbrfeed.sql.gz --- a/feedback.php +++ b/feedback.php @@ -1,28 +1,15 @@ verifyEmailAddress($address); - //$con->listVerifiedEmailAddresses(); - $m = new SimpleEmailServiceMessage(); - $m->addTo($address); - $m->setFrom($address); - $m->setSubject($topic); - $m->setMessageFromString($message); - $con->sendEmail($m); - } - else { // In case any of our lines are larger than 70 characters, we should use wordwrap() $message = wordwrap($message, 70); // Send mail($address, $topic, $message); - } + } if (isset($_REQUEST['feedback']) || isset($_REQUEST['newlocation'])){ sendEmail("bus.lambda feedback",print_r($_REQUEST,true)); @@ -30,7 +17,7 @@ } else { $stopid = ""; $stopcode = ""; -$urlparts = explode("?",$_SERVER["HTTP_REFERER"]); +if (isset($_SERVER["HTTP_REFERER"])) $urlparts = explode("?",$_SERVER["HTTP_REFERER"]); if (isset($urlparts[1])) { $getparams = explode("&",$urlparts[1]); foreach ($getparams as $param) { @@ -59,14 +46,14 @@ --- /dev/null +++ b/geo/route.kml.php @@ -1,1 +1,105 @@ + +'; +echo ' + + + + + + '; +$route = getRoute($routeid); +echo "\n\n"; +$_REQUEST['time'] = "12:00"; +$trip = getRouteNextTrip($routeid, 0); +$link = curPageURL() . "/../trip.php?routeid=" . htmlspecialchars($route["route_id"]. "&directionid=0&tripid=".$trip['trip_id']) ; +echo "" . $route['route_short_name'] . " Direction 0 "; +echo ''; +echo '' . $route['route_short_name'] . " Direction 0]]> "; +echo "#yellowLineYellowPoly"; +echo getTripShape($trip['trip_id']); + echo "\n"; +$stops = Array(); +foreach (getTripStops($trip['trip_id']) as $stop) { + $stop['style'] = "#ylw-pushpin"; + $stops[$stop['stop_id']] = $stop; +} + + +echo "\n\n"; +$trip = getRouteNextTrip($routeid, 1); +$link = curPageURL() . "/../trip.php?routeid=" . htmlspecialchars($route["route_id"]. "&directionid=1&tripid=".$trip['trip_id']) ; +echo "" . $route['route_short_name'] . " Direction 1 "; +echo ''; +echo '' . $route['route_short_name'] . " Direction 1]]> "; +echo "#blueLineBluePoly"; + +echo getTripShape($trip['trip_id']); + echo "\n"; +foreach (getTripStops($trip['trip_id']) as $stop) { + if (isset($stops[$stop['stop_id']])) { + $stop['style'] = "#grn-pushpin"; + } else { + $stop['style'] = "#blue-pushpin"; + } + $stops[$stop['stop_id']] = $stop; +} +foreach ($stops as $stop) { + echo "\n\n"; + $link = curPageURL() . '/../stop.php?stopid=' . htmlspecialchars($stop['stop_id']); + echo "" . htmlspecialchars($stop['stop_name']) . ""; + echo ''; + echo '' . htmlspecialchars($stop['stop_name']) . "]]> "; + echo "" . $stop['style'] . ""; + echo $stop['positionkml']; + echo "\n"; +} + +echo "\n"; +?> + + --- /dev/null +++ b/geo/stops.kml.php @@ -1,1 +1,40 @@ +createElementNS('http://www.opengis.net/kml/2.2', 'kml'); +$parNode = $dom->appendChild($node); +// Creates a KML Document element and append it to the KML element. +$dnode = $dom->createElement('Document'); +$docNode = $parNode->appendChild($dnode); +if ($suburb != "") $result_stops = getStopsBySuburb($suburb); +else $result_stops = getStops(); +foreach ($result_stops as $stop) { + $description = 'View stop page
'; + // Creates a Placemark and append it to the Document. + $node = $dom->createElement('Placemark'); + $placeNode = $docNode->appendChild($node); + // Creates an id attribute and assign it the value of id column. + $placeNode->setAttribute('id', 'placemark' . $stop['stop_id']); + // Create name, and description elements and assigns them the values of the name and address columns from the results. + $nameNode = $dom->createElement('name', htmlentities($stop['stop_name'])); + $descriptionNode = $dom->createElement('description', $description); + $placeNode->appendChild($nameNode); + $placeNode->appendChild($descriptionNode); + // Creates a Point element. + $pointNode = $dom->createElement('Point'); + $placeNode->appendChild($pointNode); + // Creates a coordinates element and gives it the value of the lng and lat columns from the results. + $coorStr = $stop['stop_lon'] . ',' . $stop['stop_lat']; + $coorNode = $dom->createElement('coordinates', $coorStr); + $pointNode->appendChild($coorNode); +} +$kmlOutput = $dom->saveXML(); +echo $kmlOutput; +?> --- /dev/null +++ b/geo/trip.kml.php @@ -1,1 +1,70 @@ + +'; +echo ' + + + + '; +$trip = getTrip($tripid); +echo "\n\n"; +$link = curPageURL() . "/../trip.php?tripid=" . htmlspecialchars($$tripid); +echo "" . $tripid . ""; +echo ''; +echo '' . $tripid . "]]> "; +echo "#yellowLineGreenPoly"; + +echo getTripShape($tripid); + +echo "\n"; +foreach (getTripStopTimes($tripid) as $stop) { + echo "\n\n"; + $link = curPageURL() . '/../trip.php?tripid=' . htmlspecialchars($tripid); + echo "" . $stop['arrival_time'] . " @ " . htmlspecialchars($stop['stop_name']) . ""; + echo ''; + echo '' . htmlspecialchars($stop['stop_name']) . "]]> "; + echo "#blue-pushpin"; + echo "" . $stop['stop_lon'] . "," . $stop['stop_lat'] . ""; + + echo "\n"; +} +echo "\n"; +?> + + --- /dev/null +++ b/geo/trips.kml.php @@ -1,1 +1,51 @@ + +'; +echo ' + + + '; +foreach (getActiveTrips() as $trip) { + echo "\n\n"; + $link = curPageURL() . '/../trip.php?tripid=' . htmlspecialchars($trip['trip_id']); + $lastStop = getTripLastStop($trip['trip_id']); + echo "" . $lastStop[0]['arrival_time'] . " @ " . htmlspecialchars($lastStop[0]['stop_name']) . ""; + echo ''; + echo '' . htmlspecialchars($lastStop[0]['stop_name']) . "]]> "; + echo "#bus-pushpin"; + echo "" . $lastStop[0]['stop_lon'] . "," . $lastStop[0]['stop_lat'] . ""; + + echo "\n"; +} +echo "\n"; +?> + + --- /dev/null +++ b/include/common-auth.inc.php @@ -1,1 +1,32 @@ +mode) { + $openid->required = array('contact/email'); + $openid->identity = 'https://www.google.com/accounts/o8/id'; + header('Location: ' . $openid->authUrl()); + } +} + +function auth() { + if ($_SESSION['authed'] == true) + return true; + global $openid; + + if ($openid->mode) { + $attr = $openid->getAttributes(); + if ($attr['contact/email'] != 'maxious@gmail.com') { + die('Access Denied'); + } else { + $_SESSION['authed'] = true; + } + } else { + login(); + } +} + + --- a/include/common-db.inc.php +++ b/include/common-db.inc.php @@ -1,21 +1,39 @@ +/* + * Copyright 2010,2011 Alexander Sadleir + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +if (strstr(php_uname('n'),'actbus')) { + $conn = new PDO('pgsql:dbname=transitdata;user=transitdata;password=transitdata;host=bus-main.lambdacomplex.org'); +} else if (isDebugServer()) { + $conn = new PDO('pgsql:dbname=transitdata;user=postgres;password=snmc;host=localhost'); +} else { + $conn = new PDO('pgsql:dbname=transitdata;user=transitdata;password=transitdata;host=localhost'); +} +if (!$conn) { + die('A database error occurred.'.PHP_EOL); +} + +function databaseError($errMsg) { + if ($errMsg[1] != '') { + die(print_r($errMsg,true)); + } +} + +include ('db/route-dao.inc.php'); +include ('db/trip-dao.inc.php'); +include ('db/stop-dao.inc.php'); +include ('db/servicealert-dao.inc.php'); + --- a/include/common-geo.inc.php +++ b/include/common-geo.inc.php @@ -1,152 +1,180 @@ $mapPoint) { - $markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . $markerImage . ($index + 1); - if ($index + 1 != sizeof($mapPoints)) $markers.= "|"; - if ($mapPoint[0] < $minlat) $minlat = $mapPoint[0]; - if ($mapPoint[0] > $maxlat) $maxlat = $mapPoint[0]; - if ($mapPoint[1] < $minlon) $minlon = $mapPoint[1]; - if ($mapPoint[1] > $maxlon) $maxlon = $mapPoint[1]; - $totalLat+= $mapPoint[0]; - $totalLon+= $mapPoint[1]; - } - if ($zoom == 0) { - $mapwidthinmeters = distance($minlat, $minlon, $minlat, $maxlon); - foreach (array_reverse($metersperpixel, true) as $zoomLevel => $maxdistance) { - if ($zoom == 0 && $mapwidthinmeters < ($maxdistance + 50)) $zoom = $zoomLevel; - } - } - $center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints); - } - $output = ""; - if ($collapsible) $output.= '

Open Map...

'; - $output.= ''; - if ($collapsible) $output.= '
'; - return $output; -} -function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false) -{ - $pi80 = M_PI / 180; - $lat1*= $pi80; - $lng1*= $pi80; - $lat2*= $pi80; - $lng2*= $pi80; - $r = 6372.797; // mean radius of Earth in km - $dlat = $lat2 - $lat1; - $dlng = $lng2 - $lng1; - $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); - $c = 2 * atan2(sqrt($a) , sqrt(1 - $a)); - $km = $r * $c; - if ($roundLargeValues) { - if ($km < 1) return floor($km * 1000); - else return round($km,2)."k"; - } else return floor($km * 1000); +$suburbs = explode(',', 'Acton,Ainslie,Amaroo,Aranda,Banks,Barton,Belconnen,Bonner,Bonython,Braddon,Bruce,Calwell,Campbell,Chapman,Charnwood,Chifley,Chisholm,City,Conder,Cook,Curtin,Deakin,Dickson,Downer,Duffy,Dunlop,Evatt,Fadden,Farrer,Fisher,Florey,Flynn,Forrest,Franklin,Fraser,Fyshwick,Garran,Gilmore,Giralang,Gordon,Gowrie,Greenway,Griffith,Gungahlin,Hackett,Hall,Harrison,Hawker,Higgins,Holder,Holt,Hughes,Hume,Isaacs,Isabella Plains,Kaleen,Kambah,Kingston,Latham,Lawson,Lyneham,Lyons,Macarthur,Macgregor,Macquarie,Mawson,McKellar,Melba,Mitchell,Monash,Narrabundah,Ngunnawal,Nicholls,Oaks Estate,O\'Connor,O\'Malley,Oxley,Page,Palmerston,Parkes,Pearce,Phillip,Pialligo,Red Hill,Reid,Richardson,Rivett,Russell,Scullin,Spence,Stirling,Symonston,Tharwa,Theodore,Torrens,Turner,Wanniassa,Waramanga,Watson,Weetangera,Weston,Yarralumla'); + +function staticmap($mapPoints, $collapsible = true, $twotone = false, $path = false, $numbered = false) { + + $markers = ''; + $height = 300; + $width = $height; + $index = 0; + if (sizeof($mapPoints) < 1) + return 'map error'; + if (sizeof($mapPoints) === 1) { + $markers = 'markers='.$mapPoints[0][0].','.$mapPoints[0][1]; + } else { + if (!$numbered) { + $markers = 'markers='; + } + if ($path) { + $markers.= 'markers='.$mapPoints[0][0].','.$mapPoints[0][1].'&path='; + } + foreach ($mapPoints as $index => $mapPoint) { + if ($twotone && $index == 0) { + $markers = 'markerd=color:red|' . $mapPoint[0] . ',' . $mapPoint[1] . '&markers='; + } else { + if ($numbered) { + $label = ($index > 9 ? 9 : $index); + $markers.= 'markers=label:' . $label . '|' . $mapPoint[0] . ',' . $mapPoint[1]; + if ($index + 1 != sizeof($mapPoints)) { + $markers.= '&'; + } + } else { + $markers.= $mapPoint[0] . ',' . $mapPoint[1]; + if ($index + 1 != sizeof($mapPoints)) { + $markers.= '|'; + } + } + $index++; + } + } + } + $output = ''; + if ($collapsible) { + $output.= '

Open Map...

+ + + + '; + } + if (isIOSDevice()) { + $output.= 'map of stop location'; + } + else { + $output.= 'map of stop location'; + } + + if ($collapsible) { + $output.= '
'; + } + return $output; } -function decodePolylineToArray($encoded) -{ - // source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 - $length = strlen($encoded); - $index = 0; - $points = array(); - $lat = 0; - $lng = 0; - while ($index < $length) { - // Temporary variable to hold each ASCII byte. - $b = 0; - // The encoded polyline consists of a latitude value followed by a - // longitude value. They should always come in pairs. Read the - // latitude value first. - $shift = 0; - $result = 0; - do { - // The `ord(substr($encoded, $index++))` statement returns the ASCII - // code for the character at $index. Subtract 63 to get the original - // value. (63 was added to ensure proper ASCII characters are displayed - // in the encoded polyline string, which is `human` readable) - $b = ord(substr($encoded, $index++)) - 63; - // AND the bits of the byte with 0x1f to get the original 5-bit `chunk. - // Then left shift the bits by the required amount, which increases - // by 5 bits each time. - // OR the value into $results, which sums up the individual 5-bit chunks - // into the original value. Since the 5-bit chunks were reversed in - // order during encoding, reading them in this way ensures proper - // summation. - $result|= ($b & 0x1f) << $shift; - $shift+= 5; - } - // Continue while the read byte is >= 0x20 since the last `chunk` - // was not OR'd with 0x20 during the conversion process. (Signals the end) - while ($b >= 0x20); - // Check if negative, and convert. (All negative values have the last bit - // set) - $dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1)); - // Compute actual latitude since value is offset from previous value. - $lat+= $dlat; - // The next values will correspond to the longitude for this point. - $shift = 0; - $result = 0; - do { - $b = ord(substr($encoded, $index++)) - 63; - $result|= ($b & 0x1f) << $shift; - $shift+= 5; - } while ($b >= 0x20); - $dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1)); - $lng+= $dlng; - // The actual latitude and longitude values were multiplied by - // 1e5 before encoding so that they could be converted to a 32-bit - // integer representation. (With a decimal accuracy of 5 places) - // Convert back to original values. - $points[] = array( - $lat * 1e-5, - $lng * 1e-5 - ); - } - return $points; +function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false) { + $pi80 = M_PI / 180; + $lat1*= $pi80; + $lng1*= $pi80; + $lat2*= $pi80; + $lng2*= $pi80; + $r = 6372.797; // mean radius of Earth in km + $dlat = $lat2 - $lat1; + $dlng = $lng2 - $lng1; + $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); + $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); + $km = $r * $c; + if ($roundLargeValues) { + if ($km < 1) + return floor($km * 1000); + else + return round($km, 2) . 'k'; + } + else + return floor($km * 1000); } -function geocode($query, $giveOptions) -{ - global $cloudmadeAPIkey; - $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=" . urlencode($query) . "&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true"; - $contents = json_decode(getPage($url)); - if ($giveOptions) return $contents->features; - elseif (isset($contents->features[0]->centroid)) return $contents->features[0]->centroid->coordinates[0] . "," . $contents->features[0]->centroid->coordinates[1]; - else return ""; + +function decodePolylineToArray($encoded) { + // source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 + $length = strlen($encoded); + $index = 0; + $points = array(); + $lat = 0; + $lng = 0; + while ($index < $length) { + // Temporary variable to hold each ASCII byte. + $b = 0; + // The encoded polyline consists of a latitude value followed by a + // longitude value. They should always come in pairs. Read the + // latitude value first. + $shift = 0; + $result = 0; + do { + // The `ord(substr($encoded, $index++))` statement returns the ASCII + // code for the character at $index. Subtract 63 to get the original + // value. (63 was added to ensure proper ASCII characters are displayed + // in the encoded polyline string, which is `human` readable) + $b = ord(substr($encoded, $index++)) - 63; + // AND the bits of the byte with 0x1f to get the original 5-bit `chunk. + // Then left shift the bits by the required amount, which increases + // by 5 bits each time. + // OR the value into $results, which sums up the individual 5-bit chunks + // into the original value. Since the 5-bit chunks were reversed in + // order during encoding, reading them in this way ensures proper + // summation. + $result|= ($b & 0x1f) << $shift; + $shift+= 5; + } + // Continue while the read byte is >= 0x20 since the last `chunk` + // was not OR'd with 0x20 during the conversion process. (Signals the end) + while ($b >= 0x20); + // Check if negative, and convert. (All negative values have the last bit + // set) + $dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1)); + // Compute actual latitude since value is offset from previous value. + $lat+= $dlat; + // The next values will correspond to the longitude for this point. + $shift = 0; + $result = 0; + do { + $b = ord(substr($encoded, $index++)) - 63; + $result|= ($b & 0x1f) << $shift; + $shift+= 5; + } while ($b >= 0x20); + $dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1)); + $lng+= $dlng; + // The actual latitude and longitude values were multiplied by + // 1e5 before encoding so that they could be converted to a 32-bit + // integer representation. (With a decimal accuracy of 5 places) + // Convert back to original values. + $points[] = array( + $lat * 1e-5, + $lng * 1e-5 + ); + } + return $points; } -function reverseGeocode($lat, $lng) -{ - global $cloudmadeAPIkey; - $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=" . $lat . "," . $lng . "&distance=closest&object_type=road"; - $contents = json_decode(getPage($url)); - return $contents->features[0]->properties->name; + +function geocode($query, $giveOptions) { + global $cloudmadeAPIkey; + $url = 'http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=' . urlencode($query) . '&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true'; + $contents = json_decode(getPage($url)); + if ($giveOptions) + return $contents->features; + elseif (isset($contents->features[0]->centroid)) + return $contents->features[0]->centroid->coordinates[0] . ',' . $contents->features[0]->centroid->coordinates[1]; + else + return ''; } -?> +function reverseGeocode($lat, $lng) { + global $cloudmadeAPIkey; + $url = 'http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=' . $lat . ',' . $lng . '&distance=closest&object_type=road'; + $contents = json_decode(getPage($url)); + return $contents->features[0]->properties->name; +} + --- a/include/common-net.inc.php +++ b/include/common-net.inc.php @@ -1,31 +1,47 @@ Database temporarily unavailable: "; - echo curl_errno($ch) . " " . curl_error($ch); - if (isDebug()) { - echo $url; - } - echo "
"; - } - curl_close($ch); - debug(print_r($page,true),"json"); - return $page; + +/* + * Copyright 2010,2011 Alexander Sadleir + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +function getPage($url) { + debug($url, 'json'); + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_TIMEOUT, 45); + $page = curl_exec($ch); + if (curl_errno($ch)) { + echo ' Database temporarily unavailable: '; + echo curl_errno($ch) . ' ' . curl_error($ch); + if (isDebug()) { + echo $url; + } + echo '
'; + } + curl_close($ch); + debug(print_r($page, true), 'json'); + return $page; } -function curPageURL() -{ - $isHTTPS = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"); - $port = (isset($_SERVER["SERVER_PORT"]) && ((!$isHTTPS && $_SERVER["SERVER_PORT"] != "80") || ($isHTTPS && $_SERVER["SERVER_PORT"] != "443"))); - $port = ($port) ? ':' . $_SERVER["SERVER_PORT"] : ''; - $url = ($isHTTPS ? 'https://' : 'http://') . $_SERVER["SERVER_NAME"] . $port . htmlentities(dirname($_SERVER['PHP_SELF']) , ENT_QUOTES); - return $url; + +function curPageURL() { + $isHTTPS = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'); + $port = (isset($_SERVER['SERVER_PORT']) && ((!$isHTTPS && $_SERVER['SERVER_PORT'] != '80') || ($isHTTPS && $_SERVER['SERVER_PORT'] != '443'))); + $port = ($port) ? ':' . $_SERVER['SERVER_PORT'] : ''; + $url = ($isHTTPS ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . $port . htmlentities(dirname($_SERVER['PHP_SELF']), ENT_QUOTES); + return $url; } -?> + --- /dev/null +++ b/include/common-request.inc.php @@ -1,1 +1,87 @@ +centroid)) { + $geocoded = true; + $_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; + $_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; + } else { + $_SESSION['lat'] = ''; + $_SESSION['lon'] = ''; + } + } + } + sessionUpdated(); } -if (isset($_REQUEST['time'])) { - $_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); - sessionUpdated(); + +function sessionUpdated() { + $_SESSION['lastUpdated'] = time(); } -if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") { - $geocoded = false; - if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { - $_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); - $_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); - } - else { - $geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL); - if (startsWith($geolocate, "-")) { - $locateparts = explode(",", $geolocate); - $_SESSION['lat'] = $locateparts[0]; - $_SESSION['lon'] = $locateparts[1]; - } - else { - $contents = geocode($geolocate, true); - print_r($contents); - if (isset($contents[0]->centroid)) { - $geocoded = true; - $_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; - $_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; - } - else { - $_SESSION['lat'] = ""; - $_SESSION['lon'] = ""; - } - } - } - if ($_SESSION['lat'] != "" && isAnalyticsOn()) { - trackEvent("Geolocation","Updated Location", "Geocoded - ".($geocoded ? "Yes" : "No")); - } - sessionUpdated(); + +// timeoutSession +$TIMEOUT_LIMIT = 60 * 5; // 5 minutes +if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated'] + $TIMEOUT_LIMIT < time()) { + debug('Session timeout ' . ($_SESSION['lastUpdated'] + $TIMEOUT_LIMIT) . '>' . time(), 'session'); + session_destroy(); + session_start(); } -function sessionUpdated() { - $_SESSION['lastUpdated'] = time(); + +//debug(print_r($_SESSION, true) , 'session'); +function current_time($time = '') { + if (isset($_REQUEST['time'])) + return $_REQUEST['time']; + else if ($time != '') + date('H:i:s', $time); + else + return date('H:i:s'); } -// timeoutSession -$TIMEOUT_LIMIT = 60*5; // 5 minutes -if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated']+$TIMEOUT_LIMIT < time()) { - debug ("Session timeout ".($_SESSION['lastUpdated']+$TIMEOUT_LIMIT).">".time(),"session"); - session_destroy(); - session_start(); -} -//debug(print_r($_SESSION, true) , "session"); -function current_time() { - return ($_SESSION['time']? $_SESSION['time'] : date("H:i:s")); -} -?> + --- a/include/common-template.inc.php +++ b/include/common-template.inc.php @@ -1,148 +1,126 @@ - + - ' . $pageTitle . ' - '; - if ($datepicker) echo ''; - if (isDebugServer()) { - echo ' - - - + - '; - } - else { - echo ' - - - '; - } - if ($datepicker) { - echo ' - '; - } - echo ''; - if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod')) { - echo ' + + + + + + + + '; + echo ''; + echo ''; + if (isIOSDevice()) { + echo ' '; - } - if ($geolocate) { - echo " "; - } - if (isAnalyticsOn()) echo ' + if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") + echo "geolocate();"; + echo " "; + } + if (isAnalyticsOn()) + echo ' "; - echo ' + echo ' '; - if ($opendiv) { - echo '
-
+ if ($opendiv) { + echo '
'; + echo '
Back -

' . $pageTitle . '

- Home +

' . $pageTitle . '

+ Home
'; - $overrides = getServiceOverride(); - if ($overrides['service_id']) { - if ($overrides['service_id'] == "noservice") { - echo '
Buses are not running today due to industrial action/public holiday. See Buses are not running today due to industrial action/public holiday. See http://www.action.act.gov.au for details.
'; - } - else { - echo '
Buses are running on an altered timetable today due to industrial action/public holiday. See http://www.action.act.gov.au for details.
'; - } - } - } - -} -function include_footer() -{ - echo ''; - if (isAnalyticsOn()) { - echo ""; - $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl(); - echo ''; - - } - echo "\n
"; -} -function timePlaceSettings($geolocate = false) -{ - global $service_periods; - $geoerror = false; - if ($geolocate == true) { - $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; - } - if ($geoerror) { - echo '
Sorry, but your location could not currently be detected. + $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl(); + echo ''; + } + echo "\n
"; +} + +function timeSettings() { + global $service_periods; + echo '
+

Change Time (' . (isset($_REQUEST['time']) ? $_REQUEST['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...

+
+ + + + +
+
+ + + Current Time? +
+
+ + + +
+ + +
+
'; +} + +function placeSettings() { + + $geoerror = false; + $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; + + echo '
'; + if ($geoerror) { + echo 'Sorry, but your location could not currently be detected. Please allow location permission, wait for your location to be detected, - or enter an address/co-ordinates in the box below.
'; - } - echo '
-

Change Time/Place (' . (isset($_SESSION['time']) ? $_SESSION['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...

+ or enter an address/co-ordinates in the box below.'; + } + echo '
'; + echo '
+

Change Location...

-
- - - Current Time? -
-
- - - -
'; } -function trackEvent($category, $action, $label = "", $value = - 1) -{ - if (isAnalyticsOn()) { - echo "\n"; - } -} -?> - + +function trackEvent($category, $action, $label = "", $value = - 1) { + if (isAnalyticsOn()) { + echo "\n"; + } +} + +//stop list collapsing +function stopCompare($stopName) { + return substr(trim(preg_replace("/\(Platform.*/", "", $stopName)), 0, 9); +} + +function stopGroupTitle($stopName, $stopdesc) { + if (preg_match("/Dr |Cct |Cir |Av |St |Cr |Parade |Way |Bank /", $stopName)) { + $descParts = explode("
", $stopdesc); + return trim(str_replace("Street: ", "", $descParts[0])); + } else { + return trim(preg_replace("/\(Platform.*/", "", $stopName)); + } +} + +function viaPointNames($tripid, $stop_sequence = "") { + $viaPointNames = Array(); + foreach (viaPoints($tripid, $stop_sequence) as $point) { + if (strstr($point['stop_name'], "Station") + || strstr($point['stop_name'], "Shops") + || strstr($point['stop_name'], "CIT") + || strstr($point['stop_name'], "School") + || strstr($point['stop_name'], "University") + ) { + $viaPointNames[] = $point['stop_name']; + } + } + if (sizeof($viaPointNames) > 0) { + return r_implode(", ", $viaPointNames); + } else { + return ""; + } +} + --- a/include/common-transit.inc.php +++ b/include/common-transit.inc.php @@ -1,56 +1,339 @@ 0) { - $midnight = mktime(0, 0, 0, date("n") , date("j") , date("Y")); - return date("h:ia", $midnight + $seconds); - } - else { - return ""; - } -} -?> - + +function service_period($date = '') { + + if (isset($_REQUEST['service_period'])) { + return $_REQUEST['service_period']; + } + + $override = getServiceOverride($date); + if (isset($override['service_id'])) { + return strtolower($override['service_id']); + } + $date = ($date != '' ? $date : time()); + $dow = date('w', $date); + + switch ($dow) { + case 0: + return 'sunday'; + case 6: + return 'saturday'; + default: + return 'weekday'; + } +} + +function service_ids($service_period, $date = '') { + switch ($service_period) { + case 'sunday': + return Array('Sunday', 'Sunday'); + case 'saturday': + return Array('Saturday', 'Saturday'); + default: + $date = ($date != '' ? $date : time()); +// school holidays + $ymd = date('Ymd', $date); + $dow = date('w', $date); + if (intval($ymd) < '20120427' && $dow != 0 && $dow != 6) { + return Array('Weekday-SchoolVacation', 'Weekday-SchoolVacation'); + } else { + return Array('Weekday', 'Weekday'); + } + } +} + +function valid_service_ids() { + return array_merge(service_ids(''), service_ids('saturday'), service_ids('sunday')); +} + +function midnight_seconds($time = '') { + // from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html + if ($time != '') { + return (date('G', $time) * 3600) + (date('i', $time) * 60) + date('s', $time); + } + if (isset($_SESSION['time'])) { + $time = strtotime($_SESSION['time']); + return (date('G', $time) * 3600) + (date('i', $time) * 60) + date('s', $time); + } + return (date('G') * 3600) + (date('i') * 60) + date('s'); +} + +function midnight_seconds_to_time($seconds) { + if ($seconds > 0) { + $midnight = mktime(0, 0, 0, date('n'), date('j'), date('Y')); + return date('h:ia', $midnight + $seconds); + } else { + return ''; + } +} + +if ($GTFSREnabled) { + $serviceAlertCause = Array( + 'UNKNOWN_CAUSE' => 'Unknown cause', + 'OTHER_CAUSE' => 'Other cause', + 'TECHNICAL_PROBLEM' => 'Technical problem', + 'STRIKE' => 'Strike', + 'DEMONSTRATION' => 'Demonstration', + 'ACCIDENT' => 'Accident', + 'HOLIDAY' => 'Holiday', + 'WEATHER' => 'Weather', + 'MAINTENANCE' => 'Maintenance', + 'CONSTRUCTION' => 'Construction', + 'POLICE_ACTIVITY' => 'Police activity', + 'MEDICAL_EMERGENCY' => 'Medical emergency' + ); + $serviceAlertEffect = Array( + 'NO_SERVICE' => 'No service', + 'REDUCED_SERVICE' => 'Reduced service', + 'SIGNIFICANT_DELAYS' => 'Significant delays', + 'DETOUR' => 'Detour', + 'ADDITIONAL_SERVICE' => 'Additional service', + 'MODIFIED_SERVICE' => 'Modified service', + 'OTHER_EFFECT' => 'Other effect', + 'UNKNOWN_EFFECT' => 'Unknown effect', + 'STOP_MOVED' => 'Stop moved'); + + set_include_path(get_include_path() . PATH_SEPARATOR . (ROOT. '/../lib/Protobuf-PHP/library/DrSlump/')); + + include_once('Protobuf.php'); + include_once('Protobuf/Message.php'); + include_once('Protobuf/Registry.php'); + include_once('Protobuf/Descriptor.php'); + include_once('Protobuf/Field.php'); + + include_once(ROOT. '/../lib/Protobuf-PHP/gtfs-realtime.php'); + include_once('Protobuf/CodecInterface.php'); + include_once('Protobuf/Codec/PhpArray.php'); + include_once('Protobuf/Codec/Binary.php'); + include_once('Protobuf/Codec/Binary/Writer.php'); + include_once('Protobuf/Codec/Json.php'); + + function getServiceAlerts($filter_class = '', $filter_id = '') { + /* + + also need last modified epoch of client gtfs + + - add,remove,patch,inform (null) + - stop + - trip + - network + - classes (WHERE=) + - route (short_name or route_id) + - street + - stop + - trip + Currently support: + network inform + trip patch: stop remove + street inform: route inform, trip inform, stop inform + route patch: trip remove + */ + $current_alerts = getCurrentAlerts(); + $informed_count = 0; + if (sizeof($current_alerts) > 0) { + + $fm = new transit_realtime\FeedMessage(); + $fh = new transit_realtime\FeedHeader(); + $fh->setGtfsRealtimeVersion(1); + $fh->setTimestamp(time()); + $fm->setHeader($fh); + foreach ($current_alerts as $current_alert) { + $affectsFilteredEntities = false; + $fe = new transit_realtime\FeedEntity(); + $fe->setId($current_alert['id']); + $fe->setIsDeleted(false); + $alert = new transit_realtime\Alert(); + $tr = new transit_realtime\TimeRange(); + $tr->setStart($current_alert['start']); + $tr->setEnd($current_alert['end']); + $alert->addActivePeriod($tr); + $informedEntities = getInformedAlerts($current_alert['id'], $filter_class, $filter_id); + if (sizeof($informedEntities) > 0) { + + $affectsFilteredEntities = true; + foreach ($informedEntities as $informedEntity) { + $informed_count++; + $informed = Array(); + $es = new transit_realtime\EntitySelector(); + if ($informedEntity['informed_class'] == 'agency') { + $es->setAgencyId($informedEntity['informed_id']); + } + if ($informedEntity['informed_class'] == 'stop') { + $es->setStopId($informedEntity['informed_id']); + } + if ($informedEntity['informed_class'] == 'route') { + $es->setRouteId($informedEntity['informed_id']); + } + if ($informedEntity['informed_class'] == 'trip') { + $td = new transit_realtime\TripDescriptor(); + $td->setTripId($informedEntity['informed_id']); + $es->setTrip($td); + } + $alert->addInformedEntity($es); +} + } + if ($current_alert['cause'] != '') { + $alert->setCause(constant('transit_realtime\Alert\Cause::' . $current_alert['cause'])); + } + if ($current_alert['effect'] != '') { + $alert->setEffect(constant('transit_realtime\Alert\Effect::' . $current_alert['effect'])); + } + if ($current_alert['url'] != '') { + $tsUrl = new transit_realtime\TranslatedString(); + $tUrl = new transit_realtime\TranslatedString\Translation(); + $tUrl->setText($current_alert['url']); + $tUrl->setLanguage('en'); + $tsUrl->addTranslation($tUrl); + $alert->setUrl($tsUrl); + } + if ($current_alert['header'] != '') { + $tsHeaderText = new transit_realtime\TranslatedString(); + $tHeaderText = new transit_realtime\TranslatedString\Translation(); + $tHeaderText->setText($current_alert['header']); + $tHeaderText->setLanguage('en'); + $tsHeaderText->addTranslation($tHeaderText); + $alert->setHeaderText($tsHeaderText); + } + if ($current_alert['description'] != '') { + $tsDescriptionText = new transit_realtime\TranslatedString(); + $tDescriptionText = new transit_realtime\TranslatedString\Translation(); + $tDescriptionText->setText(trim($current_alert['description'])); + $tDescriptionText->setLanguage('en'); + $tsDescriptionText->addTranslation($tDescriptionText); + $alert->setDescriptionText($tsDescriptionText); + } + $fe->setAlert($alert); + if ($affectsFilteredEntities) { + $fm->addEntity($fe); + } + } + if ($informed_count > 0) { + return $fm; + } else { + return null; + } + } else + return null; + } + + function getServiceAlertsAsArray($filter_class = '', $filter_id = '') { + + $alerts = getServiceAlerts($filter_class, $filter_id); + if ($alerts != null) { + $codec = new DrSlump\Protobuf\Codec\PhpArray(); + + return $codec->encode($alerts); + } else { + return null; + } + } + + function getServiceAlertsAsBinary($filter_class = '', $filter_id = '') { + $codec = new DrSlump\Protobuf\Codec\Binary(); + return $codec->encode(getServiceAlerts($filter_class, $filter_id)); + } + + function getServiceAlertsAsJSON($filter_class = '', $filter_id = '') { + $codec = new DrSlump\Protobuf\Codec\Json(); + return $codec->encode(getServiceAlerts($filter_class, $filter_id)); + } + + function getServiceAlertsByClass() { + $return = Array(); + $alerts = getServiceAlertsAsArray('', ''); + foreach ($alerts['entities'] as $entity) { + foreach ($entity['informed'] as $informed) { + foreach ($informed as $key => $value) { + if (strpos('_id', $key) > 0) { + $parts = explode($key); + $class = $parts[0]; + $id = $value; + } + } + $return[$class][$id][] = $entity; + } + } + } + + function getTripUpdates($filter_class = '', $filter_id = '') { + $fm = new transit_realtime\FeedMessage(); + $fh = new transit_realtime\FeedHeader(); + $fh->setGtfsRealtimeVersion(1); + $fh->setTimestamp(time()); + $fm->setHeader($fh); + foreach (getCurrentAlerts() as $alert) { + $informedEntities = getInformedAlerts($alert['id'], $_REQUEST['filter_class'], $_REQUEST['filter_id']); + $stops = Array(); + $routestrips = Array(); + if (sizeof($informedEntities) > 0) { + if ($informedEntity['informed_class'] == 'stop' && $informed['x-action'] == 'remove') { + $stops[] = $informedEntity['informed_id']; + } + if (($informedEntity['informed_class'] == 'route' || $informedEntity['informed_class'] == 'trip') && $informed['x-action'] == 'patch') { + $routestrips[] = Array('id' => $informedEntity['informed_id'], + 'type' => $informedEntity['informed_class']); + } + } + foreach ($routestrips as $routetrip) { + $fe = new transit_realtime\FeedEntity(); + $fe->setId($alert['id'] . $routetrip['id']); + $fe->setIsDeleted(false); + $tu = new transit_realtime\TripUpdate(); + $td = new transit_realtime\TripDescriptor(); + if ($routetrip['type'] == 'route') { + $td->setRouteId($routetrip['id']); + } else if ($routetrip['type'] == 'trip') { + $td->setTripId($routetrip['id']); + } + $tu->setTrip($td); + foreach ($stops as $stop) { + $stu = new transit_realtime\TripUpdate\StopTimeUpdate(); + $stu->setStopId($stop); + $stu->setScheduleRelationship(transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SKIPPED); + $tu->addStopTimeUpdate($stu); + } + $fe->setTripUpdate($tu); + $fm->addEntity($fe); + } + } + return $fm; + } + + function getTripUpdatesAsArray($filter_class = '', $filter_id = '') { + $codec = new DrSlump\Protobuf\Codec\PhpArray(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + + function getTripUpdatesAsBinary($filter_class = '', $filter_id = '') { + $codec = new DrSlump\Protobuf\Codec\Binary(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + + function getTripUpdatesAsJSON($filter_class = '', $filter_id = '') { + $codec = new DrSlump\Protobuf\Codec\Json(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + +} + --- a/include/common.inc.php +++ b/include/common.inc.php @@ -1,184 +1,197 @@ \n"; -} -function isJQueryMobileDevice() -{ - // http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897 - $user_agent = $_SERVER['HTTP_USER_AGENT']; - return preg_match('/iphone/i', $user_agent) || preg_match('/android/i', $user_agent) || preg_match('/webos/i', $user_agent) || preg_match('/ios/i', $user_agent) || preg_match('/bada/i', $user_agent) || preg_match('/maemo/i', $user_agent) || preg_match('/meego/i', $user_agent) || preg_match('/fennec/i', $user_agent) || (preg_match('/symbian/i', $user_agent) && preg_match('/s60/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/symbian/i', $user_agent) && preg_match('/platform/i', $user_agent) && $browser['majorver'] >= 3) || (preg_match('/blackberry/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/opera mobile/i', $user_agent) && $browser['majorver'] >= 10) || (preg_match('/opera mini/i', $user_agent) && $browser['majorver'] >= 5); -} -function isFastDevice() -{ - $ua = $_SERVER['HTTP_USER_AGENT']; - $fastDevices = Array( - "Mozilla/5.0 (X11;", - "Mozilla/5.0 (Windows;", - "Mozilla/5.0 (iP", - "Mozilla/5.0 (Linux; U; Android", - "Mozilla/4.0 (compatible; MSIE" - ); - $slowDevices = Array( - "J2ME", - "MIDP", - "Opera/", - "Mozilla/2.0 (compatible;", - "Mozilla/3.0 (compatible;" - ); - return true; -} -function array_flatten($a, $f = array()) -{ - if (!$a || !is_array($a)) return ''; - foreach ($a as $k => $v) { - if (is_array($v)) $f = array_flatten($v, $f); - else $f[$k] = $v; - } - return $f; -} -function remove_spaces($string) -{ - return str_replace(' ', '', $string); -} -function object2array($object) -{ - if (is_object($object)) { - foreach ($object as $key => $value) { - $array[$key] = $value; - } - } - else { - $array = $object; - } - return $array; -} -function startsWith($haystack, $needle, $case = true) -{ - if ($case) { - return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); - } - return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); +define('ROOT' , pathinfo(__FILE__, PATHINFO_DIRNAME)); +if (strstr($_SERVER['PHP_SELF'], "labs/") + || strstr($_SERVER['PHP_SELF'], "myway/") + || strstr($_SERVER['PHP_SELF'], "lib/") + || strstr($_SERVER['PHP_SELF'], "geo/") + || strstr($_SERVER['PHP_SELF'], "include/") + || strstr($_SERVER['PHP_SELF'], "rtpis/")) { + $basePath = "../"; } -function endsWith($haystack, $needle, $case = true) -{ - if ($case) { - return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); - } - return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); +function isDebugServer() { + + return php_sapi_name() == 'cli' || strstr(php_uname('n'),'actbus') || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == 'azusa' || $_SERVER['SERVER_NAME'] == 'vanille' + || $_SERVER['SERVER_NAME'] == 'localhost' || $_SERVER['SERVER_NAME'] == '127.0.0.1' || $_SERVER['SERVER_NAME'] == '192.168.1.8' || $_SERVER['SERVER_NAME'] == '192.168.178.24'); } -function bracketsMeanNewLine($input) -{ - return str_replace(")", "", str_replace("(", "
", $input)); + +if (isset($_SERVER['SERVER_NAME']) && $_SERVER['SERVER_NAME'] == 'maxious.xen.prgmr.com') { +// Set the exception handler +require ROOT.'../lib/amon-php/amon.php'; +Amon::setup_exception_handler(); } -function sksort(&$array, $subkey = "id", $sort_ascending = false) -{ - if (count($array)) $temp_array[key($array) ] = array_shift($array); - foreach ($array as $key => $val) { - $offset = 0; - $found = false; - foreach ($temp_array as $tmp_key => $tmp_val) { - if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { - $temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( - $key => $val - ) , array_slice($temp_array, $offset)); - $found = true; - } - $offset++; - } - if (!$found) $temp_array = array_merge($temp_array, array( - $key => $val - )); - } - if ($sort_ascending) $array = array_reverse($temp_array); - else $array = $temp_array; + +include_once ('common-geo.inc.php'); +include_once ('common-net.inc.php'); +include_once ('common-transit.inc.php'); +if (!strstr($_SERVER['PHP_SELF'], 'feedback')) { + include_once ('common-db.inc.php'); } -function sktimesort(&$array, $subkey = "id", $sort_ascending = false) -{ - if (count($array)) $temp_array[key($array) ] = array_shift($array); - foreach ($array as $key => $val) { - $offset = 0; - $found = false; - foreach ($temp_array as $tmp_key => $tmp_val) { - if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) { - $temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( - $key => $val - ) , array_slice($temp_array, $offset)); - $found = true; - } - $offset++; - } - if (!$found) $temp_array = array_merge($temp_array, array( - $key => $val - )); - } - if ($sort_ascending) $array = array_reverse($temp_array); - else $array = $temp_array; + +include_once ('common-request.inc.php'); +include_once ('common-session.inc.php'); +include_once ('common-auth.inc.php'); +include_once ('common-template.inc.php'); + +function isAnalyticsOn() { + $user_agent = $_SERVER['HTTP_USER_AGENT']; + return !isDebugServer() && !preg_match('/cloudkick/i', $user_agent) && !preg_match('/googlebot/i', $user_agent) && + !preg_match('/baidu/i', $user_agent); } -function r_implode( $glue, $pieces ) -{ - foreach( $pieces as $r_pieces ) - { - if( is_array( $r_pieces ) ) - { - $retVal[] = r_implode( $glue, $r_pieces ); - } - else - { - $retVal[] = $r_pieces; - } - } - return implode( $glue, $retVal ); -} -?> +function isDebug($debugReason = 'other') { + global $debugOkay; + return in_array($debugReason, $debugOkay, false) && isDebugServer(); +} + +function debug($msg, $debugReason = 'other') { + if (isDebug($debugReason)) + echo PHP_EOL.''.PHP_EOL; +} +function isIOSDevice() { + return strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad'); +} +function isJQueryMobileDevice() { + // http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897 + $user_agent = $_SERVER['HTTP_USER_AGENT']; + return preg_match('/iphone/i', $user_agent) || preg_match('/android/i', $user_agent) || preg_match('/webos/i', $user_agent) || preg_match('/ios/i', $user_agent) || preg_match('/bada/i', $user_agent) || preg_match('/maemo/i', $user_agent) || preg_match('/meego/i', $user_agent) || preg_match('/fennec/i', $user_agent) || (preg_match('/symbian/i', $user_agent) && preg_match('/s60/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/symbian/i', $user_agent) && preg_match('/platform/i', $user_agent) && $browser['majorver'] >= 3) || (preg_match('/blackberry/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/opera mobile/i', $user_agent) && $browser['majorver'] >= 10) || (preg_match('/opera mini/i', $user_agent) && $browser['majorver'] >= 5); +} + + +function array_flatten($a, $f = array()) { + if (!$a || !is_array($a)) + return ''; + foreach ($a as $k => $v) { + if (is_array($v)) + $f = array_flatten($v, $f); + else + $f[$k] = $v; + } + return $f; +} + +function remove_spaces($string) { + return str_replace(' ', '', $string); +} + +function object2array($object) { + if (is_object($object)) { + foreach ($object as $key => $value) { + $array[$key] = $value; + } + } else { + $array = $object; + } + return $array; +} + +function startsWith($haystack, $needle, $case = true) { + if ($case) { + return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0); + } + return (strcasecmp(substr($haystack, 0, strlen($needle)), $needle) === 0); +} + +function endsWith($haystack, $needle, $case = true) { + if ($case) { + return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0); + } + return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0); +} + +function sksort(&$array, $subkey = 'id', $sort_ascending = false) { + if (count($array)) + $temp_array[key($array)] = array_shift($array); + foreach ($array as $key => $val) { + $offset = 0; + $found = false; + foreach ($temp_array as $tmp_key => $tmp_val) { + if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { + $temp_array = array_merge((array) array_slice($temp_array, 0, $offset), array( + $key => $val + ), array_slice($temp_array, $offset)); + $found = true; + } + $offset++; + } + if (!$found) + $temp_array = array_merge($temp_array, array( + $key => $val + )); + } + if ($sort_ascending) + $array = array_reverse($temp_array); + else + $array = $temp_array; +} + +function sktimesort(&$array, $subkey = 'id', $sort_ascending = false) { + if (count($array)) + $temp_array[key($array)] = array_shift($array); + foreach ($array as $key => $val) { + $offset = 0; + $found = false; + foreach ($temp_array as $tmp_key => $tmp_val) { + if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) { + $temp_array = array_merge((array) array_slice($temp_array, 0, $offset), array( + $key => $val + ), array_slice($temp_array, $offset)); + $found = true; + } + $offset++; + } + if (!$found) + $temp_array = array_merge($temp_array, array( + $key => $val + )); + } + if ($sort_ascending && isset($temp_array)) + $array = array_reverse($temp_array); + else + $array = $temp_array; +} + +function r_implode($glue, $pieces) { + foreach ($pieces as $r_pieces) { + if (is_array($r_pieces)) { + $retVal[] = r_implode($glue, $r_pieces); + } else { + $retVal[] = $r_pieces; + } + } + return implode($glue, $retVal); +} + --- a/include/db/route-dao.inc.php +++ b/include/db/route-dao.inc.php @@ -1,160 +1,310 @@ prepare($query); + $query->bindParam(':routeID', $routeID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function getRoutesByShortName($routeShortName) { + global $conn; + $query = 'Select distinct route_id, route_short_name from routes where route_short_name = :routeShortName'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':routeShortName', $routeShortName); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRouteHeadsigns($routeID) { + global $conn; + $query = 'select stops.stop_name, trip_headsign, direction_id,max(service_id) as service_id, count(*) + from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id join stops on +stop_times.stop_id = stops.stop_id where trips.route_id = :routeID +and stop_times.stop_sequence = 1 group by stops.stop_name, trip_headsign, direction_id having count(*) > 2'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':routeID', $routeID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $results = $query->fetchAll(); + if (is_array($results)) { + return $results; + } else { + return Array($results); + } +} + +function getRouteDescription($routeID, $directionID) { + $trip = getRouteNextTrip($routeID, $directionID); + $start = getTripStartingPoint($trip['trip_id']); + $end = getTripDestination($trip['trip_id']); + return 'From ' . $start['stop_name'] . ' to ' . $end['stop_name']; +} + +function getRouteByFullName($routeFullName) { + global $conn; + $query = 'Select * from routes where route_short_name||route_long_name = :routeFullName LIMIT 1'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':routeFullName', $routeFullName); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + function getRoutes() { - global $conn; - $query = "Select * from routes order by route_short_name;"; - debug($query,"database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} - -function getRoutesByNumber($routeNumber = "") { - global $conn; - if ($routeNumber != "") { - $query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id = -routes.route_id join stop_times on stop_times.trip_id = trips.trip_id where route_short_name = '$routeNumber' order by route_short_name;"; - } else { - $query = "SELECT DISTINCT route_short_name from routes order by route_short_name"; + global $conn; + $query = 'Select * from routes order by route_short_name;'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRoutesByNumberSeries($routeNumberSeries = '') { + global $conn; + if (strlen($routeNumberSeries) == 1) { + return getRoute($routeNumberSeries); + } + $seriesMin = substr($routeNumberSeries, 0, -1) . '0'; + $seriesMax = substr($routeNumberSeries, 0, -1) . '9'; + $query = 'Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id = +routes.route_id join stop_times on stop_times.trip_id = trips.trip_id where to_number(route_short_name, \'FM999\') between :seriesMin and :seriesMax OR route_short_name LIKE :routeNumberSeries order by route_short_name;'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':seriesMin', $seriesMin); + $query->bindParam(':seriesMax', $seriesMax); + $routeNumberSeries = '% ' . substr($routeNumberSeries, 0, -1) . '%'; + $query->bindParam(':routeNumberSeries', $routeNumberSeries); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRouteNextTrip($routeID, $directionID) { + global $conn; + + $query = 'select routes.route_id,routes.route_url,direction_id,trips.trip_id,trip_headsign,departure_time,service_id from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id where arrival_time between :currentTime and :futureTime +and routes.route_id = :routeID and trips.direction_id = :directionID order by +arrival_time limit 1'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':currentTime', current_time()); + $futureTime = current_time(strtotime(current_time() . ' +2h')); + if (date('h', strtotime(current_time()) > 22)) + $futureTime = '23:59:59'; + $query->bindParam(':futureTime', $futureTime); + $query->bindParam(':routeID', $routeID); + $query->bindParam(':directionID', $directionID); + $query->execute(); + databaseError($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; +} + +function getRouteFirstTrip($routeID, $directionID) { + global $conn; + + $query = 'select * from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID +and trips.direction_id = :directionID order by +arrival_time DESC limit 1'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':routeID', $routeID); + + $query->bindParam(':directionID', $directionID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; +} + +function getRouteAtStop($routeID, $directionID, $stop_id) { + $nextTrip = getRouteNextTrip($routeID, $directionID); + if ($nextTrip['trip_id']) { + foreach (getTripStopTimes($nextTrip['trip_id']) as $tripStop) { + if ($tripStop['stop_id'] == $stop_id) + return $tripStop; } - debug($query,"database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} - -function getRouteNextTrip($routeID) { - global $conn; - $query = "select * from routes join trips on trips.route_id = routes.route_id -join stop_times on stop_times.trip_id = trips.trip_id where -arrival_time > '".current_time()."' and routes.route_id = '$routeID' order by -arrival_time limit 1"; - debug($query,"database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - $r = pg_fetch_assoc($result); - // past last trip of the day special case - if (sizeof($r) == 0) { - $query = "select * from routes join trips on trips.route_id = routes.route_id -join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = '$routeID' order by -arrival_time DESC limit 1"; - debug($query,"database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - $r = pg_fetch_assoc($result); - } - return $r; - } - - function getTimeInterpolatedRouteAtStop($routeID, $stop_id) -{ - $nextTrip = getRouteNextTrip($routeID); - if ($nextTrip['trip_id']){ - foreach (getTimeInterpolatedTrip($nextTrip['trip_id']) as $tripStop) { - if ($tripStop['stop_id'] == $stop_id) return $tripStop; - } - } - return Array(); -} - -function getRouteTrips($routeID) { - global $conn; - $query = "select routes.route_id,trips.trip_id,service_id,arrival_time, stop_id, stop_sequence from routes join trips on trips.route_id = routes.route_id -join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = '$routeID' and stop_sequence = '1' order by -arrival_time "; - debug($query,"database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); - } -function getRoutesByDestination($destination = "", $service_period = "") { - global $conn; - if ($service_period == "") $service_period = service_period(); - if ($destination != "") { - $query = "SELECT DISTINCT trips.route_id,route_short_name,route_long_name, service_id -FROM stop_times join trips on trips.trip_id = -stop_times.trip_id join routes on trips.route_id = routes.route_id -WHERE route_long_name = '$destination' AND service_id='$service_period' order by route_short_name"; - } else { - $query = "SELECT DISTINCT route_long_name -FROM stop_times join trips on trips.trip_id = -stop_times.trip_id join routes on trips.route_id = routes.route_id -WHERE service_id='$service_period' order by route_long_name"; - } - debug($query,"database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} - -function getRoutesBySuburb($suburb, $service_period = "") { - if ($service_period == "") $service_period = service_period(); - global $conn; - $query = "SELECT DISTINCT service_id,trips.route_id,route_short_name,route_long_name + } + return Array(); +} + +function getRouteTrips($routeID, $directionID = '', $service_period = '') { + global $conn; + if ($service_period == '') + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + $directionSQL = ''; + if ($directionID != '') + $directionSQL = ' and direction_id = :directionID '; + $query = 'select routes.route_id,trips.trip_id,service_id,arrival_time, stop_id, stop_sequence from routes join trips on trips.route_id = routes.route_id +join stop_times on stop_times.trip_id = trips.trip_id where (service_id=:service_periodA OR service_id=:service_periodB) +AND (routes.route_id = :routeID) ' . $directionSQL . ' and stop_sequence = \'1\' order by +arrival_time '; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':routeID', $routeID); + $query->bindParam(':service_periodA', $sidA); + $query->bindParam(':service_periodB', $sidB); + if ($directionSQL != '') + $query->bindParam(':directionID', $directionID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRoutesByDestination($destination = '', $service_period = '') { + global $conn; + if ($service_period == '') + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + if ($destination != '') { + /* $query = 'SELECT DISTINCT trips.route_id,route_short_name,route_long_name, service_id + FROM stop_times join trips on trips.trip_id = + stop_times.trip_id join routes on trips.route_id = routes.route_id + WHERE route_long_name = :destination AND (service_id=:service_periodA OR service_id=:service_periodB) + order by route_short_name'; */ + $query = 'select route_id, direction_id, stop_name, b.trip_id, b.stop_sequence from (select route_id, direction_id, max(stop_sequence) as stop_sequence, max(a.trip_id) as trip_id from stop_times inner join (SELECT route_id, direction_id, max(trip_id) as trip_id + from trips group by route_id,direction_id) as a on stop_times.trip_id = a.trip_id group by route_id, direction_id) as b inner join stop_times on b.trip_id = stop_times.trip_id inner join stops on stop_times.stop_id = stops.stop_id where stop_times.stop_sequence = b.stop_sequence and stop_name = :destination order by route_id;'; + } else { + $query = 'select stop_name from (select route_id, direction_id, max(stop_sequence) as stop_sequence, max(a.trip_id) as trip_id from stop_times inner join (SELECT route_id, direction_id, max(trip_id) as trip_id + from trips group by route_id,direction_id) as a on stop_times.trip_id = a.trip_id group by route_id, direction_id) as b inner join stop_times on b.trip_id = stop_times.trip_id inner join stops on stop_times.stop_id = stops.stop_id where stop_times.stop_sequence = b.stop_sequence group by stop_name order by stop_name;'; + } + debug($query, 'database'); + $query = $conn->prepare($query); + + //$query->bindParam(':service_periodA', $sidA); + //$query->bindParam(':service_periodB', $sidB); + if ($destination != '') + $query->bindParam(':destination', $destination); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getRoutesBySuburb($suburb, $service_period = '') { + if ($service_period == '') + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + + global $conn; + $query = 'SELECT DISTINCT service_id,trips.route_id,route_short_name,route_long_name FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id join stops on stops.stop_id = stop_times.stop_id -WHERE zone_id LIKE '%$suburb;%' AND service_id='$service_period' ORDER BY route_short_name"; - debug($query,"database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} - -function getRoutesNearby($lat, $lng, $limit = "", $distance = 500) { - - - if ($service_period == "") $service_period = service_period(); - if ($limit != "") $limit = " LIMIT $limit "; - global $conn; - $query = "SELECT service_id,trips.route_id,route_short_name,route_long_name,min(stops.stop_id) as stop_id, - min(ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE)) as distance +WHERE stop_desc LIKE :suburb AND (service_id=:service_periodA OR service_id=:service_periodB) + ORDER BY route_short_name'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':service_periodA', $sidA); + $query->bindParam(':service_periodB', $sidB); + $suburb = '%Suburb: %' . $suburb . '%'; + $query->bindParam(':suburb', $suburb); + $query->execute(); + + databaseError($conn->errorInfo()); + + return $query->fetchAll(); +} + +function getRoutesNearby($lat, $lng, $limit = '', $distance = 500) { + // if ($service_period == '') + $service_period = service_period(); + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + $limitSQL = ''; + if ($limit != '') + $limitSQL = ' LIMIT :limit '; + global $conn; + $query = 'SELECT service_id,trips.route_id,trips.direction_id,route_short_name,route_long_name,min(stops.stop_id) as stop_id, + min(ST_Distance(position, ST_GeographyFromText(\'SRID=4326;POINT($lng $lat)\'), FALSE)) as distance FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id join stops on stops.stop_id = stop_times.stop_id -WHERE service_id='$service_period' -AND ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), $distance, FALSE) - group by service_id,trips.route_id,route_short_name,route_long_name - order by distance $limit"; - debug($query,"database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} -?> +WHERE (service_id=:service_periodA OR service_id=:service_periodB) +AND ST_DWithin(position, ST_GeographyFromText(\'SRID=4326;POINT($lng $lat)\'), :distance, FALSE) + group by service_id,trips.route_id,trips.direction_id,route_short_name,route_long_name + order by distance '.$limitSQL; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':service_periodA', $sidA); + $query->bindParam(':service_periodB', $sidB); + $query->bindParam(':distance', $distance); + if ($limit != '') + $query->bindParam(':limit', $limit); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + --- /dev/null +++ b/include/db/servicealert-dao.inc.php @@ -1,1 +1,198 @@ +prepare($query); // Create a prepared statement + $date = date('Ymd', ($date != '' ? $date : time())); + $query->bindParam(':date', $date); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function getServiceAlert($alertID) { + global $conn; + $query = 'SELECT id,extract(\'epoch\' from start) as start, extract(\'epoch\' from "end") as end,cause,effect,header,description,url from servicealerts_alerts where id = :servicealert_id'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':servicealert_id', $alertID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function updateServiceAlert($alertID, $alert) { + global $conn; + $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url, cause=:cause, effect=:effect where id = :servicealert_id'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindValue(':servicealert_id', $alertID); + $query->bindValue(':start', $alert['startdate']); + $query->bindValue(':end', $alert['enddate']); + $query->bindValue(':header', $alert['header']); + $query->bindValue(':description', $alert['description']); + $query->bindValue(':url', $alert['url']); + $query->bindValue(':cause', $alert['cause']); + $query->bindValue(':effect', $alert['effect']); + $query->execute(); + + print_r($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function addServiceAlert($alert) { + global $conn; + $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url,cause,effect) VALUES (:start, :end, :header, :description, :url,:cause,:effect) '; + debug($query, 'database'); + $query = $conn->prepare($query); + //print_r($alert); + $query->bindValue(':start', $alert['startdate']); + $query->bindValue(':end', $alert['enddate']); + $query->bindValue(':header', $alert['header']); + $query->bindValue(':description', $alert['description']); + $query->bindValue(':url', $alert['url']); + $query->bindValue(':cause', $alert['cause']); + $query->bindValue(':effect', $alert['effect']); + $query->execute(); + + print_r($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function getCurrentAlerts() { + global $conn; + $query = 'SELECT id,extract(\'epoch\' from start) as start, extract(\'epoch\' from "end") as end,cause,effect,header,description,url from servicealerts_alerts where NOW() > start and NOW() < "end"'; + // debug($query, 'database'); + $query = $conn->prepare($query); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getFutureAlerts() { + global $conn; + $query = 'SELECT id,extract(\'epoch\' from start) as start, extract(\'epoch\' from "end") as end,cause,effect,header,description,url from servicealerts_alerts where NOW() < "end"'; + // debug($query, 'database'); + $query = $conn->prepare($query); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getAllAlerts() { + global $conn; + $query = 'SELECT id,extract(\'epoch\' from start) as start, extract(\'epoch\' from "end") as end,cause,effect,header,description,url from servicealerts_alerts'; + // debug($query, 'database'); + $query = $conn->prepare($query); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getInformedAlerts($id, $filter_class, $filter_id) { + + global $conn; + //echo '$id, $filter_class, $filter_id\n'; + $query = 'SELECT * from servicealerts_informed where servicealert_id = :servicealert_id'; + + if ($filter_class != '') { + $query .= ' AND informed_class = :informed_class '; + } + if ($filter_id != '') { + $query .= ' AND informed_id = :informed_id '; + } + // debug($query, 'database'); + $query = $conn->prepare($query); + if ($filter_class != '') { + $query->bindParam(':informed_class', $filter_class); + } + if ($filter_id != '') { + $query->bindParam(':informed_id', $filter_id); + } + $query->bindParam(':servicealert_id', $id); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function deleteInformedAlert($serviceAlertID, $class, $id) { + global $conn; + $query = 'DELETE from servicealerts_informed where servicealert_id = :servicealert_id and informed_class = :informed_class AND informed_id = :informed_id'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':servicealert_id', $serviceAlertID); + $query->bindParam(':informed_class', $class); + $query->bindParam(':informed_id', $id); + $query->execute(); + print_r($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return null; +} + +function addInformedAlert($serviceAlertID, $class, $id, $action) { + global $conn; + $query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id, informed_action) + VALUES(:servicealert_id ,:informed_class, :informed_id, :informed_action)'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':servicealert_id', $serviceAlertID); + $query->bindParam(':informed_class', $class); + $query->bindParam(':informed_id', $id); + $query->bindParam(':informed_action', $action); + $query->execute(); + + print_r($conn->errorInfo()); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return null; +} + --- a/include/db/stop-dao.inc.php +++ b/include/db/stop-dao.inc.php @@ -1,144 +1,249 @@ 0) { - if (sizeof($conditions) > 1) { - $query.= " Where " . implode(" AND ", $conditions) . " "; - } - else { - $query.= " Where " . $conditions[0] . " "; - } - } - $query.= " order by stop_name;"; - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} -function getNearbyStops($lat, $lng, $limit = "", $distance = 1000) -{ - if ($lat == null || $lng == null) return Array(); - if ($limit != "") $limit = " LIMIT $limit "; - global $conn; - $query = "Select *, ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE) as distance - from stops WHERE ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), $distance, FALSE) - order by distance $limit;"; - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} -function getStopsBySuburb($suburb) -{ - global $conn; - $query = "Select * from stops where zone_id LIKE '%$suburb;%' order by stop_name;"; - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} -function getStopRoutes($stopID, $service_period) -{ - if ($service_period == "") $service_period = service_period(); - global $conn; - $query = "SELECT service_id,trips.route_id,route_short_name,route_long_name + +/* + * Copyright 2010,2011 Alexander Sadleir + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +function getStop($stopID) { + global $conn; + $query = 'Select * from stops where stop_id = :stopID LIMIT 1'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':stopID', $stopID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function getStops($firstLetter = '', $startsWith = '') { + global $conn; + $conditions = Array(); + if ($firstLetter != '') + $conditions[] = 'substr(stop_name,1,1) = :firstLetter'; + if ($startsWith != '') + $conditions[] = 'stop_name like :startsWith'; + $query = 'Select * from stops'; + if (sizeof($conditions) > 0) { + if (sizeof($conditions) > 1) { + $query .= ' Where ' . implode(' AND ', $conditions) . ' '; + } else { + $query .= ' Where ' . $conditions[0] . ' '; + } + } + $query .= ' order by stop_name;'; + debug($query, 'database'); + $query = $conn->prepare($query); + if ($firstLetter != '') + $query->bindParam(':firstLetter', $firstLetter); + + if ($startsWith != '') { + $startsWith = $startsWith . '%'; + $query->bindParam(':startsWith', $startsWith); + } + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getNearbyStops($lat, $lng, $limit = '', $distance = 1000) { + if ($lat == null || $lng == null) + return Array(); + if ($limit != '') + $limitSQL = ' LIMIT :limit '; + global $conn; + $query = 'Select *, ST_Distance(position, ST_GeographyFromText(\'SRID=4326;POINT('.$lng.' '.$lat.')\'), FALSE) as distance + from stops WHERE ST_DWithin(position, ST_GeographyFromText(\'SRID=4326;POINT('.$lng.' '.$lat.')\'), :distance, FALSE) + order by distance '.$limitSQL; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':distance', $distance); + $query->bindParam(':limit', $limit); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopsByName($name) { + global $conn; + $query = 'Select * from stops where stop_name LIKE :name;'; + debug($query, 'database'); + $query = $conn->prepare($query); + $name = $name . '%'; + $query->bindParam(':name', $name); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopsBySuburb($suburb) { + global $conn; + $query = 'Select * from stops where stop_desc LIKE :suburb order by stop_name;'; + debug($query, 'database'); + $query = $conn->prepare($query); + $suburb = '%
Suburb: %' . $suburb . '%'; + $query->bindParam(':suburb', $suburb); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopsByStopCode($stop_code, $startsWith = '') { + global $conn; + $query = 'Select * from stops where (stop_code = :stop_code OR stop_code LIKE :stop_code2)'; + if ($startsWith != '') + $query .= ' AND stop_name like :startsWith'; + + debug($query, 'database'); + $query = $conn->prepare($query); + + $query->bindParam(':stop_code', $stop_code); + $stop_code2 = $stop_code . '%'; + $query->bindParam(':stop_code2', $stop_code2); + if ($startsWith != '') { + $startsWith = $startsWith . '%'; + $query->bindParam(':startsWith', $startsWith); + } + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopRoutes($stopID, $service_period) { + if ($service_period == '') { + $service_period = service_period(); + } + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + global $conn; + $query = 'SELECT distinct service_id,trips.route_id,route_short_name,route_long_name FROM stop_times join trips on trips.trip_id = -stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_id = '$stopID' AND service_id='$service_period'"; - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} -function getStopTrips($stopID, $service_period = "", $afterTime = "") -{ - if ($service_period == "") $service_period = service_period(); - $afterCondition = "AND arrival_time > '$afterTime'"; - global $conn; - if ($afterTime != "") { - $query = " SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name, end_times.arrival_time as end_time +stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_id = :stopID +AND (service_id=:service_periodA OR service_id=:service_periodB)'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':service_periodA', $sidA); + $query->bindParam(':service_periodB', $sidB); + $query->bindParam(':stopID', $stopID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopTrips($stopID, $service_period = '', $afterTime = '', $limit = '', $route_short_name = '') { + if ($service_period == '') { + $service_period = service_period(); + } + $service_ids = service_ids($service_period); + $sidA = $service_ids[0]; + $sidB = $service_ids[1]; + $limitSQL = ''; + if ($limit != '') + $limitSQL .= ' LIMIT :limit '; + + global $conn; + if ($afterTime != '') { + $query = ' SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,trips.direction_id,trips.trip_headsign,route_short_name,route_long_name,end_times.arrival_time as end_time FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id , (SELECT trip_id,max(arrival_time) as arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times -WHERE stop_times.stop_id = '$stopID' +WHERE stop_times.stop_id = :stopID AND stop_times.trip_id = end_times.trip_id -AND service_id='$service_period' -AND end_times.arrival_time > '$afterTime' -ORDER BY end_time"; - } - else { - $query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name +AND (service_id=:service_periodA OR service_id=:service_periodB) ' . ($route_short_name != '' ? ' AND route_short_name = :route_short_name ' : '') . ' +AND end_times.arrival_time > :afterTime +ORDER BY end_time '.$limitSQL; + } else { + $query = 'SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id -WHERE stop_times.stop_id = '$stopID' -AND service_id='$service_period' -ORDER BY arrival_time"; - } - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} -function getStopTripsWithTimes($stopID, $time = "", $service_period = "", $time_range = "", $limit = "") -{ - if ($service_period == "") $service_period = service_period(); - if ($time_range == "") $time_range = (24 * 60 * 60); - if ($time == "") $time = current_time(); - if ($limit == "") $limit = 10; - $trips = getStopTrips($stopID, $service_period, $time); - $timedTrips = Array(); - if ($trips && sizeof($trips) > 0) { - foreach ($trips as $trip) { - if ($trip['arrival_time'] != "") { - if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) { - $timedTrips[] = $trip; - } - } - else { - $timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']); - if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) { - $timedTrips[] = $timedTrip; - } - } - if (sizeof($timedTrips) > $limit) break; - } - sktimesort($timedTrips, "arrival_time", true); +WHERE stop_times.stop_id = :stopID +AND (service_id=:service_periodA OR service_id=:service_periodB) ' . ($route_short_name != '' ? ' AND route_short_name = :route_short_name ' : '') . ' +ORDER BY arrival_time '.$limitSQL; + } + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':service_periodA', $sidA); + $query->bindParam(':service_periodB', $sidB); + $query->bindParam(':stopID', $stopID); + if ($limit != '') + $query->bindParam(':limit', $limit); + if ($afterTime != '') + $query->bindParam(':afterTime', $afterTime); + if ($route_short_name != '') + $query->bindParam(':route_short_name', $route_short_name); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getStopTripsWithTimes($stopID, $time = '', $service_period = '', $time_range = '', $limit = '') { + if ($service_period == '') + $service_period = service_period(); + if ($time_range == '') + $time_range = (24 * 60 * 60); + if ($time == '') + $time = current_time(); + if ($limit == '') + $limit = 10; + $trips = getStopTrips($stopID, $service_period, $time); + $timedTrips = Array(); + if ($trips && sizeof($trips) > 0) { + foreach ($trips as $trip) { + if ($trip['arrival_time'] != '') { + if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) { + $timedTrips[] = $trip; + } + } else { + $timedTrip = getTripAtStop($trip['trip_id'], $trip['stop_sequence']); + if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) { + $timedTrips[] = $timedTrip; + } + } + if (sizeof($timedTrips) > $limit) + break; } - return $timedTrips; -} -?> + sktimesort($timedTrips, 'arrival_time', true); + } + return $timedTrips; +} + --- a/include/db/trip-dao.inc.php +++ b/include/db/trip-dao.inc.php @@ -1,186 +1,243 @@ prepare($query); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + + return Array(); + } + return $query->fetch(PDO :: FETCH_ASSOC); +} + +function getTripStops($tripID) { + global $conn; + $query = 'SELECT stops.stop_id, stop_name, ST_AsKML(position) as positionkml, + stop_sequence, trips.trip_id +FROM stop_times +join trips on trips.trip_id = stop_times.trip_id +join stops on stops.stop_id = stop_times.stop_id +WHERE trips.trip_id = :tripID ORDER BY stop_sequence'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function getTripHasStop($tripID, $stopID) { + global $conn; + $query = 'SELECT stop_id +FROM stop_times +join trips on trips.trip_id = stop_times.trip_id +WHERE trips.trip_id = :tripID and stop_times.stop_id = :stopID'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':tripID', $tripID); + $query->bindParam(':stopID', $stopID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return ($query->fetchColumn() > 0); +} + +function getTripShape($tripID) { + global $conn; + $query = 'SELECT ST_AsKML(ST_MakeLine(geometry(a.shape_pt))) as the_route +FROM (SELECT shapes.shape_id,shape_pt from shapes +inner join trips on shapes.shape_id = trips.shape_id +WHERE trips.trip_id = :tripID ORDER BY shape_pt_sequence) as a group by a.shape_id'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchColumn(0); +} + +function getTripStopTimes($tripID) { + global $conn; + $query = 'SELECT stop_times.trip_id,trip_headsign,arrival_time,stop_times.stop_id + ,stop_lat,stop_lon,stop_name,stop_desc,stop_code, stop_sequence,service_id,trips.route_id,route_short_name,route_long_name FROM stop_times join trips on trips.trip_id = stop_times.trip_id join routes on trips.route_id = routes.route_id join stops on stops.stop_id = stop_times.stop_id -WHERE trips.trip_id = '$tripID' $range ORDER BY stop_sequence"; - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - $stopTimes = pg_fetch_all($result); - $cur_timepoint = Array(); - $next_timepoint = Array(); - $distance_between_timepoints = 0.0; - $distance_traveled_between_timepoints = 0.0; - $rv = Array(); - foreach ($stopTimes as $i => $stopTime) { - if ($stopTime['arrival_time'] != "") { - // is timepoint - $cur_timepoint = $stopTime; - $distance_between_timepoints = 0.0; - $distance_traveled_between_timepoints = 0.0; - if ($i + 1 < sizeof($stopTimes)) { - $k = $i + 1; - $distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); - while ($stopTimes[$k]["arrival_time"] == "" && $k + 1 < sizeof($stopTimes)) { - $k += 1; - //echo "k".$k; - $distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); - } - $next_timepoint = $stopTimes[$k]; - $rv[] = $stopTime; - } - } - else { - // is untimed point - //echo "i".$i; - $distance_traveled_between_timepoints += distance($stopTimes[$i - 1]["stop_lat"], $stopTimes[$i - 1]["stop_lon"], $stopTimes[$i]["stop_lat"], $stopTimes[$i]["stop_lon"]); - //echo "$distance_traveled_between_timepoints / $distance_between_timepoints
"; - $distance_percent = $distance_traveled_between_timepoints / $distance_between_timepoints; - if ($next_timepoint["arrival_time"] != "") { - $total_time = strtotime($next_timepoint["arrival_time"]) - strtotime($cur_timepoint["arrival_time"]); - //echo strtotime($next_timepoint["arrival_time"])." - ".strtotime($cur_timepoint["arrival_time"])."
"; - $time_estimate = ($distance_percent * $total_time) + strtotime($cur_timepoint["arrival_time"]); - $stopTime["arrival_time"] = date("H:i:s", $time_estimate); - } else { - $stopTime["arrival_time"] = $cur_timepoint["arrival_time"]; - } - $rv[] = $stopTime; - //var_dump($rv); - } - } - return $rv; -} -function getTimeInterpolatedTripAtStop($tripID, $stop_sequence) -{ - global $conn; - // limit interpolation to between nearest actual points. - $prevTimePoint = pg_fetch_assoc(pg_query($conn," SELECT trip_id,stop_id, - stop_sequence -FROM stop_times -WHERE trip_id = '$tripID' and stop_sequence < $stop_sequence and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence DESC LIMIT 1")); - $nextTimePoint = pg_fetch_assoc(pg_query($conn," SELECT trip_id,stop_id, - stop_sequence -FROM stop_times -WHERE trip_id = '$tripID' and stop_sequence > $stop_sequence and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence LIMIT 1")); - $range = "AND stop_sequence >= '{$prevTimePoint['stop_sequence']}' AND stop_sequence <= '{$nextTimePoint['stop_sequence']}'"; - foreach (getTimeInterpolatedTrip($tripID,$range) as $tripStop) { - if ($tripStop['stop_sequence'] == $stop_sequence) return $tripStop; - } - return Array(); -} -function getTripStartTime($tripID) -{ - global $conn; - $query = "Select * from stop_times - where trip_id = '$tripID' +WHERE trips.trip_id = :tripID ORDER BY stop_sequence'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $stopTimes = $query->fetchAll(); + return $stopTimes; +} + +function getTripAtStop($tripID, $stop_sequence) { + global $conn; + foreach (getTripStopTimes($tripID) as $tripStop) { + if ($tripStop['stop_sequence'] == $stop_sequence) + return $tripStop; + } + return Array(); +} + +function getTripStartTime($tripID) { + global $conn; + $query = 'Select * from stop_times + where trip_id = :tripID AND arrival_time IS NOT NULL - AND stop_sequence = '1'"; - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - $r = pg_fetch_assoc($result); - return $r['arrival_time']; -} -function getActiveTrips($time) -{ - global $conn; - if ($time == "") $time = current_time(); - $query = "Select distinct stop_times.trip_id, start_times.arrival_time as start_time, end_times.arrival_time as end_time from stop_times, (SELECT trip_id,arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL -AND stop_sequence = '1') as start_times, (SELECT trip_id,max(arrival_time) as arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times -WHERE start_times.trip_id = end_times.trip_id AND stop_times.trip_id = end_times.trip_id AND $time > start_times.arrival_time AND $time < end_times.arrival_time"; - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} - -function viaPoints($tripid, $stop_sequence = "") -{ - global $conn; - $query = "SELECT stops.stop_id, stop_name, arrival_time + AND stop_sequence = \'1\''; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r['arrival_time']; +} + +function getTripEndTime($tripID) { + global $conn; + $query = 'SELECT trip_id,max(arrival_time) as arrival_time from stop_times + WHERE stop_times.arrival_time IS NOT NULL and trip_id = :tripID group by trip_id'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r['arrival_time']; +} + +function getTripStartingPoint($tripID) { + global $conn; + $query = 'SELECT stops.stop_id, stops.stop_name, stops.stop_desc + from stop_times inner join stops on stop_times.stop_id = stops.stop_id + WHERE trip_id = :tripID and stop_sequence = \'1\' limit 1'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; +} + +function getTripDestination($tripID) { + global $conn; + $query = 'SELECT stops.stop_id, stops.stop_name, stops.stop_desc + from stop_times inner join stops on stop_times.stop_id = stops.stop_id + WHERE trip_id = :tripID order by stop_sequence desc limit 1'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + $r = $query->fetch(PDO :: FETCH_ASSOC); + return $r; +} + +function getActiveTrips($time='') { + global $conn; + if ($time == '') { + $time = current_time(); + } + $query = 'Select distinct stop_times.trip_id, start_times.arrival_time as start_time, end_times.arrival_time as end_time from stop_times, (SELECT trip_id,arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL +AND stop_sequence = \'1\') as start_times, (SELECT trip_id,max(arrival_time) as arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times +WHERE start_times.trip_id = end_times.trip_id AND stop_times.trip_id = end_times.trip_id AND :time > start_times.arrival_time AND :time < end_times.arrival_time'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':time', $time); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} +function getTripLastStop($tripid, $time='') { + global $conn; + if ($time == '') { + $time = current_time(); + } + $query = 'Select trip_id,stops.stop_id,stop_sequence,stop_code,stop_name,stop_lat,stop_lon,arrival_time,(arrival_time - :time::time) as time_diff from stop_times inner join stops on stop_times.stop_id = stops.stop_id WHERE trip_id = :tripid and arrival_time >= :time::time order by stop_sequence limit 2'; + debug($query, 'database'); + $query = $conn->prepare($query); + $query->bindParam(':time', $time); + $query->bindParam(':tripid', $tripid); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} + +function viaPoints($tripID, $stop_sequence = '') { + global $conn; + $query = 'SELECT stops.stop_id, stop_name, arrival_time FROM stop_times join stops on stops.stop_id = stop_times.stop_id -WHERE stop_times.trip_id = '$tripid' -".($stop_sequence != "" ? "AND stop_sequence > '$stop_sequence'" : ""). -"AND substr(stop_code,1,2) != 'Wj' ORDER BY stop_sequence"; - debug($query, "database"); - $result = pg_query($conn, $query); - if (!$result) { - databaseError(pg_result_error($result)); - return Array(); - } - return pg_fetch_all($result); -} -function viaPointNames($tripid, $stop_sequence = "") -{ - $viaPointNames = Array(); - foreach(viaPoints($tripid, $stop_sequence) as $point) { - $viaPointNames[] = $point['stop_name']; - } - return r_implode(", ", $viaPointNames); -} -?> +WHERE stop_times.trip_id = :tripID +' . ($stop_sequence != '' ? ' AND stop_sequence > :stop_sequence ' : '') . ' ORDER BY stop_sequence'; + debug($query, 'database'); + $query = $conn->prepare($query); + if ($stop_sequence != '') + $query->bindParam(':stop_sequence', $stop_sequence); + $query->bindParam(':tripID', $tripID); + $query->execute(); + if (!$query) { + databaseError($conn->errorInfo()); + return Array(); + } + return $query->fetchAll(); +} --- a/index.php +++ b/index.php @@ -1,32 +1,45 @@
-
-
-

busness time


Canberra Bus Timetables and Trip Planner -
- - Launch Trip Planner... - - -Busness R&D'; -include_footer(true) -?> - +
+
+

busness time


Canberra Bus Timetables and Trip Planner +
+ + Launch Trip Planner... + + + + MyWay Balance and Timeliness Survey Results + --- /dev/null +++ b/js/FlashCanvas --- /dev/null +++ b/js/LAB.min.js @@ -1,1 +1,5 @@ - +/*! LAB.js (LABjs :: Loading And Blocking JavaScript) + v2.0.1 (c) Kyle Simpson + MIT License +*/ +(function(o){var K=o.$LAB,y="UseLocalXHR",z="AlwaysPreserveOrder",u="AllowDuplicates",A="CacheBust",B="BasePath",C=/^[^?#]*\//.exec(location.href)[0],D=/^\w+\:\/\/\/?[^\/]+/.exec(C)[0],i=document.head||document.getElementsByTagName("head"),L=(o.opera&&Object.prototype.toString.call(o.opera)=="[object Opera]")||("MozAppearance"in document.documentElement.style),q=document.createElement("script"),E=typeof q.preload=="boolean",r=E||(q.readyState&&q.readyState=="uninitialized"),F=!r&&q.async===true,M=!r&&!F&&!L;function G(a){return Object.prototype.toString.call(a)=="[object Function]"}function H(a){return Object.prototype.toString.call(a)=="[object Array]"}function N(a,c){var b=/^\w+\:\/\//;if(/^\/\/\/?/.test(a)){a=location.protocol+a}else if(!b.test(a)&&a.charAt(0)!="/"){a=(c||"")+a}return b.test(a)?a:((a.charAt(0)=="/"?D:C)+a)}function s(a,c){for(var b in a){if(a.hasOwnProperty(b)){c[b]=a[b]}}return c}function O(a){var c=false;for(var b=0;b0){for(var a=0;a=0;){d=n.shift();a=a[d.type].apply(null,d.args)}return a},noConflict:function(){o.$LAB=K;return m},sandbox:function(){return J()}};return m}o.$LAB=J();(function(a,c,b){if(document.readyState==null&&document[a]){document.readyState="loading";document[a](c,b=function(){document.removeEventListener(c,b,false);document.readyState="complete"},false)}})("addEventListener","DOMContentLoaded")})(this); --- a/js/flotr/flotr-0.2.0-alpha.js +++ /dev/null @@ -1,2 +1,1 @@ -//Flotr 0.2.0-alpha Copyright (c) 2009 Bas Wenneker, , MIT License. -var Flotr={version:"0.2.0-alpha",author:"Bas Wenneker",website:"http://www.solutoire.com",_registeredTypes:{lines:"drawSeriesLines",points:"drawSeriesPoints",bars:"drawSeriesBars",candles:"drawSeriesCandles",pie:"drawSeriesPie"},register:function(A,B){Flotr._registeredTypes[A]=B+""},draw:function(B,D,A,C){C=C||Flotr.Graph;return new C(B,D,A)},getSeries:function(A){return A.collect(function(C){var B,C=(C.data)?Object.clone(C):{data:C};for(B=C.data.length-1;B>-1;--B){C.data[B][1]=(C.data[B][1]===null?null:parseFloat(C.data[B][1]))}return C})},merge:function(D,B){var A=B||{};for(var C in D){A[C]=(D[C]!=null&&typeof (D[C])=="object"&&!(D[C].constructor==Array||D[C].constructor==RegExp)&&!Object.isElement(D[C]))?Flotr.merge(D[C],B[C]):A[C]=D[C]}return A},getTickSize:function(E,D,A,B){var H=(A-D)/E;var G=Flotr.getMagnitude(H);var C=H/G;var F=10;if(C<1.5){F=1}else{if(C<2.25){F=2}else{if(C<3){F=((B==0)?2:2.5)}else{if(C<7.5){F=5}}}}return F*G},defaultTickFormatter:function(A){return A+""},defaultTrackFormatter:function(A){return"("+A.x+", "+A.y+")"},defaultPieLabelFormatter:function(A){return(A.fraction*100).toFixed(2)+"%"},getMagnitude:function(A){return Math.pow(10,Math.floor(Math.log(A)/Math.LN10))},toPixel:function(A){return Math.floor(A)+0.5},toRad:function(A){return -A*(Math.PI/180)},parseColor:function(D){if(D instanceof Flotr.Color){return D}var A,C=Flotr.Color;if((A=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(D))){return new C(parseInt(A[1]),parseInt(A[2]),parseInt(A[3]))}if((A=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(D))){return new C(parseInt(A[1]),parseInt(A[2]),parseInt(A[3]),parseFloat(A[4]))}if((A=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(D))){return new C(parseFloat(A[1])*2.55,parseFloat(A[2])*2.55,parseFloat(A[3])*2.55)}if((A=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(D))){return new C(parseFloat(A[1])*2.55,parseFloat(A[2])*2.55,parseFloat(A[3])*2.55,parseFloat(A[4]))}if((A=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(D))){return new C(parseInt(A[1],16),parseInt(A[2],16),parseInt(A[3],16))}if((A=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(D))){return new C(parseInt(A[1]+A[1],16),parseInt(A[2]+A[2],16),parseInt(A[3]+A[3],16))}var B=D.strip().toLowerCase();if(B=="transparent"){return new C(255,255,255,0)}return((A=C.lookupColors[B]))?new C(A[0],A[1],A[2]):false},extractColor:function(B){var A;do{A=B.getStyle("background-color").toLowerCase();if(!(A==""||A=="transparent")){break}B=B.up(0)}while(!B.nodeName.match(/^body$/i));return(A=="rgba(0, 0, 0, 0)")?"transparent":A}};Flotr.Graph=Class.create({initialize:function(B,C,A){this.el=$(B);if(!this.el){throw"The target container doesn't exist"}this.data=C;this.series=Flotr.getSeries(C);this.setOptions(A);this.lastMousePos={pageX:null,pageY:null};this.selection={first:{x:-1,y:-1},second:{x:-1,y:-1}};this.prevSelection=null;this.selectionInterval=null;this.ignoreClick=false;this.prevHit=null;this.constructCanvas();this.initEvents();this.findDataRanges();this.calculateTicks(this.axes.x);this.calculateTicks(this.axes.x2);this.calculateTicks(this.axes.y);this.calculateTicks(this.axes.y2);this.calculateSpacing();this.draw();this.insertLegend();if(this.options.spreadsheet.show){this.constructTabs()}},setOptions:function(B){var P={colors:["#00A8F0","#C0D800","#CB4B4B","#4DA74D","#9440ED"],title:null,subtitle:null,legend:{show:true,noColumns:1,labelFormatter:Prototype.K,labelBoxBorderColor:"#CCCCCC",labelBoxWidth:14,labelBoxHeight:10,labelBoxMargin:5,container:null,position:"nw",margin:5,backgroundColor:null,backgroundOpacity:0.85},xaxis:{ticks:null,showLabels:true,labelsAngle:0,title:null,titleAngle:0,noTicks:5,tickFormatter:Flotr.defaultTickFormatter,tickDecimals:null,min:null,max:null,autoscaleMargin:0,color:null},x2axis:{},yaxis:{ticks:null,showLabels:true,labelsAngle:0,title:null,titleAngle:90,noTicks:5,tickFormatter:Flotr.defaultTickFormatter,tickDecimals:null,min:null,max:null,autoscaleMargin:0,color:null},y2axis:{titleAngle:270},points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#FFFFFF",fillOpacity:0.4},lines:{show:false,lineWidth:2,fill:false,fillColor:null,fillOpacity:0.4},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,fillOpacity:0.4,horizontal:false,stacked:false},candles:{show:false,lineWidth:1,wickLineWidth:1,candleWidth:0.6,fill:true,upFillColor:"#00A8F0",downFillColor:"#CB4B4B",fillOpacity:0.5,barcharts:false},pie:{show:false,lineWidth:1,fill:true,fillColor:null,fillOpacity:0.6,explode:6,sizeRatio:0.6,startAngle:Math.PI/4,labelFormatter:Flotr.defaultPieLabelFormatter,pie3D:false,pie3DviewAngle:(Math.PI/2*0.8),pie3DspliceThickness:20},grid:{color:"#545454",backgroundColor:null,tickColor:"#DDDDDD",labelMargin:3,verticalLines:true,horizontalLines:true,outlineWidth:2},selection:{mode:null,color:"#B6D9FF",fps:20},mouse:{track:false,position:"se",relative:false,trackFormatter:Flotr.defaultTrackFormatter,margin:5,lineColor:"#FF3F19",trackDecimals:1,sensibility:2,radius:3},shadowSize:4,defaultType:"lines",HtmlText:true,fontSize:7.5,spreadsheet:{show:false,tabGraphLabel:"Graph",tabDataLabel:"Data",toolbarDownload:"Download CSV",toolbarSelectAll:"Select all"}};P.x2axis=Object.extend(Object.clone(P.xaxis),P.x2axis);P.y2axis=Object.extend(Object.clone(P.yaxis),P.y2axis);this.options=Flotr.merge((B||{}),P);this.axes={x:{options:this.options.xaxis,n:1},x2:{options:this.options.x2axis,n:2},y:{options:this.options.yaxis,n:1},y2:{options:this.options.y2axis,n:2}};var H=[],C=[],K=this.series.length,N=this.series.length,D=this.options.colors,A=[],G=0,M,J,I,O,E;for(J=N-1;J>-1;--J){M=this.series[J].color;if(M!=null){--N;if(Object.isNumber(M)){H.push(M)}else{A.push(Flotr.parseColor(M))}}}for(J=H.length-1;J>-1;--J){N=Math.max(N,H[J]+1)}for(J=0;C.length=D.length){J=0;++G}}for(J=0,I=0;J'+F+"
").select(".flotr-dummy-div")[0];dim=A.getDimensions();A.remove();return dim}},loadDataGrid:function(){if(this.seriesData){return this.seriesData}var A=this.series;var B=[];for(i=0;i"];var F=[''];F.push(" ");for(D=0;D'+(L[D].label||String.fromCharCode(65+D))+"");C.push("")}F.push("");for(B=0;B");for(D=0;D"+G+"")}F.push("")}C.push("");K.update(C.join("")+F.join(""));if(!Prototype.Browser.IE){K.select("td").each(function(N){N.observe("mouseover",function(O){N=O.element();var P=N.previousSiblings();K.select("th[scope=col]")[P.length-1].addClassName("hover");K.select("colgroup col")[P.length].addClassName("hover")});N.observe("mouseout",function(){K.select("colgroup col.hover, th.hover").each(function(O){O.removeClassName("hover")})})})}var H=new Element("div",{className:"flotr-datagrid-toolbar"}).insert(new Element("button",{type:"button",className:"flotr-datagrid-toolbar-button"}).update(this.options.spreadsheet.toolbarDownload).observe("click",this.downloadCSV.bind(this))).insert(new Element("button",{type:"button",className:"flotr-datagrid-toolbar-button"}).update(this.options.spreadsheet.toolbarSelectAll).observe("click",this.selectAllData.bind(this)));var A=new Element("div",{className:"flotr-datagrid-container",style:"left:0px;top:0px;width:"+this.canvasWidth+"px;height:"+this.canvasHeight+"px;overflow:auto;"});A.insert(H);K.wrap(A.hide());this.el.insert(A);return K},selectAllData:function(){if(this.tabs){var B,A,E,D,C=this.constructDataGrid();this.showTab("data");(function(){if((E=C.ownerDocument)&&(D=E.defaultView)&&D.getSelection&&E.createRange&&(B=window.getSelection())&&B.removeAllRanges){A=E.createRange();A.selectNode(C);B.removeAllRanges();B.addRange(A)}else{if(document.body&&document.body.createTextRange&&(A=document.body.createTextRange())){A.moveToElementText(C);A.select()}}}).defer();return true}else{return false}},downloadCSV:function(){var D,A='"x"',C=this.series,E=this.loadDataGrid();for(D=0;D0){var C,A,D,H,F,B,I,E;for(C=0;C0&&!J[C].hide){if(!I.used){I.datamin=I.datamax=B[0][0]}if(!E.used){E.datamin=E.datamax=B[0][1]}I.used=true;E.used=true;for(D=B.length-1;D>-1;--D){H=B[D][0];if(HI.datamax){I.datamax=H}}for(A=1;AE.datamax){E.datamax=F}}}}}}}this.findXAxesValues();this.calculateRange(G.x);this.extendXRangeIfNeededByBar(G.x);if(G.x2.used){this.calculateRange(G.x2);this.extendXRangeIfNeededByBar(G.x2)}this.calculateRange(G.y);this.extendYRangeIfNeededByBar(G.y);if(G.y2.used){this.calculateRange(G.y2);this.extendYRangeIfNeededByBar(G.y2)}},calculateRange:function(D){var F=D.options,C=F.min!=null?F.min:D.datamin,A=F.max!=null?F.max:D.datamax,E;if(A-C==0){var B=(A==0)?1:0.01;C-=B;A+=B}D.tickSize=Flotr.getTickSize(F.noTicks,C,A,F.tickDecimals);if(F.min==null){E=F.autoscaleMargin;if(E!=0){C-=D.tickSize*E;if(C<0&&D.datamin>=0){C=0}C=D.tickSize*Math.floor(C/D.tickSize)}}if(F.max==null){E=F.autoscaleMargin;if(E!=0){A+=D.tickSize*E;if(A>0&&D.datamax<=0){A=0}A=D.tickSize*Math.ceil(A/D.tickSize)}}D.min=C;D.max=A},extendXRangeIfNeededByBar:function(A){if(A.options.max==null){var D=A.max,B,I,F,E,H=[],C=null;for(B=0;BD)||(E.candleWidth+A.datamax>D)){D=A.max+I.bars.barWidth}if(F.stacked&&F.horizontal){for(j=0;jD)||(E.candleWidth+A.datamax>D)){D=A.max+F.barWidth}if(F.stacked&&!F.horizontal){for(j=0;j-1;--i){s=this.series[i];s.xaxis.values=s.xaxis.values||[];for(j=s.data.length-1;j>-1;--j){s.xaxis.values[s.data[j][0]]={}}}},calculateTicks:function(D){var B=D.options,E,H;D.ticks=[];if(B.ticks){var G=B.ticks,I,F;if(Object.isFunction(G)){G=G({min:D.min,max:D.max})}for(E=0;E1)?I[1]:B.tickFormatter(H)}else{H=I;F=B.tickFormatter(H)}D.ticks[E]={v:H,label:F}}}else{var A=D.tickSize*Math.ceil(D.min/D.tickSize),C;for(E=0;A+E*D.tickSize<=D.max;++E){H=A+E*D.tickSize;C=B.tickDecimals;if(C==null){C=1-Math.floor(Math.log(D.tickSize)/Math.LN10)}if(C<0){C=0}H=H.toFixed(C);D.ticks.push({v:H,label:B.tickFormatter(H)})}}},calculateSpacing:function(){var L=this.axes,N=this.options,H=this.series,D=N.grid.labelMargin,M=L.x,A=L.x2,J=L.y,K=L.y2,F=2,G,E,C,I;[M,A,J,K].each(function(P){var O="";if(P.options.showLabels){for(G=0;GO.length){O=P.ticks[G].label}}}P.maxLabel=this.getTextDimensions(O,{size:N.fontSize,angle:Flotr.toRad(P.options.labelsAngle)},"font-size:smaller;","flotr-grid-label");P.titleSize=this.getTextDimensions(P.options.title,{size:N.fontSize*1.2,angle:Flotr.toRad(P.options.titleAngle)},"font-weight:bold;","flotr-axis-title")},this);I=this.getTextDimensions(N.title,{size:N.fontSize*1.5},"font-size:1em;font-weight:bold;","flotr-title");this.titleHeight=I.height;I=this.getTextDimensions(N.subtitle,{size:N.fontSize},"font-size:smaller;","flotr-subtitle");this.subtitleHeight=I.height;if(N.show){F=Math.max(F,N.points.radius+N.points.lineWidth/2)}for(E=0;E'];D=H.x;if(D.options.showLabels){for(E=0;E'+G.label+"
")}}D=H.x2;if(D.options.showLabels&&D.used){for(E=0;E'+G.label+"
")}}D=H.y;if(D.options.showLabels){for(E=0;E'+G.label+"
")}}D=H.y2;if(D.options.showLabels&&D.used){I.save();I.strokeStyle=D.options.color||J.grid.color;I.beginPath();for(E=0;E'+G.label+"");I.moveTo(this.plotOffset.left+this.plotWidth-8,this.plotOffset.top+this.tVert(G.v,D));I.lineTo(this.plotOffset.left+this.plotWidth,this.plotOffset.top+this.tVert(G.v,D))}I.stroke();I.restore()}F.push("");this.el.insert(F.join(""))}}},drawTitles:function(){var D,C=this.options,F=C.grid.labelMargin,B=this.ctx,A=this.axes;if(!C.HtmlText&&this.textEnabled){var E={size:C.fontSize,color:C.grid.color,halign:"c"};if(C.subtitle){B.drawText(C.subtitle,this.plotOffset.left+this.plotWidth/2,this.titleHeight+this.subtitleHeight-2,E)}E.weight=1.5;E.size*=1.5;if(C.title){B.drawText(C.title,this.plotOffset.left+this.plotWidth/2,this.titleHeight-2,E)}E.weight=1.8;E.size*=0.8;E.adjustAlign=true;if(A.x.options.title&&A.x.used){E.halign="c";E.valign="t";E.angle=Flotr.toRad(A.x.options.titleAngle);B.drawText(A.x.options.title,this.plotOffset.left+this.plotWidth/2,this.plotOffset.top+A.x.maxLabel.height+this.plotHeight+2*F,E)}if(A.x2.options.title&&A.x2.used){E.halign="c";E.valign="b";E.angle=Flotr.toRad(A.x2.options.titleAngle);B.drawText(A.x2.options.title,this.plotOffset.left+this.plotWidth/2,this.plotOffset.top-A.x2.maxLabel.height-2*F,E)}if(A.y.options.title&&A.y.used){E.halign="r";E.valign="m";E.angle=Flotr.toRad(A.y.options.titleAngle);B.drawText(A.y.options.title,this.plotOffset.left-A.y.maxLabel.width-2*F,this.plotOffset.top+this.plotHeight/2,E)}if(A.y2.options.title&&A.y2.used){E.halign="l";E.valign="m";E.angle=Flotr.toRad(A.y2.options.titleAngle);B.drawText(A.y2.options.title,this.plotOffset.left+this.plotWidth+A.y2.maxLabel.width+2*F,this.plotOffset.top+this.plotHeight/2,E)}}else{D=['
'];if(C.title){D.push('
'+C.title+"
")}if(C.subtitle){D.push('
'+C.subtitle+"
")}D.push("
");D.push('
');if(A.x.options.title&&A.x.used){D.push('
'+A.x.options.title+"
")}if(A.x2.options.title&&A.x2.used){D.push('
'+A.x2.options.title+"
")}if(A.y.options.title&&A.y.used){D.push('
'+A.y.options.title+"
")}if(A.y2.options.title&&A.y2.used){D.push('
'+A.y2.options.title+"
")}D.push("
");this.el.insert(D.join(""))}},drawSeries:function(A){A=A||this.series;var C=false;for(var B in Flotr._registeredTypes){if(A[B]&&A[B].show){this[Flotr._registeredTypes[B]](A);C=true}}if(!C){this[Flotr._registeredTypes[this.options.defaultType]](A)}},plotLine:function(I,F){var O=this.ctx,A=I.xaxis,K=I.yaxis,J=this.tHoz.bind(this),M=this.tVert.bind(this),H=I.data;if(H.length<2){return }var E=J(H[0][0],A),D=M(H[0][1],K)+F;O.beginPath();O.moveTo(E,D);for(var G=0;G=L&&N>K.max){if(L>K.max){continue}C=(K.max-N)/(L-N)*(B-C)+C;N=K.max}else{if(L>=N&&L>K.max){if(N>K.max){continue}B=(K.max-N)/(L-N)*(B-C)+C;L=K.max}}if(C<=B&&C=B&&C>A.max){if(B>A.max){continue}N=(A.max-C)/(B-C)*(L-N)+N;C=A.max}else{if(B>=C&&B>A.max){if(C>A.max){continue}L=(A.max-C)/(B-C)*(L-N)+N;B=A.max}}if(E!=J(C,A)||D!=M(N,K)+F){O.moveTo(J(C,A),M(N,K)+F)}E=J(B,A);D=M(L,K)+F;O.lineTo(E,D)}O.stroke()},plotLineArea:function(J,D){var S=J.data;if(S.length<2){return }var L,G=0,N=this.ctx,Q=J.xaxis,B=J.yaxis,E=this.tHoz.bind(this),M=this.tVert.bind(this),H=Math.min(Math.max(0,B.min),B.max),F=true;N.beginPath();for(var O=0;O=P&&R>Q.max){if(P>Q.max){continue}C=(Q.max-R)/(P-R)*(A-C)+C;R=Q.max}else{if(P>=R&&P>Q.max){if(R>Q.max){continue}A=(Q.max-R)/(P-R)*(A-C)+C;P=Q.max}}if(F){N.moveTo(E(R,Q),M(H,B)+D);F=false}if(C>=B.max&&A>=B.max){N.lineTo(E(R,Q),M(B.max,B)+D);N.lineTo(E(P,Q),M(B.max,B)+D);continue}else{if(C<=B.min&&A<=B.min){N.lineTo(E(R,Q),M(B.min,B)+D);N.lineTo(E(P,Q),M(B.min,B)+D);continue}}var I=R,K=P;if(C<=A&&C=B.min){R=(B.min-C)/(A-C)*(P-R)+R;C=B.min}else{if(A<=C&&A=B.min){P=(B.min-C)/(A-C)*(P-R)+R;A=B.min}}if(C>=A&&C>B.max&&A<=B.max){R=(B.max-C)/(A-C)*(P-R)+R;C=B.max}else{if(A>=C&&A>B.max&&C<=B.max){P=(B.max-C)/(A-C)*(P-R)+R;A=B.max}}if(R!=I){L=(C<=B.min)?L=B.min:B.max;N.lineTo(E(I,Q),M(L,B)+D);N.lineTo(E(R,Q),M(L,B)+D)}N.lineTo(E(R,Q),M(C,B)+D);N.lineTo(E(P,Q),M(A,B)+D);if(P!=K){L=(A<=B.min)?B.min:B.max;N.lineTo(E(K,Q),M(L,B)+D);N.lineTo(E(P,Q),M(L,B)+D)}G=Math.max(P,K)}N.lineTo(E(G,Q),M(H,B)+D);N.closePath();N.fill()},drawSeriesLines:function(C){C=C||this.series;var B=this.ctx;B.save();B.translate(this.plotOffset.left,this.plotOffset.top);B.lineJoin="round";var D=C.lines.lineWidth;var A=C.shadowSize;if(A>0){B.lineWidth=A/2;var E=D/2+B.lineWidth/2;B.strokeStyle="rgba(0,0,0,0.1)";this.plotLine(C,E+A/2);B.strokeStyle="rgba(0,0,0,0.2)";this.plotLine(C,E);if(C.lines.fill){B.fillStyle="rgba(0,0,0,0.05)";this.plotLineArea(C,E+A/2)}}B.lineWidth=D;B.strokeStyle=C.color;if(C.lines.fill){B.fillStyle=C.lines.fillColor!=null?C.lines.fillColor:Flotr.parseColor(C.color).scale(null,null,null,C.lines.fillOpacity).toString();this.plotLineArea(C,0)}this.plotLine(C,0);B.restore()},drawSeriesPoints:function(C){var B=this.ctx;B.save();B.translate(this.plotOffset.left,this.plotOffset.top);var D=C.lines.lineWidth;var A=C.shadowSize;if(A>0){B.lineWidth=A/2;B.strokeStyle="rgba(0,0,0,0.1)";this.plotPointShadows(C,A/2+B.lineWidth/2,C.points.radius);B.strokeStyle="rgba(0,0,0,0.2)";this.plotPointShadows(C,B.lineWidth/2,C.points.radius)}B.lineWidth=C.points.lineWidth;B.strokeStyle=C.color;B.fillStyle=C.points.fillColor!=null?C.points.fillColor:C.color;this.plotPoints(C,C.points.radius,C.points.fill);B.restore()},plotPoints:function(C,E,I){var A=C.xaxis,F=C.yaxis,J=this.ctx,D,B=C.data;for(D=B.length-1;D>-1;--D){var H=B[D][0],G=B[D][1];if(HA.max||GF.max){continue}J.beginPath();J.arc(this.tHoz(H,A),this.tVert(G,F),E,0,2*Math.PI,true);if(I){J.fill()}J.stroke()}},plotPointShadows:function(D,B,F){var A=D.xaxis,G=D.yaxis,J=this.ctx,E,C=D.data;for(E=C.length-1;E>-1;--E){var I=C[E][0],H=C[E][1];if(IA.max||HG.max){continue}J.beginPath();J.arc(this.tHoz(I,A),this.tVert(H,G)+B,F,0,Math.PI,false);J.stroke()}},drawSeriesBars:function(B){var A=this.ctx,D=B.bars.barWidth,C=Math.min(B.bars.lineWidth,D);A.save();A.translate(this.plotOffset.left,this.plotOffset.top);A.lineJoin="miter";A.lineWidth=C;A.strokeStyle=B.color;this.plotBarsShadows(B,D,0,B.bars.fill);if(B.bars.fill){A.fillStyle=B.bars.fillColor!=null?B.bars.fillColor:Flotr.parseColor(B.color).scale(null,null,null,B.bars.fillOpacity).toString()}this.plotBars(B,D,0,B.bars.fill);A.restore()},plotBars:function(K,N,D,Q){var U=K.data;if(U.length<1){return }var S=K.xaxis,B=K.yaxis,P=this.ctx,F=this.tHoz.bind(this),O=this.tVert.bind(this);for(var R=0;RS.max||MB.max){continue}if(CS.max){T=S.max;if(S.lastSerie!=K&&K.bars.horizontal){L=false}}if(GB.max){M=B.max;if(B.lastSerie!=K&&!K.bars.horizontal){L=false}}if(Q){P.beginPath();P.moveTo(F(C,S),O(G,B)+D);P.lineTo(F(C,S),O(M,B)+D);P.lineTo(F(T,S),O(M,B)+D);P.lineTo(F(T,S),O(G,B)+D);P.fill()}if(K.bars.lineWidth!=0&&(E||A||L)){P.beginPath();P.moveTo(F(C,S),O(G,B)+D);P[E?"lineTo":"moveTo"](F(C,S),O(M,B)+D);P[L?"lineTo":"moveTo"](F(T,S),O(M,B)+D);P[A?"lineTo":"moveTo"](F(T,S),O(G,B)+D);P.stroke()}}},plotBarsShadows:function(I,K,C){var T=I.data;if(T.length<1){return }var R=I.xaxis,A=I.yaxis,P=this.ctx,D=this.tHoz.bind(this),M=this.tVert.bind(this),N=this.options.shadowSize;for(var Q=0;QR.max||JA.max){continue}if(BR.max){S=R.max}if(FA.max){J=A.max}var O=D(S,R)-D(B,R)-((D(S,R)+N<=this.plotWidth)?0:N);var L=Math.max(0,M(F,A)-M(J,A)-((M(F,A)+N<=this.plotHeight)?0:N));P.fillStyle="rgba(0,0,0,0.05)";P.fillRect(Math.min(D(B,R)+N,this.plotWidth),Math.min(M(J,A)+N,this.plotWidth),O,L)}},drawSeriesCandles:function(B){var A=this.ctx,C=B.candles.candleWidth;A.save();A.translate(this.plotOffset.left,this.plotOffset.top);A.lineJoin="miter";A.lineWidth=B.candles.lineWidth;this.plotCandlesShadows(B,C/2);this.plotCandles(B,C/2);A.restore()},plotCandles:function(K,D){var W=K.data;if(W.length<1){return }var T=K.xaxis,B=K.yaxis,P=this.ctx,E=this.tHoz.bind(this),O=this.tVert.bind(this);for(var S=0;ST.max||MB.max){continue}var Q=K.candles[L>N?"downFillColor":"upFillColor"];if(K.candles.fill&&!K.candles.barcharts){P.fillStyle=Flotr.parseColor(Q).scale(null,null,null,K.candles.fillOpacity).toString();P.fillRect(E(C,T),O(R,B)+D,E(V,T)-E(C,T),O(A,B)-O(R,B))}if(K.candles.lineWidth||K.candles.wickLineWidth){var J,H,F=(K.candles.wickLineWidth%2)/2;J=Math.floor(E((C+V)/2),T)+F;P.save();P.strokeStyle=Q;P.lineWidth=K.candles.wickLineWidth;P.lineCap="butt";if(K.candles.barcharts){P.beginPath();P.moveTo(J,Math.floor(O(M,B)+D));P.lineTo(J,Math.floor(O(G,B)+D));H=Math.floor(O(L,B)+D)+0.5;P.moveTo(Math.floor(E(C,T))+F,H);P.lineTo(J,H);H=Math.floor(O(N,B)+D)+0.5;P.moveTo(Math.floor(E(V,T))+F,H);P.lineTo(J,H)}else{P.strokeRect(E(C,T),O(R,B)+D,E(V,T)-E(C,T),O(A,B)-O(R,B));P.beginPath();P.moveTo(J,Math.floor(O(R,B)+D));P.lineTo(J,Math.floor(O(M,B)+D));P.moveTo(J,Math.floor(O(A,B)+D));P.lineTo(J,Math.floor(O(G,B)+D))}P.stroke();P.restore()}}},plotCandlesShadows:function(H,C){var T=H.data;if(T.length<1||H.candles.barcharts){return }var Q=H.xaxis,A=H.yaxis,D=this.tHoz.bind(this),M=this.tVert.bind(this),N=this.options.shadowSize;for(var P=0;PQ.max||JA.max){continue}var O=D(S,Q)-D(B,Q)-((D(S,Q)+N<=this.plotWidth)?0:N);var L=Math.max(0,M(E,A)-M(J,A)-((M(E,A)+N<=this.plotHeight)?0:N));this.ctx.fillStyle="rgba(0,0,0,0.05)";this.ctx.fillRect(Math.min(D(B,Q)+N,this.plotWidth),Math.min(M(J,A)+N,this.plotWidth),O,L)}},drawSeriesPie:function(G){if(!this.options.pie.drawn){var K=this.ctx,C=this.options,E=G.pie.lineWidth,I=G.shadowSize,R=G.data,D=(Math.min(this.canvasWidth,this.canvasHeight)*G.pie.sizeRatio)/2,H=[];var L=1;var P=Math.sin(G.pie.viewAngle)*G.pie.spliceThickness/L;var M={size:C.fontSize*1.2,color:C.grid.color,weight:1.5};var Q={x:(this.canvasWidth+this.plotOffset.left)/2,y:(this.canvasHeight-this.plotOffset.bottom)/2};var O=this.series.collect(function(T,S){if(T.pie.show){return{name:(T.label||T.data[0][1]),value:[S,T.data[0][1]],explode:T.pie.explode}}});var B=O.pluck("value").pluck(1).inject(0,function(S,T){return S+T});var F=0,N=G.pie.startAngle,J=0;var A=O.collect(function(S){N+=F;J=parseFloat(S.value[1]);F=J/B;return{name:S.name,fraction:F,x:S.value[0],y:J,explode:S.explode,startAngle:2*N*Math.PI,endAngle:2*(N+F)*Math.PI}});K.save();if(I>0){A.each(function(V){var S=(V.startAngle+V.endAngle)/2;var T=Q.x+Math.cos(S)*V.explode+I;var U=Q.y+Math.sin(S)*V.explode+I;this.plotSlice(T,U,D,V.startAngle,V.endAngle,false,L);K.fillStyle="rgba(0,0,0,0.1)";K.fill()},this)}if(C.HtmlText){H=['
']}A.each(function(c,X){var W=(c.startAngle+c.endAngle)/2;var V=C.colors[X];var Y=Q.x+Math.cos(W)*c.explode;var U=Q.y+Math.sin(W)*c.explode;this.plotSlice(Y,U,D,c.startAngle,c.endAngle,false,L);if(G.pie.fill){K.fillStyle=Flotr.parseColor(V).scale(null,null,null,G.pie.fillOpacity).toString();K.fill()}K.lineWidth=E;K.strokeStyle=V;K.stroke();var b=C.pie.labelFormatter(c);var S=(Math.cos(W)<0);var a=Y+Math.cos(W)*(G.pie.explode+D);var Z=U+Math.sin(W)*(G.pie.explode+D);if(c.fraction&&b){if(C.HtmlText){var T="position:absolute;top:"+(Z-5)+"px;";if(S){T+="right:"+(this.canvasWidth-a)+"px;text-align:right;"}else{T+="left:"+a+"px;text-align:left;"}H.push('
'+b+"
")}else{M.halign=S?"r":"l";K.drawText(b,a,Z+M.size/2,M)}}},this);if(C.HtmlText){H.push("
");this.el.insert(H.join(""))}K.restore();C.pie.drawn=true}},plotSlice:function(B,H,A,E,D,F,G){var C=this.ctx;G=G||1;C.save();C.scale(1,G);C.beginPath();C.moveTo(B,H);C.arc(B,H,A,E,D,F);C.lineTo(B,H);C.closePath();C.restore()},plotPie:function(){},insertLegend:function(){if(!this.options.legend.show){return }var H=this.series,I=this.plotOffset,B=this.options,b=[],A=false,O=this.ctx,R;var Q=H.findAll(function(c){return(c.label&&!c.hide)}).size();if(Q){if(!B.HtmlText&&this.textEnabled){var T={size:B.fontSize*1.1,color:B.grid.color};var M=B.legend.position,N=B.legend.margin,L=B.legend.labelBoxWidth,Z=B.legend.labelBoxHeight,S=B.legend.labelBoxMargin,W=I.left+N,U=I.top+N;var a=0;for(R=H.length-1;R>-1;--R){if(!H[R].label||H[R].hide){continue}var E=B.legend.labelFormatter(H[R].label);a=Math.max(a,O.measureText(E,T))}var K=Math.round(L+S*3+a),C=Math.round(Q*(S+Z)+S);if(M.charAt(0)=="s"){U=I.top+this.plotHeight-(N+C)}if(M.charAt(1)=="e"){W=I.left+this.plotWidth-(N+K)}var P=Flotr.parseColor(B.legend.backgroundColor||"rgb(240,240,240)").scale(null,null,null,B.legend.backgroundOpacity||0.1).toString();O.fillStyle=P;O.fillRect(W,U,K,C);O.strokeStyle=B.legend.labelBoxBorderColor;O.strokeRect(Flotr.toPixel(W),Flotr.toPixel(U),K,C);var G=W+S;var F=U+S;for(R=0;R":"");A=true}var E=B.legend.labelFormatter(H[R].label);b.push('
'+E+"")}if(A){b.push("")}if(b.length>0){var V=''+b.join("")+"
";if(B.legend.container!=null){$(B.legend.container).update(V)}else{var D="";var M=B.legend.position,N=B.legend.margin;if(M.charAt(0)=="n"){D+="top:"+(N+I.top)+"px;"}else{if(M.charAt(0)=="s"){D+="bottom:"+(N+I.bottom)+"px;"}}if(M.charAt(1)=="e"){D+="right:"+(N+I.right)+"px;"}else{if(M.charAt(1)=="w"){D+="left:"+(N+I.left)+"px;"}}var J=this.el.insert('
'+V+"
").select("div.flotr-legend").first();if(B.legend.backgroundOpacity!=0){var Y=B.legend.backgroundColor;if(Y==null){var X=(B.grid.backgroundColor!=null)?B.grid.backgroundColor:Flotr.extractColor(J);Y=Flotr.parseColor(X).adjust(null,null,null,1).toString()}this.el.insert('
').select("div.flotr-legend-bg").first().setStyle({opacity:B.legend.backgroundOpacity})}}}}}},getEventPosition:function(C){var G=this.overlay.cumulativeOffset(),F=(C.pageX-G.left-this.plotOffset.left),E=(C.pageY-G.top-this.plotOffset.top),D=0,B=0;if(C.pageX==null&&C.clientX!=null){var H=document.documentElement,A=document.body;D=C.clientX+(H&&H.scrollLeft||A.scrollLeft||0);B=C.clientY+(H&&H.scrollTop||A.scrollTop||0)}else{D=C.pageX;B=C.pageY}return{x:this.axes.x.min+F/this.axes.x.scale,x2:this.axes.x2.min+F/this.axes.x2.scale,y:this.axes.y.max-E/this.axes.y.scale,y2:this.axes.y2.max-E/this.axes.y2.scale,relX:F,relY:E,absX:D,absY:B}},clickHandler:function(A){if(this.ignoreClick){this.ignoreClick=false;return }this.el.fire("flotr:click",[this.getEventPosition(A),this])},mouseMoveHandler:function(A){var B=this.getEventPosition(A);this.lastMousePos.pageX=B.absX;this.lastMousePos.pageY=B.absY;if(this.selectionInterval==null&&(this.options.mouse.track||this.series.any(function(C){return C.mouse&&C.mouse.track}))){this.hit(B)}this.el.fire("flotr:mousemove",[A,B,this])},mouseDownHandler:function(C){if(C.isRightClick()){C.stop();var B=this.overlay;B.hide();function A(){B.show();$(document).stopObserving("mousemove",A)}$(document).observe("mousemove",A);return }if(!this.options.selection.mode||!C.isLeftClick()){return }this.setSelectionPos(this.selection.first,C);if(this.selectionInterval!=null){clearInterval(this.selectionInterval)}this.lastMousePos.pageX=null;this.selectionInterval=setInterval(this.updateSelection.bind(this),1000/this.options.selection.fps);this.mouseUpHandler=this.mouseUpHandler.bind(this);$(document).observe("mouseup",this.mouseUpHandler)},fireSelectEvent:function(){var A=this.axes,F=this.selection,C=(F.first.x<=F.second.x)?F.first.x:F.second.x,B=(F.first.x<=F.second.x)?F.second.x:F.first.x,E=(F.first.y>=F.second.y)?F.first.y:F.second.y,D=(F.first.y>=F.second.y)?F.second.y:F.first.y;C=A.x.min+C/A.x.scale;B=A.x.min+B/A.x.scale;E=A.y.max-E/A.y.scale;D=A.y.max-D/A.y.scale;this.el.fire("flotr:select",[{x1:C,y1:E,x2:B,y2:D},this])},mouseUpHandler:function(A){$(document).stopObserving("mouseup",this.mouseUpHandler);A.stop();if(this.selectionInterval!=null){clearInterval(this.selectionInterval);this.selectionInterval=null}this.setSelectionPos(this.selection.second,A);this.clearSelection();if(this.selectionIsSane()){this.drawSelection();this.fireSelectEvent();this.ignoreClick=true}},setSelectionPos:function(D,B){var A=this.options,C=$(this.overlay).cumulativeOffset();if(A.selection.mode.indexOf("x")==-1){D.x=(D==this.selection.first)?0:this.plotWidth}else{D.x=B.pageX-C.left-this.plotOffset.left;D.x=Math.min(Math.max(0,D.x),this.plotWidth)}if(A.selection.mode.indexOf("y")==-1){D.y=(D==this.selection.first)?0:this.plotHeight}else{D.y=B.pageY-C.top-this.plotOffset.top;D.y=Math.min(Math.max(0,D.y),this.plotHeight)}},updateSelection:function(){if(this.lastMousePos.pageX==null){return }this.setSelectionPos(this.selection.second,this.lastMousePos);this.clearSelection();if(this.selectionIsSane()){this.drawSelection()}},clearSelection:function(){if(this.prevSelection==null){return }var G=this.prevSelection,E=this.octx,C=this.plotOffset,A=Math.min(G.first.x,G.second.x),F=Math.min(G.first.y,G.second.y),B=Math.abs(G.second.x-G.first.x),D=Math.abs(G.second.y-G.first.y);E.clearRect(A+C.left-E.lineWidth,F+C.top-E.lineWidth,B+E.lineWidth*2,D+E.lineWidth*2);this.prevSelection=null},setSelection:function(G){var B=this.options,H=this.axes.x,A=this.axes.y,F=yaxis.scale,D=xaxis.scale,E=B.selection.mode.indexOf("x")!=-1,C=B.selection.mode.indexOf("y")!=-1;this.clearSelection();this.selection.first.y=E?0:(A.max-G.y1)*F;this.selection.second.y=E?this.plotHeight:(A.max-G.y2)*F;this.selection.first.x=C?0:(G.x1-H.min)*D;this.selection.second.x=C?this.plotWidth:(G.x2-H.min)*D;this.drawSelection();this.fireSelectEvent()},drawSelection:function(){var C=this.prevSelection,F=this.selection,H=this.octx,I=this.options,A=this.plotOffset;if(C!=null&&F.first.x==C.first.x&&F.first.y==C.first.y&&F.second.x==C.second.x&&F.second.y==C.second.y){return }H.strokeStyle=Flotr.parseColor(I.selection.color).scale(null,null,null,0.8).toString();H.lineWidth=1;H.lineJoin="round";H.fillStyle=Flotr.parseColor(I.selection.color).scale(null,null,null,0.4).toString();this.prevSelection={first:{x:F.first.x,y:F.first.y},second:{x:F.second.x,y:F.second.y}};var E=Math.min(F.first.x,F.second.x),D=Math.min(F.first.y,F.second.y),G=Math.abs(F.second.x-F.first.x),B=Math.abs(F.second.y-F.first.y);H.fillRect(E+A.left,D+A.top,G,B);H.strokeRect(E+A.left,D+A.top,G,B)},selectionIsSane:function(){var A=this.selection;return Math.abs(A.second.x-A.first.x)>=5&&Math.abs(A.second.y-A.first.y)>=5},clearHit:function(){if(this.prevHit){var B=this.options,A=this.plotOffset,C=this.prevHit;this.octx.clearRect(this.tHoz(C.x)+A.left-B.points.radius*2,this.tVert(C.y)+A.top-B.points.radius*2,B.points.radius*3+B.points.lineWidth*3,B.points.radius*3+B.points.lineWidth*3);this.prevHit=null}},hit:function(I){var G=this.series,C=this.options,R=this.prevHit,H=this.plotOffset,D=this.octx,S,A,M,Q,L={dist:Number.MAX_VALUE,x:null,y:null,relX:I.relX,relY:I.relY,absX:I.absX,absY:I.absY,mouse:null};for(Q=0;Q');K=this.mouseTrack=this.el.select(".flotr-mouse-value").first()}else{this.mouseTrack=K.setStyle(O)}if(L.x!==null&&L.y!==null){K.show();this.clearHit();if(L.mouse.lineColor!=null){D.save();D.translate(H.left,H.top);D.lineWidth=C.points.lineWidth;D.strokeStyle=L.mouse.lineColor;D.fillStyle="#ffffff";D.beginPath();D.arc(this.tHoz(L.x),this.tVert(L.y),C.mouse.radius,0,2*Math.PI,true);D.fill();D.stroke();D.restore()}this.prevHit=L;var T=L.mouse.trackDecimals;if(T==null||T<0){T=0}K.innerHTML=L.mouse.trackFormatter({x:L.x.toFixed(T),y:L.y.toFixed(T)});K.fire("flotr:hit",[L,this])}else{if(R){K.hide();this.clearHit()}}}},saveImage:function(D,C,A,B){var E=null;switch(D){case"jpeg":case"jpg":E=Canvas2Image.saveAsJPEG(this.canvas,B,C,A);break;default:case"png":E=Canvas2Image.saveAsPNG(this.canvas,B,C,A);break;case"bmp":E=Canvas2Image.saveAsBMP(this.canvas,B,C,A);break}if(Object.isElement(E)&&B){this.restoreCanvas();this.canvas.hide();this.overlay.hide();this.el.insert(E.setStyle({position:"absolute"}))}},restoreCanvas:function(){this.canvas.show();this.overlay.show();this.el.select("img").invoke("remove")}});Flotr.Color=Class.create({initialize:function(E,D,B,C){this.rgba=["r","g","b","a"];var A=4;while(-1<--A){this[this.rgba[A]]=arguments[A]||((A==3)?1:0)}this.normalize()},adjust:function(D,C,E,B){var A=4;while(-1<--A){if(arguments[A]!=null){this[this.rgba[A]]+=arguments[A]}}return this.normalize()},clone:function(){return new Flotr.Color(this.r,this.b,this.g,this.a)},limit:function(B,A,C){return Math.max(Math.min(B,C),A)},normalize:function(){var A=this.limit;this.r=A(parseInt(this.r),0,255);this.g=A(parseInt(this.g),0,255);this.b=A(parseInt(this.b),0,255);this.a=A(this.a,0,1);return this},scale:function(D,C,E,B){var A=4;while(-1<--A){if(arguments[A]!=null){this[this.rgba[A]]*=arguments[A]}}return this.normalize()},distance:function(B){if(!B){return }B=new Flotr.parseColor(B);var C=0;var A=3;while(-1<--A){C+=Math.abs(this[this.rgba[A]]-B[this.rgba[A]])}return C},toString:function(){return(this.a>=1)?"rgb("+[this.r,this.g,this.b].join(",")+")":"rgba("+[this.r,this.g,this.b,this.a].join(",")+")"}});Flotr.Color.lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]};Flotr.Date={format:function(F,E){if(!F){return }var A=function(H){H=H.toString();return H.length==1?"0"+H:H};var D=[];var C=false;for(var B=0;B, MIT License. -// -//Radar chart added by Ryan Simmons -// -/* $Id: flotr.js 82 2009-01-12 19:19:31Z fabien.menager $ */ - -var Flotr = { - version: '0.2.0-alpha', - author: 'Bas Wenneker', - website: 'http://www.solutoire.com', - /** - * An object of the default registered graph types. Use Flotr.register(type, functionName) - * to add your own type. - */ - _registeredTypes:{ - 'lines': 'drawSeriesLines', - 'points': 'drawSeriesPoints', - 'bars': 'drawSeriesBars', - 'candles': 'drawSeriesCandles', - 'pie': 'drawSeriesPie', - 'radar':'drawSeriesRadar' - }, - /** - * Can be used to register your own chart type. Default types are 'lines', 'points' and 'bars'. - * This is still experimental. - * @todo Test and confirm. - * @param {String} type - type of chart, like 'pies', 'bars' etc. - * @param {String} functionName - Name of the draw function, like 'drawSeriesPies', 'drawSeriesBars' etc. - */ - register: function(type, functionName){ - Flotr._registeredTypes[type] = functionName+''; - }, - /** - * Draws the graph. This function is here for backwards compatibility with Flotr version 0.1.0alpha. - * You could also draw graphs by directly calling Flotr.Graph(element, data, options). - * @param {Element} el - element to insert the graph into - * @param {Object} data - an array or object of dataseries - * @param {Object} options - an object containing options - * @param {Class} _GraphKlass_ - (optional) Class to pass the arguments to, defaults to Flotr.Graph - * @return {Class} returns a new graph object and of course draws the graph. - */ - draw: function(el, data, options, _GraphKlass_){ - _GraphKlass_ = _GraphKlass_ || Flotr.Graph; - return new _GraphKlass_(el, data, options); - }, - /** - * Collects dataseries from input and parses the series into the right format. It returns an Array - * of Objects each having at least the 'data' key set. - * @param {Array/Object} data - Object or array of dataseries - * @return {Array} Array of Objects parsed into the right format ({(...,) data: [[x1,y1], [x2,y2], ...] (, ...)}) - */ - getSeries: function(data){ - return data.collect(function(serie){ - var i, serie = (serie.data) ? Object.clone(serie) : {'data': serie}; - for (i = serie.data.length-1; i > -1; --i) { - serie.data[i][1] = (serie.data[i][1] === null ? null : parseFloat(serie.data[i][1])); - } - return serie; - }); - }, - /** - * Recursively merges two objects. - * @param {Object} src - source object (likely the object with the least properties) - * @param {Object} dest - destination object (optional, object with the most properties) - * @return {Object} recursively merged Object - */ - merge: function(src, dest){ - var result = dest || {}; - for(var i in src){ - result[i] = (src[i] != null && typeof(src[i]) == 'object' && !(src[i].constructor == Array || src[i].constructor == RegExp) && !Object.isElement(src[i])) ? Flotr.merge(src[i], dest[i]) : result[i] = src[i]; - } - return result; - }, - /** - * Function calculates the ticksize and returns it. - * @param {Integer} noTicks - number of ticks - * @param {Integer} min - lower bound integer value for the current axis - * @param {Integer} max - upper bound integer value for the current axis - * @param {Integer} decimals - number of decimals for the ticks - * @return {Integer} returns the ticksize in pixels - */ - getTickSize: function(noTicks, min, max, decimals){ - var delta = (max - min) / noTicks; - var magn = Flotr.getMagnitude(delta); - - // Norm is between 1.0 and 10.0. - var norm = delta / magn; - - var tickSize = 10; - if(norm < 1.5) tickSize = 1; - else if(norm < 2.25) tickSize = 2; - else if(norm < 3) tickSize = ((decimals == 0) ? 2 : 2.5); - else if(norm < 7.5) tickSize = 5; - - return tickSize * magn; - }, - /** - * Default tick formatter. - * @param {String/Integer} val - tick value integer - * @return {String} formatted tick string - */ - defaultTickFormatter: function(val){ - return val+''; - }, - /** - * Formats the mouse tracker values. - * @param {Object} obj - Track value Object {x:..,y:..} - * @return {String} Formatted track string - */ - defaultTrackFormatter: function(obj){ - return '('+obj.x+', '+obj.y+')'; - }, - defaultPieLabelFormatter: function(slice) { - return (slice.fraction*100).toFixed(2)+'%'; - }, - /** - * Returns the magnitude of the input value. - * @param {Integer/Float} x - integer or float value - * @return {Integer/Float} returns the magnitude of the input value - */ - getMagnitude: function(x){ - return Math.pow(10, Math.floor(Math.log(x) / Math.LN10)); - }, - toPixel: function(val){ - return Math.floor(val)+0.5;//((val-Math.round(val) < 0.4) ? (Math.floor(val)-0.5) : val); - }, - toRad: function(angle){ - return -angle * (Math.PI/180); - }, - /** - * Parses a color string and returns a corresponding Color. - * @param {String} str - string thats representing a color - * @return {Color} returns a Color object or false - */ - parseColor: function(str){ - if (str instanceof Flotr.Color) return str; - - var result, Color = Flotr.Color; - - // rgb(num,num,num) - if((result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))) - return new Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3])); - - // rgba(num,num,num,num) - if((result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))) - return new Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]), parseFloat(result[4])); - - // rgb(num%,num%,num%) - if((result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))) - return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55); - - // rgba(num%,num%,num%,num) - if((result = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))) - return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55, parseFloat(result[4])); - - // #a0b1c2 - if((result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))) - return new Color(parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)); - - // #fff - if((result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))) - return new Color(parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)); - - // Otherwise, we're most likely dealing with a named color. - var name = str.strip().toLowerCase(); - if(name == 'transparent'){ - return new Color(255, 255, 255, 0); - } - return ((result = Color.lookupColors[name])) ? new Color(result[0], result[1], result[2]) : false; - }, - /** - * Extracts the background-color of the passed element. - * @param {Element} element - * @return {String} color string - */ - extractColor: function(element){ - var color; - // Loop until we find an element with a background color and stop when we hit the body element. - do { - color = element.getStyle('background-color').toLowerCase(); - if(!(color == '' || color == 'transparent')) break; - element = element.up(0); - } while(!element.nodeName.match(/^body$/i)); - - // Catch Safari's way of signaling transparent. - return (color == 'rgba(0, 0, 0, 0)') ? 'transparent' : color; - } -}; -/** - * Flotr Graph class that plots a graph on creation. - - */ -Flotr.Graph = Class.create({ - /** - * Flotr Graph constructor. - * @param {Element} el - element to insert the graph into - * @param {Object} data - an array or object of dataseries - * @param {Object} options - an object containing options - */ - initialize: function(el, data, options){ - this.el = $(el); - - if (!this.el) throw 'The target container doesn\'t exist'; - - this.data = data; - this.series = Flotr.getSeries(data); - this.setOptions(options); - - // Initialize some variables - this.lastMousePos = { pageX: null, pageY: null }; - this.selection = { first: { x: -1, y: -1}, second: { x: -1, y: -1} }; - this.prevSelection = null; - this.selectionInterval = null; - this.ignoreClick = false; - this.prevHit = null; - - // Create and prepare canvas. - this.constructCanvas(); - - // Add event handlers for mouse tracking, clicking and selection - this.initEvents(); - - this.findDataRanges(); - this.calculateTicks(this.axes.x); - this.calculateTicks(this.axes.x2); - this.calculateTicks(this.axes.y); - this.calculateTicks(this.axes.y2); - - this.calculateSpacing(); - this.draw(); - this.insertLegend(); - - // Graph and Data tabs - if (this.options.spreadsheet.show) - this.constructTabs(); - }, - /** - * Sets options and initializes some variables and color specific values, used by the constructor. - * @param {Object} opts - options object - */ - setOptions: function(opts){ - var options = { - colors: ['#00A8F0', '#C0D800', '#CB4B4B', '#4DA74D', '#9440ED'], //=> The default colorscheme. When there are > 5 series, additional colors are generated. - title: null, - subtitle: null, - legend: { - show: true, // => setting to true will show the legend, hide otherwise - noColumns: 1, // => number of colums in legend table // @todo: doesn't work for HtmlText = false - labelFormatter: Prototype.K, // => fn: string -> string - labelBoxBorderColor: '#CCCCCC', // => border color for the little label boxes - labelBoxWidth: 14, - labelBoxHeight: 10, - labelBoxMargin: 5, - container: null, // => container (as jQuery object) to put legend in, null means default on top of graph - position: 'nw', // => position of default legend container within plot - margin: 5, // => distance from grid edge to default legend container within plot - backgroundColor: null, // => null means auto-detect - backgroundOpacity: 0.85// => set to 0 to avoid background, set to 1 for a solid background - }, - xaxis: { - ticks: null, // => format: either [1, 3] or [[1, 'a'], 3] - showLabels: true, // => setting to true will show the axis ticks labels, hide otherwise - labelsAngle: 0, // => Labels' angle, in degrees - title: null, // => axis title - titleAngle: 0, // => axis title's angle, in degrees - noTicks: 5, // => number of ticks for automagically generated ticks - tickFormatter: Flotr.defaultTickFormatter, // => fn: number -> string - tickDecimals: null, // => no. of decimals, null means auto - min: null, // => min. value to show, null means set automatically - max: null, // => max. value to show, null means set automatically - autoscaleMargin: 0, // => margin in % to add if auto-setting min/max - color: null - }, - x2axis: {}, - yaxis: { - ticks: null, // => format: either [1, 3] or [[1, 'a'], 3] - showLabels: true, // => setting to true will show the axis ticks labels, hide otherwise - labelsAngle: 0, // => Labels' angle, in degrees - title: null, // => axis title - titleAngle: 90, // => axis title's angle, in degrees - noTicks: 5, // => number of ticks for automagically generated ticks - tickFormatter: Flotr.defaultTickFormatter, // => fn: number -> string - tickDecimals: null, // => no. of decimals, null means auto - min: null, // => min. value to show, null means set automatically - max: null, // => max. value to show, null means set automatically - autoscaleMargin: 0, // => margin in % to add if auto-setting min/max - color: null - }, - y2axis: { - titleAngle: 270 - }, - points: { - show: false, // => setting to true will show points, false will hide - radius: 3, // => point radius (pixels) - lineWidth: 2, // => line width in pixels - fill: true, // => true to fill the points with a color, false for (transparent) no fill - fillColor: '#FFFFFF', // => fill color - fillOpacity: 0.4 - }, - lines: { - show: false, // => setting to true will show lines, false will hide - lineWidth: 2, // => line width in pixels - fill: false, // => true to fill the area from the line to the x axis, false for (transparent) no fill - fillColor: null, // => fill color - fillOpacity: 0.4 // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - }, - radar: { - show: false, // => setting to true will show radar chart, false will hide - lineWidth: 2, // => line width in pixels - fill: false, // => true to fill the area from the line to the x axis, false for (transparent) no fill - fillColor: null, // => fill color - fillOpacity: 0.4 // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - }, - bars: { - show: false, // => setting to true will show bars, false will hide - lineWidth: 2, // => in pixels - barWidth: 1, // => in units of the x axis - fill: true, // => true to fill the area from the line to the x axis, false for (transparent) no fill - fillColor: null, // => fill color - fillOpacity: 0.4, // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - horizontal: false, - stacked: false - }, - candles: { - show: false, // => setting to true will show candle sticks, false will hide - lineWidth: 1, // => in pixels - wickLineWidth: 1, // => in pixels - candleWidth: 0.6, // => in units of the x axis - fill: true, // => true to fill the area from the line to the x axis, false for (transparent) no fill - upFillColor: '#00A8F0',// => up sticks fill color - downFillColor: '#CB4B4B',// => down sticks fill color - fillOpacity: 0.5, // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - barcharts: false // => draw as barcharts (not standard bars but financial barcharts) - }, - pie: { - show: false, // => setting to true will show bars, false will hide - lineWidth: 1, // => in pixels - fill: true, // => true to fill the area from the line to the x axis, false for (transparent) no fill - fillColor: null, // => fill color - fillOpacity: 0.6, // => opacity of the fill color, set to 1 for a solid fill, 0 hides the fill - explode: 6, - sizeRatio: 0.6, - startAngle: Math.PI/4, - labelFormatter: Flotr.defaultPieLabelFormatter, - pie3D: false, - pie3DviewAngle: (Math.PI/2 * 0.8), - pie3DspliceThickness: 20 - }, - grid: { - color: '#545454', // => primary color used for outline and labels - backgroundColor: null, // => null for transparent, else color - tickColor: '#DDDDDD', // => color used for the ticks - labelMargin: 3, // => margin in pixels - verticalLines: true, // => whether to show gridlines in vertical direction - horizontalLines: true, // => whether to show gridlines in horizontal direction - outlineWidth: 2 // => width of the grid outline/border in pixels - }, - selection: { - mode: null, // => one of null, 'x', 'y' or 'xy' - color: '#B6D9FF', // => selection box color - fps: 20 // => frames-per-second - }, - mouse: { - track: false, // => true to track the mouse, no tracking otherwise - position: 'se', // => position of the value box (default south-east) - relative: false, // => next to the mouse cursor - trackFormatter: Flotr.defaultTrackFormatter, // => formats the values in the value box - margin: 5, // => margin in pixels of the valuebox - lineColor: '#FF3F19', // => line color of points that are drawn when mouse comes near a value of a series - trackDecimals: 1, // => decimals for the track values - sensibility: 2, // => the lower this number, the more precise you have to aim to show a value - radius: 3 // => radius of the track point - }, - radarChartMode: false, // => true to render radar grid / and setup scaling for radar chart - shadowSize: 4, // => size of the 'fake' shadow - defaultType: 'lines', // => default series type - HtmlText: true, // => wether to draw the text using HTML or on the canvas - fontSize: 7.5, // => canvas' text font size - spreadsheet: { - show: false, // => show the data grid using two tabs - tabGraphLabel: 'Graph', - tabDataLabel: 'Data', - toolbarDownload: 'Download CSV', // @todo: add language support - toolbarSelectAll: 'Select all' - } - } - - options.x2axis = Object.extend(Object.clone(options.xaxis), options.x2axis); - options.y2axis = Object.extend(Object.clone(options.yaxis), options.y2axis); - this.options = Flotr.merge((opts || {}), options); - - this.axes = { - x: {options: this.options.xaxis, n: 1}, - x2: {options: this.options.x2axis, n: 2}, - y: {options: this.options.yaxis, n: 1}, - y2: {options: this.options.y2axis, n: 2} - }; - - // Initialize some variables used throughout this function. - var assignedColors = [], - colors = [], - ln = this.series.length, - neededColors = this.series.length, - oc = this.options.colors, - usedColors = [], - variation = 0, - c, i, j, s, tooClose; - - // Collect user-defined colors from series. - for(i = neededColors - 1; i > -1; --i){ - c = this.series[i].color; - if(c != null){ - --neededColors; - if(Object.isNumber(c)) assignedColors.push(c); - else usedColors.push(Flotr.parseColor(c)); - } - } - - // Calculate the number of colors that need to be generated. - for(i = assignedColors.length - 1; i > -1; --i) - neededColors = Math.max(neededColors, assignedColors[i] + 1); - - // Generate needed number of colors. - for(i = 0; colors.length < neededColors;){ - c = (oc.length == i) ? new Flotr.Color(100, 100, 100) : Flotr.parseColor(oc[i]); - - // Make sure each serie gets a different color. - var sign = variation % 2 == 1 ? -1 : 1; - var factor = 1 + sign * Math.ceil(variation / 2) * 0.2; - c.scale(factor, factor, factor); - - /** - * @todo if we're getting too close to something else, we should probably skip this one - */ - colors.push(c); - - if(++i >= oc.length){ - i = 0; - ++variation; - } - } - - // Fill the options with the generated colors. - for(i = 0, j = 0; i < ln; ++i){ - s = this.series[i]; - - // Assign the color. - if(s.color == null){ - s.color = colors[j++].toString(); - }else if(Object.isNumber(s.color)){ - s.color = colors[s.color].toString(); - } - - if (!s.xaxis) s.xaxis = this.axes.x; - if (s.xaxis == 1) s.xaxis = this.axes.x; - else if (s.xaxis == 2) s.xaxis = this.axes.x2; - - if (!s.yaxis) s.yaxis = this.axes.y; - if (s.yaxis == 1) s.yaxis = this.axes.y; - else if (s.yaxis == 2) s.yaxis = this.axes.y2; - - // Apply missing options to the series. - s.lines = Object.extend(Object.clone(this.options.lines), s.lines); - s.points = Object.extend(Object.clone(this.options.points), s.points); - s.bars = Object.extend(Object.clone(this.options.bars), s.bars); - s.candles = Object.extend(Object.clone(this.options.candles), s.candles); - s.pie = Object.extend(Object.clone(this.options.pie), s.pie); - s.radar = Object.extend(Object.clone(this.options.radar), s.radar); - s.mouse = Object.extend(Object.clone(this.options.mouse), s.mouse); - - if(s.shadowSize == null) s.shadowSize = this.options.shadowSize; - } - }, - /** - * Initializes the canvas and it's overlay canvas element. When the browser is IE, this makes use - * of excanvas. The overlay canvas is inserted for displaying interactions. After the canvas elements - * are created, the elements are inserted into the container element. - */ - constructCanvas: function(){ - var el = this.el, - size, c, oc; - - this.canvas = el.select('.flotr-canvas')[0]; - this.overlay = el.select('.flotr-overlay')[0]; - - el.childElements().invoke('remove'); - - // For positioning labels and overlay. - el.setStyle({position:'relative', cursor:'default'}); - - this.canvasWidth = el.getWidth(); - this.canvasHeight = el.getHeight(); - size = {'width': this.canvasWidth, 'height': this.canvasHeight}; - - if(this.canvasWidth <= 0 || this.canvasHeight <= 0){ - throw 'Invalid dimensions for plot, width = ' + this.canvasWidth + ', height = ' + this.canvasHeight; - } - - // Insert main canvas. - if (!this.canvas) { - c = this.canvas = new Element('canvas', size); - c.className = 'flotr-canvas'; - c = c.writeAttribute('style', 'position:absolute;left:0px;top:0px;'); - } else { - c = this.canvas.writeAttribute(size); - } - el.insert(c); - - if(Prototype.Browser.IE){ - c = window.G_vmlCanvasManager.initElement(c); - } - this.ctx = c.getContext('2d'); - - // Insert overlay canvas for interactive features. - if (!this.overlay) { - oc = this.overlay = new Element('canvas', size); - oc.className = 'flotr-overlay'; - oc = oc.writeAttribute('style', 'position:absolute;left:0px;top:0px;'); - } else { - oc = this.overlay.writeAttribute(size); - } - el.insert(oc); - - if(Prototype.Browser.IE){ - oc = window.G_vmlCanvasManager.initElement(oc); - } - this.octx = oc.getContext('2d'); - - // Enable text functions - if (window.CanvasText) { - CanvasText.enable(this.ctx); - CanvasText.enable(this.octx); - this.textEnabled = true; - } - }, - getTextDimensions: function(text, canvasStyle, HtmlStyle, className) { - if (!text) return {width:0, height:0}; - - if (!this.options.HtmlText && this.textEnabled) { - var bounds = this.ctx.getTextBounds(text, canvasStyle); - return { - width: bounds.width+2, - height: bounds.height+6 - }; - } - else { - var dummyDiv = this.el.insert('
' + text + '
').select(".flotr-dummy-div")[0]; - dim = dummyDiv.getDimensions(); - dummyDiv.remove(); - return dim; - } - }, - loadDataGrid: function(){ - if (this.seriesData) return this.seriesData; - - var s = this.series; - var dg = []; - - /* The data grid is a 2 dimensions array. There is a row for each X value. - * Each row contains the x value and the corresponding y value for each serie ('undefined' if there isn't one) - **/ - for(i = 0; i < s.length; ++i){ - s[i].data.each(function(v) { - var x = v[0], - y = v[1]; - if (r = dg.find(function(row) {return row[0] == x})) { - r[i+1] = y; - } - else { - var newRow = []; - newRow[0] = x; - newRow[i+1] = y - dg.push(newRow); - } - }); - } - - // The data grid is sorted by x value - dg = dg.sortBy(function(v) { - return v[0]; - }); - return this.seriesData = dg; - }, - - // @todo: make a tab manager (Flotr.Tabs) - showTab: function(tabName, onComplete){ - var elementsClassNames = 'canvas, .flotr-labels, .flotr-legend, .flotr-legend-bg, .flotr-title, .flotr-subtitle'; - switch(tabName) { - case 'graph': - this.datagrid.up().hide(); - this.el.select(elementsClassNames).invoke('show'); - this.tabs.data.removeClassName('selected'); - this.tabs.graph.addClassName('selected'); - break; - case 'data': - this.constructDataGrid(); - this.datagrid.up().show(); - this.el.select(elementsClassNames).invoke('hide'); - this.tabs.data.addClassName('selected'); - this.tabs.graph.removeClassName('selected'); - break; - } - }, - constructTabs: function(){ - var tabsContainer = new Element('div', {className:'flotr-tabs-group', style:'position:absolute;left:0px;top:'+this.canvasHeight+'px;width:'+this.canvasWidth+'px;'}); - this.el.insert({bottom: tabsContainer}); - this.tabs = { - graph: new Element('div', {className:'flotr-tab selected', style:'float:left;'}).update(this.options.spreadsheet.tabGraphLabel), - data: new Element('div', {className:'flotr-tab', style:'float:left;'}).update(this.options.spreadsheet.tabDataLabel) - } - - tabsContainer.insert(this.tabs.graph).insert(this.tabs.data); - - this.el.setStyle({height: this.canvasHeight+this.tabs.data.getHeight()+2+'px'}); - - this.tabs.graph.observe('click', (function() {this.showTab('graph')}).bind(this)); - this.tabs.data.observe('click', (function() {this.showTab('data')}).bind(this)); - }, - - // @todo: make a spreadsheet manager (Flotr.Spreadsheet) - constructDataGrid: function(){ - // If the data grid has already been built, nothing to do here - if (this.datagrid) return this.datagrid; - - var i, j, - s = this.series, - datagrid = this.loadDataGrid(); - - var t = this.datagrid = new Element('table', {className:'flotr-datagrid', style:'height:100px;'}); - var colgroup = ['']; - - // First row : series' labels - var html = ['']; - html.push(' '); - for (i = 0; i < s.length; ++i) { - html.push(''+(s[i].label || String.fromCharCode(65+i))+''); - colgroup.push(''); - } - html.push(''); - - // Data rows - for (j = 0; j < datagrid.length; ++j) { - html.push(''); - for (i = 0; i < s.length+1; ++i) { - var tag = 'td'; - var content = (datagrid[j][i] != null ? Math.round(datagrid[j][i]*100000)/100000 : ''); - - if (i == 0) { - tag = 'th'; - var label; - if(this.options.xaxis.ticks) { - var tick = this.options.xaxis.ticks.find(function (x) { return x[0] == datagrid[j][i] }); - if (tick) label = tick[1]; - } - else { - label = this.options.xaxis.tickFormatter(content); - } - - if (label) content = label; - } - - html.push('<'+tag+(tag=='th'?' scope="row"':'')+'>'+content+''); - } - html.push(''); - } - colgroup.push(''); - t.update(colgroup.join('')+html.join('')); - - if (!Prototype.Browser.IE) { - t.select('td').each(function(td) { - td.observe('mouseover', function(e){ - td = e.element(); - var siblings = td.previousSiblings(); - - t.select('th[scope=col]')[siblings.length-1].addClassName('hover'); - t.select('colgroup col')[siblings.length].addClassName('hover'); - }); - - td.observe('mouseout', function(){ - t.select('colgroup col.hover, th.hover').each(function(e){e.removeClassName('hover')}); - }); - }); - } - - var toolbar = new Element('div', {className: 'flotr-datagrid-toolbar'}). - insert(new Element('button', {type:'button', className:'flotr-datagrid-toolbar-button'}).update(this.options.spreadsheet.toolbarDownload).observe('click', this.downloadCSV.bind(this))). - insert(new Element('button', {type:'button', className:'flotr-datagrid-toolbar-button'}).update(this.options.spreadsheet.toolbarSelectAll).observe('click', this.selectAllData.bind(this))); - - var container = new Element('div', {className:'flotr-datagrid-container', style:'left:0px;top:0px;width:'+this.canvasWidth+'px;height:'+this.canvasHeight+'px;overflow:auto;'}); - container.insert(toolbar); - t.wrap(container.hide()); - - this.el.insert(container); - return t; - }, - selectAllData: function(){ - if (this.tabs) { - var selection, range, doc, win, node = this.constructDataGrid(); - - this.showTab('data'); - - // deferred to be able to select the table - (function () { - if ((doc = node.ownerDocument) && (win = doc.defaultView) && - win.getSelection && doc.createRange && - (selection = window.getSelection()) && - selection.removeAllRanges) { - range = doc.createRange(); - range.selectNode(node); - selection.removeAllRanges(); - selection.addRange(range); - } - else if (document.body && document.body.createTextRange && - (range = document.body.createTextRange())) { - range.moveToElementText(node); - range.select(); - } - }).defer(); - return true; - } - else return false; - }, - downloadCSV: function(){ - var i, csv = '"x"', - series = this.series, - dg = this.loadDataGrid(); - - for (i = 0; i < series.length; ++i) { - csv += '%09"'+(series[i].label || String.fromCharCode(65+i))+'"'; // \t - } - csv += "%0D%0A"; // \r\n - - for (i = 0; i < dg.length; ++i) { - if (this.options.xaxis.ticks) { - var tick = this.options.xaxis.ticks.find(function (x) { return x[0] == dg[i][0] }); - if (tick) dg[i][0] = tick[1]; - } else { - dg[i][0] = this.options.xaxis.tickFormatter(dg[i][0]); - } - csv += dg[i].join('%09')+"%0D%0A"; // \t and \r\n - } - if (Prototype.Browser.IE) { - csv = csv.gsub('%09', '\t').gsub('%0A', '\n').gsub('%0D', '\r'); - window.open().document.write(csv); - } - else { - window.open('data:text/csv,'+csv); - } - }, - /** - * Initializes event some handlers. - */ - initEvents: function () { - //@todo: maybe stopObserving with only flotr functions - this.overlay.stopObserving(); - this.overlay.observe('mousedown', this.mouseDownHandler.bind(this)); - this.overlay.observe('mousemove', this.mouseMoveHandler.bind(this)); - this.overlay.observe('click', this.clickHandler.bind(this)); - }, - /** - * Function determines the min and max values for the xaxis and yaxis. - */ - findDataRanges: function(){ - var s = this.series, - a = this.axes; - - a.x.datamin = 0; a.x.datamax = 0; - a.x2.datamin = 0; a.x2.datamax = 0; - a.y.datamin = 0; a.y.datamax = 0; - a.y2.datamin = 0; a.y2.datamax = 0; - - if(s.length > 0){ - var i, j, h, x, y, data, xaxis, yaxis; - - // Get datamin, datamax start values - for(i = 0; i < s.length; ++i) { - data = s[i].data, - xaxis = s[i].xaxis, - yaxis = s[i].yaxis; - - if (data.length > 0 && !s[i].hide) { - if (!xaxis.used) xaxis.datamin = xaxis.datamax = data[0][0]; - if (!yaxis.used) yaxis.datamin = yaxis.datamax = data[0][1]; - xaxis.used = true; - yaxis.used = true; - - for(h = data.length - 1; h > -1; --h){ - x = data[h][0]; - if(x < xaxis.datamin) xaxis.datamin = x; - else if(x > xaxis.datamax) xaxis.datamax = x; - - for(j = 1; j < data[h].length; j++){ - y = data[h][j]; - if(y < yaxis.datamin) yaxis.datamin = y; - else if(y > yaxis.datamax) yaxis.datamax = y; - } - } - } - if (this.options.radarChartMode) { - xaxis.datamin = yaxis.datamin = - yaxis.datamax; - xaxis.datamax = yaxis.datamax; - if (!this.options.radarChartSides) this.options.radarChartSides = data.length; - } - } - } - - this.findXAxesValues(); - - this.calculateRange(a.x); - this.extendXRangeIfNeededByBar(a.x); - - if (a.x2.used) { - this.calculateRange(a.x2); - this.extendXRangeIfNeededByBar(a.x2); - } - - this.calculateRange(a.y); - this.extendYRangeIfNeededByBar(a.y); - - if (a.y2.used) { - this.calculateRange(a.y2); - this.extendYRangeIfNeededByBar(a.y2); - } - }, - /** - * Calculates the range of an axis to apply autoscaling. - */ - calculateRange: function(axis){ - var o = axis.options, - min = o.min != null ? o.min : axis.datamin, - max = o.max != null ? o.max : axis.datamax, - margin; - - if(max - min == 0.0){ - var widen = (max == 0.0) ? 1.0 : 0.01; - min -= widen; - max += widen; - } - axis.tickSize = Flotr.getTickSize(o.noTicks, ((this.options.radarChartMode) ? 0 : min), max, o.tickDecimals); - - // Autoscaling. - if(o.min == null){ - // Add a margin. - margin = o.autoscaleMargin; - if(margin != 0){ - min -= axis.tickSize * margin; - - // Make sure we don't go below zero if all values are positive. - if(min < 0 && axis.datamin >= 0) min = 0; - min = axis.tickSize * Math.floor(min / axis.tickSize); - } - } - if(o.max == null){ - margin = o.autoscaleMargin; - if(margin != 0){ - max += axis.tickSize * margin; - if(max > 0 && axis.datamax <= 0) max = 0; - max = axis.tickSize * Math.ceil(max / axis.tickSize); - } - } - axis.min = min; - axis.max = max; - }, - /** - * Bar series autoscaling in x direction. - */ - extendXRangeIfNeededByBar: function(axis){ - if(axis.options.max == null){ - var newmax = axis.max, - i, s, b, c, - stackedSums = [], - lastSerie = null; - - for(i = 0; i < this.series.length; ++i){ - s = this.series[i]; - b = s.bars; - c = s.candles; - if(s.axis == axis && (b.show || c.show)) { - if (!b.horizontal && (b.barWidth + axis.datamax > newmax) || (c.candleWidth + axis.datamax > newmax)){ - newmax = axis.max + s.bars.barWidth; - } - if(b.stacked && b.horizontal){ - for (j = 0; j < s.data.length; j++) { - if (s.bars.show && s.bars.stacked) { - var x = s.data[j][0]; - stackedSums[x] = (stackedSums[x] || 0) + s.data[j][1]; - lastSerie = s; - } - } - - for (j = 0; j < stackedSums.length; j++) { - newmax = Math.max(stackedSums[j], newmax); - } - } - } - } - axis.lastSerie = lastSerie; - axis.max = newmax; - } - }, - /** - * Bar series autoscaling in y direction. - */ - extendYRangeIfNeededByBar: function(axis){ - if(axis.options.max == null){ - var newmax = axis.max, - i, s, b, c, - stackedSums = [], - lastSerie = null; - - for(i = 0; i < this.series.length; ++i){ - s = this.series[i]; - b = s.bars; - c = s.candles; - if (s.yaxis == axis && b.show && !s.hide) { - if (b.horizontal && (b.barWidth + axis.datamax > newmax) || (c.candleWidth + axis.datamax > newmax)){ - newmax = axis.max + b.barWidth; - } - if(b.stacked && !b.horizontal){ - for (j = 0; j < s.data.length; j++) { - if (s.bars.show && s.bars.stacked) { - var x = s.data[j][0]; - stackedSums[x] = (stackedSums[x] || 0) + s.data[j][1]; - lastSerie = s; - } - } - - for (j = 0; j < stackedSums.length; j++) { - newmax = Math.max(stackedSums[j], newmax); - } - } - } - } - axis.lastSerie = lastSerie; - axis.max = newmax; - } - }, - /** - * Find every values of the x axes - */ - findXAxesValues: function(){ - for(i = this.series.length-1; i > -1 ; --i){ - s = this.series[i]; - s.xaxis.values = s.xaxis.values || []; - for (j = s.data.length-1; j > -1 ; --j){ - s.xaxis.values[s.data[j][0]] = {}; - } - } - }, - /** - * Calculate axis ticks. - * @param {Object} axis - axis object - * @param {Object} o - axis options - */ - calculateTicks: function(axis){ - var o = axis.options, i, v; - - axis.ticks = []; - if(o.ticks){ - var ticks = o.ticks, t, label; - - if(Object.isFunction(ticks)){ - ticks = ticks({min: axis.min, max: axis.max}); - } - - // Clean up the user-supplied ticks, copy them over. - for(i = 0; i < ticks.length; ++i){ - t = ticks[i]; - if(typeof(t) == 'object'){ - v = t[0]; - label = (t.length > 1) ? t[1] : o.tickFormatter(v); - }else{ - v = t; - label = o.tickFormatter(v); - } - axis.ticks[i] = { v: v, label: label }; - } - } - else { - // Round to nearest multiple of tick size. - var start = axis.tickSize * Math.ceil(axis.min / axis.tickSize), - decimals; - - // Then store all possible ticks. - for(i = 0; start + i * axis.tickSize <= axis.max; ++i){ - v = start + i * axis.tickSize; - - // Round (this is always needed to fix numerical instability). - decimals = o.tickDecimals; - if(decimals == null) decimals = 1 - Math.floor(Math.log(axis.tickSize) / Math.LN10); - if(decimals < 0) decimals = 0; - - v = v.toFixed(decimals); - axis.ticks.push({ v: v, label: o.tickFormatter(v) }); - } - } - }, - /** - * Calculates axis label sizes. - */ - calculateSpacing: function(){ - var a = this.axes, - options = this.options, - series = this.series, - margin = options.grid.labelMargin, - x = a.x, - x2 = a.x2, - y = a.y, - y2 = a.y2, - maxOutset = 2, - i, j, l, dim; - - // Labels width and height - [x, x2, y, y2].each(function(axis) { - var maxLabel = ''; - - if (axis.options.showLabels) { - for(i = 0; i < axis.ticks.length; ++i){ - l = axis.ticks[i].label.length; - if(l > maxLabel.length){ - maxLabel = axis.ticks[i].label; - } - } - } - axis.maxLabel = this.getTextDimensions(maxLabel, {size:options.fontSize, angle: Flotr.toRad(axis.options.labelsAngle)}, 'font-size:smaller;', 'flotr-grid-label'); - axis.titleSize = this.getTextDimensions(axis.options.title, {size: options.fontSize*1.2, angle: Flotr.toRad(axis.options.titleAngle)}, 'font-weight:bold;', 'flotr-axis-title'); - }, this); - - // Title height - dim = this.getTextDimensions(options.title, {size: options.fontSize*1.5}, 'font-size:1em;font-weight:bold;', 'flotr-title'); - this.titleHeight = dim.height; - - // Subtitle height - dim = this.getTextDimensions(options.subtitle, {size: options.fontSize}, 'font-size:smaller;', 'flotr-subtitle'); - this.subtitleHeight = dim.height; - - // Grid outline line width. - if(options.show){ - maxOutset = Math.max(maxOutset, options.points.radius + options.points.lineWidth/2); - } - for(j = 0; j < options.length; ++j){ - if (series[j].points.show){ - maxOutset = Math.max(maxOutset, series[j].points.radius + series[j].points.lineWidth/2); - } - } - - var p = this.plotOffset = {left: 0, right: 0, top: 0, bottom: 0}; - p.left = p.right = p.top = p.bottom = maxOutset; - - p.bottom += (x.options.showLabels ? (x.maxLabel.height + margin) : 0) + - (x.options.title ? (x.titleSize.height + margin) : 0); - - p.top += (x2.options.showLabels ? (x2.maxLabel.height + margin) : 0) + - (x2.options.title ? (x2.titleSize.height + margin) : 0) + this.subtitleHeight + this.titleHeight + - this.options.radarChartMode ? (y.options.showLabels ? (y.maxLabel.height + margin) : 0) : 0; - - p.left += (y.options.showLabels ? (y.maxLabel.width + margin) : 0) + - (y.options.title ? (y.titleSize.width + margin) : 0); - - p.right += (y2.options.showLabels ? (y2.maxLabel.width + margin) : 0) + - (y2.options.title ? (y2.titleSize.width + margin) : 0) + - this.options.radarChartMode ? (x.options.showLabels ? (x.maxLabel.width + margin) : 0) : 0; - - p.top = Math.floor(p.top); // In order the outline not to be blured - - this.plotWidth = this.canvasWidth - p.left - p.right; - this.plotHeight = this.canvasHeight - p.bottom - p.top; - - x.scale = this.plotWidth / (x.max - x.min); - x2.scale = this.plotWidth / (x2.max - x2.min); - y.scale = this.plotHeight / (y.max - y.min); - y2.scale = this.plotHeight / (y2.max - y2.min); - }, - /** - * Draws grid, labels and series. - */ - draw: function() { - this.drawGrid(); - this.drawLabels(); - this.drawTitles(); - - if(this.series.length){ - this.el.fire('flotr:beforedraw', [this.series, this]); - for(var i = 0; i < this.series.length; i++){ - if (!this.series[i].hide) - this.drawSeries(this.series[i]); - } - } - this.el.fire('flotr:afterdraw', [this.series, this]); - }, - /** - * Translates absolute horizontal x coordinates to relative coordinates. - * @param {Integer} x - absolute integer x coordinate - * @return {Integer} translated relative x coordinate - */ - tHoz: function(x, axis){ - axis = axis || this.axes.x; - return (x - axis.min) * axis.scale; - }, - /** - * Translates absolute vertical x coordinates to relative coordinates. - * @param {Integer} y - absolute integer y coordinate - * @return {Integer} translated relative y coordinate - */ - tVert: function(y, axis){ - axis = axis || this.axes.y; - return this.plotHeight - (y - axis.min) * axis.scale; - }, - /** - * Draws a grid for the graph. - */ - drawGrid: function(){ - if (this.options.radarChartMode) { // If we are in radar chart mode call drawRadarGrid instead and exit - this.drawRadarGrid(); - return; - } - var v, o = this.options, - ctx = this.ctx; - if(o.grid.verticalLines || o.grid.horizontalLines){ - this.el.fire('flotr:beforegrid', [this.axes.x, this.axes.y, o, this]); - } - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - - // Draw grid background, if present in options. - if(o.grid.backgroundColor != null){ - ctx.fillStyle = o.grid.backgroundColor; - ctx.fillRect(0, 0, this.plotWidth, this.plotHeight); - } - - // Draw grid lines in vertical direction. - ctx.lineWidth = 1; - ctx.strokeStyle = o.grid.tickColor; - ctx.beginPath(); - if(o.grid.verticalLines){ - for(var i = 0; i < this.axes.x.ticks.length; ++i){ - v = this.axes.x.ticks[i].v; - // Don't show lines on upper and lower bounds. - if ((v == this.axes.x.min || v == this.axes.x.max) && o.grid.outlineWidth != 0) - continue; - - ctx.moveTo(Math.floor(this.tHoz(v)) + ctx.lineWidth/2, 0); - ctx.lineTo(Math.floor(this.tHoz(v)) + ctx.lineWidth/2, this.plotHeight); - } - } - - // Draw grid lines in horizontal direction. - if(o.grid.horizontalLines){ - for(var j = 0; j < this.axes.y.ticks.length; ++j){ - v = this.axes.y.ticks[j].v; - // Don't show lines on upper and lower bounds. - if ((v == this.axes.y.min || v == this.axes.y.max) && o.grid.outlineWidth != 0) - continue; - - ctx.moveTo(0, Math.floor(this.tVert(v)) + ctx.lineWidth/2); - ctx.lineTo(this.plotWidth, Math.floor(this.tVert(v)) + ctx.lineWidth/2); - } - } - ctx.stroke(); - - // Draw axis/grid border. - if(o.grid.outlineWidth != 0) { - ctx.lineWidth = o.grid.outlineWidth; - ctx.strokeStyle = o.grid.color; - ctx.lineJoin = 'round'; - ctx.strokeRect(0, 0, this.plotWidth, this.plotHeight); - } - ctx.restore(); - if(o.grid.verticalLines || o.grid.horizontalLines){ - this.el.fire('flotr:aftergrid', [this.axes.x, this.axes.y, o, this]); - } - }, - /** - * Draws a grid for the graph. - */ - drawRadarGrid: function(){ - - var v, o = this.options, - ctx = this.ctx; - - var sides = this.options.radarChartSides, - degreesInRadiansForAngle = Math.PI * 2 / sides, - nintyDegrees = Math.PI / 2; - - if(o.grid.verticalLines || o.grid.horizontalLines){ - this.el.fire('flotr:beforegrid', [this.axes.x, this.axes.y, o, this]); - } - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'round'; - - // Draw grid background, if present in options. - if(o.grid.backgroundColor != null){ - ctx.fillStyle = o.grid.backgroundColor; - ctx.fillRect(0, 0, this.plotWidth, this.plotHeight); - } - - // Draw grid lines - var regPoly = {}; - regPoly.xaxis = {}; - regPoly.yaxis = {}; - regPoly.xaxis.min = regPoly.yaxis.min = this.axes.x.min; - regPoly.xaxis.max = regPoly.yaxis.max = this.axes.x.max; - regPoly.xaxis.scale = this.plotWidth / (this.axes.x.max - this.axes.x.min); - regPoly.yaxis.scale = this.plotHeight / (this.axes.x.max - this.axes.x.min); - - ctx.lineWidth = 1; - ctx.strokeStyle = o.grid.tickColor; - - if(o.grid.horizontalLines){ - for(var j = 0; j < this.axes.y.ticks.length; ++j){ - v = this.axes.y.ticks[j].v; - if (v < 0) continue; - // Don't show lines on upper and lower bounds. - if ((v == this.axes.y.min || v == this.axes.y.max) && o.grid.outlineWidth != 0) - continue; - regPoly.data = new Array(); - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - regPoly.data[i] = [v * Math.cos(angle), v * Math.sin(angle)] - } - regPoly.data[sides] = regPoly.data[0]; - this.plotLine(regPoly,0); - } - } - - // Draw axis/grid border. - if(o.grid.outlineWidth != 0) { - ctx.lineWidth = o.grid.outlineWidth; - ctx.strokeStyle = o.grid.color; - regPoly.data = new Array(); - var radius = this.axes.x.max; - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - regPoly.data[i] = [radius * Math.cos(angle), radius * Math.sin(angle)] - } - regPoly.data[sides] = regPoly.data[0]; - this.plotLine(regPoly,0); - } - - ctx.lineWidth = 1; - ctx.strokeStyle = o.grid.tickColor; - ctx.beginPath(); - - if(o.grid.verticalLines){ - for(var i = 0; i < sides; ++i){ - ctx.moveTo(Math.floor(this.tHoz(0)) + ctx.lineWidth/2, - Math.floor(this.tVert(0)) + ctx.lineWidth/2); - ctx.lineTo(Math.floor(this.tHoz(regPoly.data[i][0])) + ctx.lineWidth/2, - Math.floor(this.tVert(regPoly.data[i][1])) + ctx.lineWidth/2); - } - } - - ctx.stroke(); - - ctx.restore(); - if(o.grid.verticalLines || o.grid.horizontalLines){ - this.el.fire('flotr:aftergrid', [this.axes.x, this.axes.y, o, this]); - } - }, - /** - * Draws labels aroung radar chart - */ - drawRadarLabels:function(){ - var ctx = this.ctx, - options = this.options, - axis = this.axes.x, - tick, minY = 0, maxY = 0, - xOffset, yOffset; - var style = { - size: options.fontSize, - adjustAlign: true - }; - style.color = axis.options.color || options.grid.color; - style.angle = Flotr.toRad(axis.options.labelsAngle); - var radius = axis.max * 1, - closeTo = axis.max * 0.1, - sides = this.options.radarChartSides, - degreesInRadiansForAngle = Math.PI * 2 / sides, - nintyDegrees = Math.PI / 2, - posdata = new Array(); - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - posdata[i] = [radius * Math.cos(angle), radius * Math.sin(angle)]; - if (minY > posdata[i][1]) minY = posdata[i][1]; - if (maxY < posdata[i][1]) maxY = posdata[i][1]; - } - for (i = 0; i < sides; i++) { - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - yOffset = 0; - if (posdata[i][0] > 0) { - style.halign = 'l'; - xOffset = options.grid.labelMargin; - } else { - style.halign = 'r'; - xOffset = - options.grid.labelMargin; - } - style.valign = 'm'; - - if ((posdata[i][1] + closeTo) >= minY && (posdata[i][1] - closeTo) <= minY) { - style.valign = 't' ; - style.halign = 'c'; - yOffset = options.grid.labelMargin; - }; - if (posdata[i][1] == maxY) { - style.valign = 'b' ; - style.halign = 'c'; - yOffset = - options.grid.labelMargin; - } - ctx.drawText( - tick.label, - this.plotOffset.left + this.tHoz(posdata[i][0]) + xOffset, - this.plotOffset.top + this.tVert(posdata[i][1]) + yOffset, - style - ); - } - - }, - /** - * Draws labels for x and y axis. - */ - drawLabels: function(){ - // Construct fixed width label boxes, which can be styled easily. - var noLabels = 0, axis, - xBoxWidth, i, html, tick, - options = this.options, - ctx = this.ctx, - a = this.axes; - - for(i = 0; i < a.x.ticks.length; ++i){ - if (a.x.ticks[i].label) { - ++noLabels; - } - } - xBoxWidth = this.plotWidth / noLabels; - - if (!options.HtmlText && this.textEnabled) { - var style = { - size: options.fontSize, - adjustAlign: true - }; - - // Add x labels. - if (options.radarChartMode) { - this.drawRadarLabels();} else { - axis = a.x; - style.color = axis.options.color || options.grid.color; - for(i = 0; i < axis.ticks.length && axis.options.showLabels && axis.used; ++i){ - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - - style.angle = Flotr.toRad(axis.options.labelsAngle); - style.halign = 'c'; - style.valign = 't'; - - ctx.drawText( - tick.label, - this.plotOffset.left + this.tHoz(tick.v, axis), - this.plotOffset.top + this.plotHeight + options.grid.labelMargin, - style - ); - }} - - // Add x2 labels. - axis = a.x2; - style.color = axis.options.color || options.grid.color; - for(i = 0; i < axis.ticks.length && axis.options.showLabels && axis.used; ++i){ - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - - style.angle = Flotr.toRad(axis.options.labelsAngle); - style.halign = 'c'; - style.valign = 'b'; - - ctx.drawText( - tick.label, - this.plotOffset.left + this.tHoz(tick.v, axis), - this.plotOffset.top + options.grid.labelMargin, - style - ); - } - - // Add y labels. - axis = a.y; - style.color = axis.options.color || options.grid.color; - for(i = 0; i < axis.ticks.length && axis.options.showLabels && axis.used; ++i){ - tick = axis.ticks[i]; - if (!tick.label || tick.label.length == 0 || (tick.v < 0 && this.options.radarChartMode)) continue; - - style.angle = Flotr.toRad(axis.options.labelsAngle); - style.halign = 'r'; - style.valign = 'm'; - - ctx.drawText( - tick.label, - this.plotOffset.left + (this.options.radarChartMode ? this.tHoz(0) : 0) - options.grid.labelMargin, - this.plotOffset.top + this.tVert(tick.v, axis), - style - ); - } - - // Add y2 labels. - axis = a.y2; - style.color = axis.options.color || options.grid.color; - for(i = 0; i < axis.ticks.length && axis.options.showLabels && axis.used; ++i){ - tick = axis.ticks[i]; - if (!tick.label || tick.label.length == 0) continue; - - style.angle = Flotr.toRad(axis.options.labelsAngle); - style.halign = 'l'; - style.valign = 'm'; - - ctx.drawText( - tick.label, - this.plotOffset.left + this.plotWidth + options.grid.labelMargin, - this.plotOffset.top + this.tVert(tick.v, axis), - style - ); - - ctx.save(); - ctx.strokeStyle = style.color; - ctx.beginPath(); - ctx.moveTo(this.plotOffset.left + this.plotWidth - 8, this.plotOffset.top + this.tVert(tick.v, axis)); - ctx.lineTo(this.plotOffset.left + this.plotWidth, this.plotOffset.top + this.tVert(tick.v, axis)); - ctx.stroke(); - ctx.restore(); - } - } - else if (a.x.options.showLabels || - a.x2.options.showLabels || - a.y.options.showLabels || - a.y2.options.showLabels) { - html = ['
']; - - // Add x labels. - axis = a.x; - if (axis.options.showLabels){ - for(i = 0; i < axis.ticks.length; ++i){ - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - html.push('
' + tick.label + '
'); - } - } - - // Add x2 labels. - axis = a.x2; - if (axis.options.showLabels && axis.used){ - for(i = 0; i < axis.ticks.length; ++i){ - tick = axis.ticks[i]; - if(!tick.label || tick.label.length == 0) continue; - html.push('
' + tick.label + '
'); - } - } - - // Add y labels. - axis = a.y; - if (axis.options.showLabels){ - for(i = 0; i < axis.ticks.length; ++i){ - tick = axis.ticks[i]; - if (!tick.label || tick.label.length == 0) continue; - html.push('
' + tick.label + '
'); - } - } - - // Add y2 labels. - axis = a.y2; - if (axis.options.showLabels && axis.used){ - ctx.save(); - ctx.strokeStyle = axis.options.color || options.grid.color; - ctx.beginPath(); - - for(i = 0; i < axis.ticks.length; ++i){ - tick = axis.ticks[i]; - if (!tick.label || tick.label.length == 0) continue; - html.push('
' + tick.label + '
'); - - ctx.moveTo(this.plotOffset.left + this.plotWidth - 8, this.plotOffset.top + this.tVert(tick.v, axis)); - ctx.lineTo(this.plotOffset.left + this.plotWidth, this.plotOffset.top + this.tVert(tick.v, axis)); - } - ctx.stroke(); - ctx.restore(); - } - - html.push('
'); - this.el.insert(html.join('')); - } - }, - /** - * Draws the title and the subtitle - */ - drawTitles: function(){ - var html, - options = this.options, - margin = options.grid.labelMargin, - ctx = this.ctx, - a = this.axes; - - if (!options.HtmlText && this.textEnabled) { - var style = { - size: options.fontSize, - color: options.grid.color, - halign: 'c' - }; - - // Add subtitle - if (options.subtitle){ - ctx.drawText( - options.subtitle, - this.plotOffset.left + this.plotWidth/2, - this.titleHeight + this.subtitleHeight - 2, - style - ); - } - - style.weight = 1.5; - style.size *= 1.5; - - // Add title - if (options.title){ - ctx.drawText( - options.title, - this.plotOffset.left + this.plotWidth/2, - this.titleHeight - 2, - style - ); - } - - style.weight = 1.8; - style.size *= 0.8; - style.adjustAlign = true; - - // Add x axis title - if (a.x.options.title && a.x.used){ - style.halign = 'c'; - style.valign = 't'; - style.angle = Flotr.toRad(a.x.options.titleAngle); - ctx.drawText( - a.x.options.title, - this.plotOffset.left + this.plotWidth/2, - this.plotOffset.top + a.x.maxLabel.height + this.plotHeight + 2 * margin, - style - ); - } - - // Add x2 axis title - if (a.x2.options.title && a.x2.used){ - style.halign = 'c'; - style.valign = 'b'; - style.angle = Flotr.toRad(a.x2.options.titleAngle); - ctx.drawText( - a.x2.options.title, - this.plotOffset.left + this.plotWidth/2, - this.plotOffset.top - a.x2.maxLabel.height - 2 * margin, - style - ); - } - - // Add y axis title - if (a.y.options.title && a.y.used){ - style.halign = 'r'; - style.valign = 'm'; - style.angle = Flotr.toRad(a.y.options.titleAngle); - ctx.drawText( - a.y.options.title, - this.plotOffset.left - a.y.maxLabel.width - 2 * margin, - this.plotOffset.top + this.plotHeight / 2, - style - ); - } - - // Add y2 axis title - if (a.y2.options.title && a.y2.used){ - style.halign = 'l'; - style.valign = 'm'; - style.angle = Flotr.toRad(a.y2.options.titleAngle); - ctx.drawText( - a.y2.options.title, - this.plotOffset.left + this.plotWidth + a.y2.maxLabel.width + 2 * margin, - this.plotOffset.top + this.plotHeight / 2, - style - ); - } - } - else { - html = ['
']; - - // Add title - if (options.title){ - html.push('
'+options.title+'
'); - } - - // Add subtitle - if (options.subtitle){ - html.push('
'+options.subtitle+'
'); - } - html.push('
'); - - - html.push('
'); - // Add x axis title - if (a.x.options.title && a.x.used){ - html.push('
' + a.x.options.title + '
'); - } - - // Add x2 axis title - if (a.x2.options.title && a.x2.used){ - html.push('
' + a.x2.options.title + '
'); - } - - // Add y axis title - if (a.y.options.title && a.y.used){ - html.push('
' + a.y.options.title + '
'); - } - - // Add y2 axis title - if (a.y2.options.title && a.y2.used){ - html.push('
' + a.y2.options.title + '
'); - } - html.push('
'); - - this.el.insert(html.join('')); - } - }, - /** - * Actually draws the graph. - * @param {Object} series - series to draw - */ - drawSeries: function(series){ - series = series || this.series; - - var drawn = false; - for(var type in Flotr._registeredTypes){ - if(series[type] && series[type].show){ - this[Flotr._registeredTypes[type]](series); - drawn = true; - } - } - - if(!drawn){ - this[Flotr._registeredTypes[this.options.defaultType]](series); - } - }, - - plotLine: function(series, offset){ - var ctx = this.ctx, - xa = series.xaxis, - ya = series.yaxis, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this), - data = series.data; - - if(data.length < 2) return; - - var prevx = tHoz(data[0][0], xa), - prevy = tVert(data[0][1], ya) + offset; - ctx.beginPath(); - ctx.moveTo(prevx, prevy); - for(var i = 0; i < data.length - 1; ++i){ - var x1 = data[i][0], y1 = data[i][1], - x2 = data[i+1][0], y2 = data[i+1][1]; - - // To allow empty values - if (y1 === null || y2 === null) continue; - - /** - * Clip with ymin. - */ - if(y1 <= y2 && y1 < ya.min){ - /** - * Line segment is outside the drawing area. - */ - if(y2 < ya.min) continue; - - /** - * Compute new intersection point. - */ - x1 = (ya.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = ya.min; - }else if(y2 <= y1 && y2 < ya.min){ - if(y1 < ya.min) continue; - x2 = (ya.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = ya.min; - } - - /** - * Clip with ymax. - */ - if(y1 >= y2 && y1 > ya.max) { - if(y2 > ya.max) continue; - x1 = (ya.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = ya.max; - } - else if(y2 >= y1 && y2 > ya.max){ - if(y1 > ya.max) continue; - x2 = (ya.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = ya.max; - } - - /** - * Clip with xmin. - */ - if(x1 <= x2 && x1 < xa.min){ - if(x2 < xa.min) continue; - y1 = (xa.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = xa.min; - }else if(x2 <= x1 && x2 < xa.min){ - if(x1 < xa.min) continue; - y2 = (xa.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = xa.min; - } - - /** - * Clip with xmax. - */ - if(x1 >= x2 && x1 > xa.max){ - if (x2 > xa.max) continue; - y1 = (xa.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = xa.max; - }else if(x2 >= x1 && x2 > xa.max){ - if(x1 > xa.max) continue; - y2 = (xa.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = xa.max; - } - - if(prevx != tHoz(x1, xa) || prevy != tVert(y1, ya) + offset) - ctx.moveTo(tHoz(x1, xa), tVert(y1, ya) + offset); - - prevx = tHoz(x2, xa); - prevy = tVert(y2, ya) + offset; - ctx.lineTo(prevx, prevy); - } - ctx.stroke(); - }, - /** - * Function used to fill - * @param {Object} data - */ - plotLineArea: function(series, offset){ - var data = series.data; - if(data.length < 2) return; - - var top, lastX = 0, - ctx = this.ctx, - xa = series.xaxis, - ya = series.yaxis, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this), - bottom = Math.min(Math.max(0, ya.min), ya.max), - first = true; - - ctx.beginPath(); - for(var i = 0; i < data.length - 1; ++i){ - - var x1 = data[i][0], y1 = data[i][1], - x2 = data[i+1][0], y2 = data[i+1][1]; - - if(x1 <= x2 && x1 < xa.min){ - if(x2 < xa.min) continue; - y1 = (xa.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = xa.min; - }else if(x2 <= x1 && x2 < xa.min){ - if(x1 < xa.min) continue; - y2 = (xa.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = xa.min; - } - - if(x1 >= x2 && x1 > xa.max){ - if(x2 > xa.max) continue; - y1 = (xa.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = xa.max; - }else if(x2 >= x1 && x2 > xa.max){ - if (x1 > xa.max) continue; - y2 = (xa.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = xa.max; - } - - if(first){ - ctx.moveTo(tHoz(x1, xa), tVert(bottom, ya) + offset); - first = false; - } - - /** - * Now check the case where both is outside. - */ - if(y1 >= ya.max && y2 >= ya.max){ - ctx.lineTo(tHoz(x1, xa), tVert(ya.max, ya) + offset); - ctx.lineTo(tHoz(x2, xa), tVert(ya.max, ya) + offset); - continue; - }else if(y1 <= ya.min && y2 <= ya.min){ - ctx.lineTo(tHoz(x1, xa), tVert(ya.min, ya) + offset); - ctx.lineTo(tHoz(x2, xa), tVert(ya.min, ya) + offset); - continue; - } - - /** - * Else it's a bit more complicated, there might - * be two rectangles and two triangles we need to fill - * in; to find these keep track of the current x values. - */ - var x1old = x1, x2old = x2; - - /** - * And clip the y values, without shortcutting. - * Clip with ymin. - */ - if(y1 <= y2 && y1 < ya.min && y2 >= ya.min){ - x1 = (ya.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = ya.min; - }else if(y2 <= y1 && y2 < ya.min && y1 >= ya.min){ - x2 = (ya.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = ya.min; - } - - /** - * Clip with ymax. - */ - if(y1 >= y2 && y1 > ya.max && y2 <= ya.max){ - x1 = (ya.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = ya.max; - }else if(y2 >= y1 && y2 > ya.max && y1 <= ya.max){ - x2 = (ya.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = ya.max; - } - - /** - * If the x value was changed we got a rectangle to fill. - */ - if(x1 != x1old){ - top = (y1 <= ya.min) ? top = ya.min : ya.max; - ctx.lineTo(tHoz(x1old, xa), tVert(top, ya) + offset); - ctx.lineTo(tHoz(x1, xa), tVert(top, ya) + offset); - } - - /** - * Fill the triangles. - */ - ctx.lineTo(tHoz(x1, xa), tVert(y1, ya) + offset); - ctx.lineTo(tHoz(x2, xa), tVert(y2, ya) + offset); - - /** - * Fill the other rectangle if it's there. - */ - if(x2 != x2old){ - top = (y2 <= ya.min) ? ya.min : ya.max; - ctx.lineTo(tHoz(x2old, xa), tVert(top, ya) + offset); - ctx.lineTo(tHoz(x2, xa), tVert(top, ya) + offset); - } - - lastX = Math.max(x2, x2old); - } - - ctx.lineTo(tHoz(lastX, xa), tVert(bottom, ya) + offset); - ctx.closePath(); - ctx.fill(); - }, - /** - * Function: (private) drawSeriesLines - * - * Function draws lines series in the canvas element. - * - * Parameters: - * series - Series with options.lines.show = true. - * - * Returns: - * void - */ - drawSeriesLines: function(series){ - series = series || this.series; - var ctx = this.ctx; - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'round'; - - var lw = series.lines.lineWidth; - var sw = series.shadowSize; - - if(sw > 0){ - ctx.lineWidth = sw / 2; - - var offset = lw/2 + ctx.lineWidth/2; - - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - this.plotLine(series, offset + sw/2); - - ctx.strokeStyle = "rgba(0,0,0,0.2)"; - this.plotLine(series, offset); - - if(series.lines.fill) { - ctx.fillStyle = "rgba(0,0,0,0.05)"; - this.plotLineArea(series, offset + sw/2); - } - } - - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - if(series.lines.fill){ - ctx.fillStyle = series.lines.fillColor != null ? series.lines.fillColor : Flotr.parseColor(series.color).scale(null, null, null, series.lines.fillOpacity).toString(); - this.plotLineArea(series, 0); - } - - this.plotLine(series, 0); - ctx.restore(); - }, - /** - * Function: drawSeriesPoints - * - * Function draws point series in the canvas element. - * - * Parameters: - * series - Series with options.points.show = true. - * - * Returns: - * void - */ - drawSeriesPoints: function(series) { - var ctx = this.ctx; - - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - - var lw = series.lines.lineWidth; - var sw = series.shadowSize; - - if(sw > 0){ - ctx.lineWidth = sw / 2; - - ctx.strokeStyle = 'rgba(0,0,0,0.1)'; - this.plotPointShadows(series, sw/2 + ctx.lineWidth/2, series.points.radius); - - ctx.strokeStyle = 'rgba(0,0,0,0.2)'; - this.plotPointShadows(series, ctx.lineWidth/2, series.points.radius); - } - - ctx.lineWidth = series.points.lineWidth; - ctx.strokeStyle = series.color; - ctx.fillStyle = series.points.fillColor != null ? series.points.fillColor : series.color; - this.plotPoints(series, series.points.radius, series.points.fill); - ctx.restore(); - }, - plotPoints: function (series, radius, fill) { - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, i, - data = series.data; - - for(i = data.length - 1; i > -1; --i){ - var x = data[i][0], y = data[i][1]; - if(x < xa.min || x > xa.max || y < ya.min || y > ya.max) - continue; - - ctx.beginPath(); - ctx.arc(this.tHoz(x, xa), this.tVert(y, ya), radius, 0, 2 * Math.PI, true); - if(fill) ctx.fill(); - ctx.stroke(); - } - }, - plotPointShadows: function(series, offset, radius){ - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, i, - data = series.data; - - for(i = data.length - 1; i > -1; --i){ - var x = data[i][0], y = data[i][1]; - if (x < xa.min || x > xa.max || y < ya.min || y > ya.max) - continue; - ctx.beginPath(); - ctx.arc(this.tHoz(x, xa), this.tVert(y, ya) + offset, radius, 0, Math.PI, false); - ctx.stroke(); - } - }, - /** - * Function: drawSeriesBars - * - * Function draws bar series in the canvas element. - * - * Parameters: - * series - Series with options.bars.show = true. - * - * Returns: - * void - */ - drawSeriesBars: function(series) { - var ctx = this.ctx, - bw = series.bars.barWidth, - lw = Math.min(series.bars.lineWidth, bw); - - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'miter'; - - /** - * @todo linewidth not interpreted the right way. - */ - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - - this.plotBarsShadows(series, bw, 0, series.bars.fill); - - if(series.bars.fill){ - ctx.fillStyle = series.bars.fillColor != null ? series.bars.fillColor : Flotr.parseColor(series.color).scale(null, null, null, series.bars.fillOpacity).toString(); - } - - this.plotBars(series, bw, 0, series.bars.fill); - ctx.restore(); - }, - plotBars: function(series, barWidth, offset, fill){ - var data = series.data; - if(data.length < 1) return; - - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this); - - for(var i = 0; i < data.length; i++){ - var x = data[i][0], - y = data[i][1]; - var drawLeft = true, drawTop = true, drawRight = true; - - // Stacked bars - var stackOffset = 0; - if(series.bars.stacked) { - xa.values.each(function(o, v) { - if (v == x) { - stackOffset = o.stack || 0; - o.stack = stackOffset + y; - } - }); - } - - // @todo: fix horizontal bars support - // Horizontal bars - if(series.bars.horizontal) - var left = stackOffset, right = x + stackOffset, bottom = y, top = y + barWidth; - else - var left = x, right = x + barWidth, bottom = stackOffset, top = y + stackOffset; - - if(right < xa.min || left > xa.max || top < ya.min || bottom > ya.max) - continue; - - if(left < xa.min){ - left = xa.min; - drawLeft = false; - } - - if(right > xa.max){ - right = xa.max; - if (xa.lastSerie != series && series.bars.horizontal) - drawTop = false; - } - - if(bottom < ya.min) - bottom = ya.min; - - if(top > ya.max){ - top = ya.max; - if (ya.lastSerie != series && !series.bars.horizontal) - drawTop = false; - } - - /** - * Fill the bar. - */ - if(fill){ - ctx.beginPath(); - ctx.moveTo(tHoz(left, xa), tVert(bottom, ya) + offset); - ctx.lineTo(tHoz(left, xa), tVert(top, ya) + offset); - ctx.lineTo(tHoz(right, xa), tVert(top, ya) + offset); - ctx.lineTo(tHoz(right, xa), tVert(bottom, ya) + offset); - ctx.fill(); - } - - /** - * Draw bar outline/border. - */ - if(series.bars.lineWidth != 0 && (drawLeft || drawRight || drawTop)){ - ctx.beginPath(); - ctx.moveTo(tHoz(left, xa), tVert(bottom, ya) + offset); - - ctx[drawLeft ?'lineTo':'moveTo'](tHoz(left, xa), tVert(top, ya) + offset); - ctx[drawTop ?'lineTo':'moveTo'](tHoz(right, xa), tVert(top, ya) + offset); - ctx[drawRight?'lineTo':'moveTo'](tHoz(right, xa), tVert(bottom, ya) + offset); - - ctx.stroke(); - } - } - }, - plotBarsShadows: function(series, barWidth, offset){ - var data = series.data; - if(data.length < 1) return; - - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this), - sw = this.options.shadowSize; - - for(var i = 0; i < data.length; i++){ - var x = data[i][0], - y = data[i][1]; - - // Stacked bars - var stackOffset = 0; - if(series.bars.stacked) { - xa.values.each(function(o, v) { - if (v == x) { - stackOffset = o.stackShadow || 0; - o.stackShadow = stackOffset + y; - } - }); - } - - // Horizontal bars - if(series.bars.horizontal) - var left = stackOffset, right = x + stackOffset, bottom = y, top = y + barWidth; - else - var left = x, right = x + barWidth, bottom = stackOffset, top = y + stackOffset; - - if(right < xa.min || left > xa.max || top < ya.min || bottom > ya.max) - continue; - - if(left < xa.min) left = xa.min; - if(right > xa.max) right = xa.max; - if(bottom < ya.min) bottom = ya.min; - if(top > ya.max) top = ya.max; - - var width = tHoz(right, xa)-tHoz(left, xa)-((tHoz(right, xa)+sw <= this.plotWidth) ? 0 : sw); - var height = Math.max(0, tVert(bottom, ya)-tVert(top, ya)-((tVert(bottom, ya)+sw <= this.plotHeight) ? 0 : sw)); - - ctx.fillStyle = 'rgba(0,0,0,0.05)'; - ctx.fillRect(Math.min(tHoz(left, xa)+sw, this.plotWidth), Math.min(tVert(top, ya)+sw, this.plotWidth), width, height); - } - }, - /** - * Function: drawSeriesCandles - * - * Function draws candles series in the canvas element. - * - * Parameters: - * series - Series with options.candles.show = true. - * - * Returns: - * void - */ - drawSeriesCandles: function(series) { - var ctx = this.ctx, - bw = series.candles.candleWidth; - - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'miter'; - - /** - * @todo linewidth not interpreted the right way. - */ - ctx.lineWidth = series.candles.lineWidth; - this.plotCandlesShadows(series, bw/2); - this.plotCandles(series, bw/2); - - ctx.restore(); - }, - plotCandles: function(series, offset){ - var data = series.data; - if(data.length < 1) return; - - var xa = series.xaxis, - ya = series.yaxis, - ctx = this.ctx, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this); - - for(var i = 0; i < data.length; i++){ - var d = data[i], - x = d[0], - open = d[1], - high = d[2], - low = d[3], - close = d[4]; - - var left = x, - right = x + series.candles.candleWidth, - bottom = Math.max(ya.min, low), - top = Math.min(ya.max, high), - bottom2 = Math.max(ya.min, Math.min(open, close)), - top2 = Math.min(ya.max, Math.max(open, close)); - - if(right < xa.min || left > xa.max || top < ya.min || bottom > ya.max) - continue; - - var color = series.candles[open>close?'downFillColor':'upFillColor']; - /** - * Fill the candle. - */ - if(series.candles.fill && !series.candles.barcharts){ - ctx.fillStyle = Flotr.parseColor(color).scale(null, null, null, series.candles.fillOpacity).toString(); - ctx.fillRect(tHoz(left, xa), tVert(top2, ya) + offset, tHoz(right, xa) - tHoz(left, xa), tVert(bottom2, ya) - tVert(top2, ya)); - } - - /** - * Draw candle outline/border, high, low. - */ - if(series.candles.lineWidth || series.candles.wickLineWidth){ - var x, y, pixelOffset = (series.candles.wickLineWidth % 2) / 2; - - x = Math.floor(tHoz((left + right) / 2), xa) + pixelOffset; - - ctx.save(); - ctx.strokeStyle = color; - ctx.lineWidth = series.candles.wickLineWidth; - ctx.lineCap = 'butt'; - - if (series.candles.barcharts) { - ctx.beginPath(); - - ctx.moveTo(x, Math.floor(tVert(top, ya) + offset)); - ctx.lineTo(x, Math.floor(tVert(bottom, ya) + offset)); - - y = Math.floor(tVert(open, ya) + offset)+0.5; - ctx.moveTo(Math.floor(tHoz(left, xa))+pixelOffset, y); - ctx.lineTo(x, y); - - y = Math.floor(tVert(close, ya) + offset)+0.5; - ctx.moveTo(Math.floor(tHoz(right, xa))+pixelOffset, y); - ctx.lineTo(x, y); - } - else { - ctx.strokeRect(tHoz(left, xa), tVert(top2, ya) + offset, tHoz(right, xa) - tHoz(left, xa), tVert(bottom2, ya) - tVert(top2, ya)); - - ctx.beginPath(); - ctx.moveTo(x, Math.floor(tVert(top2, ya) + offset)); - ctx.lineTo(x, Math.floor(tVert(top, ya) + offset)); - ctx.moveTo(x, Math.floor(tVert(bottom2, ya) + offset)); - ctx.lineTo(x, Math.floor(tVert(bottom, ya) + offset)); - } - - ctx.stroke(); - ctx.restore(); - } - } - }, - plotCandlesShadows: function(series, offset){ - var data = series.data; - if(data.length < 1 || series.candles.barcharts) return; - - var xa = series.xaxis, - ya = series.yaxis, - tHoz = this.tHoz.bind(this), - tVert = this.tVert.bind(this), - sw = this.options.shadowSize; - - for(var i = 0; i < data.length; i++){ - var d = data[i], - x = d[0], - open = d[1], - high = d[2], - low = d[3], - close = d[4]; - - var left = x, - right = x + series.candles.candleWidth, - bottom = Math.max(ya.min, Math.min(open, close)), - top = Math.min(ya.max, Math.max(open, close)); - - if(right < xa.min || left > xa.max || top < ya.min || bottom > ya.max) - continue; - - var width = tHoz(right, xa)-tHoz(left, xa)-((tHoz(right, xa)+sw <= this.plotWidth) ? 0 : sw); - var height = Math.max(0, tVert(bottom, ya)-tVert(top, ya)-((tVert(bottom, ya)+sw <= this.plotHeight) ? 0 : sw)); - - this.ctx.fillStyle = 'rgba(0,0,0,0.05)'; - this.ctx.fillRect(Math.min(tHoz(left, xa)+sw, this.plotWidth), Math.min(tVert(top, ya)+sw, this.plotWidth), width, height); - } - }, - /** - * Function: drawSeriesRadar - * - * Function draws a radar chart on the canvas element. - * - * Parameters: - * series - Series with options.radar.show = true. - * - * Returns: - * void - */ - drawSeriesRadar: function(series) { - var ctx = this.ctx, - options = this.options, sides= series.data.length; - - var degreesInRadiansForAngle = Math.PI * 2 / sides, - nintyDegrees = Math.PI / 2; - - var poly = {}; - - /* - Draw radar grid - - poly.xaxis = series.xaxis; - poly.yaxis = series.yaxis; - ctx.save(); - ctx.translate(this.plotOffset.left, this.plotOffset.top); - ctx.lineJoin = 'round'; - for (radius = 20; radius <= 100; radius += 20) { - poly.data = new Array(); - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - poly.data[i] = [radius * Math.cos(angle), radius * Math.sin(angle)] - } - poly.data[sides] = poly.data[0]; - this.plotLine(poly,0);} - - var outside = poly.data; - for (i = 0; i < sides; i++) { - poly.data = new Array(); - poly.data[0] = [0,0]; - poly.data[1] = outside[i]; - this.plotLine(poly,0); - } - */ - - /* - Convert Series data into X, Y co-ordinates - */ - if (!series.dataInRadarFormat) { - poly.data = new Array(); - for (i = 0; i < sides; i++) { - angle = nintyDegrees + (degreesInRadiansForAngle * i); - poly.data[i] = [series.data[i][1] * Math.cos(angle), series.data[i][1] * Math.sin(angle), series.data[i][0], series.data[i][1]] - } - poly.data[sides] = poly.data[0]; - series.data = poly.data; - series.lines = series.radar; - series.lines.show = false; - series.dataInRadarFormat = true; - } - - this.drawSeriesLines(series); - -}, - - - /** - * Function: drawSeriesPie - * - * Function draws a pie in the canvas element. - * - * Parameters: - * series - Series with options.pie.show = true. - * - * Returns: - * void - */ - drawSeriesPie: function(series) { - if (!this.options.pie.drawn) { - var ctx = this.ctx, - options = this.options, - lw = series.pie.lineWidth, - sw = series.shadowSize, - data = series.data, - radius = (Math.min(this.canvasWidth, this.canvasHeight) * series.pie.sizeRatio) / 2, - html = []; - - var vScale = 1;//Math.cos(series.pie.viewAngle); - var plotTickness = Math.sin(series.pie.viewAngle)*series.pie.spliceThickness / vScale; - - var style = { - size: options.fontSize*1.2, - color: options.grid.color, - weight: 1.5 - }; - - var center = { - x: (this.canvasWidth+this.plotOffset.left)/2, - y: (this.canvasHeight-this.plotOffset.bottom)/2 - }; - - // Pie portions - var portions = this.series.collect(function(hash, index){ - if (hash.pie.show) - return { - name: (hash.label || hash.data[0][1]), - value: [index, hash.data[0][1]], - explode: hash.pie.explode - }; - }); - - // Sum of the portions' angles - var sum = portions.pluck('value').pluck(1).inject(0, function(acc, n) { return acc + n; }); - - var fraction = 0.0, - angle = series.pie.startAngle, - value = 0.0; - - var slices = portions.collect(function(slice){ - angle += fraction; - value = parseFloat(slice.value[1]); // @warning : won't support null values !! - fraction = value/sum; - return { - name: slice.name, - fraction: fraction, - x: slice.value[0], - y: value, - explode: slice.explode, - startAngle: 2 * angle * Math.PI, - endAngle: 2 * (angle + fraction) * Math.PI - }; - }); - - ctx.save(); - - if(sw > 0){ - slices.each(function (slice) { - var bisection = (slice.startAngle + slice.endAngle) / 2; - - var xOffset = center.x + Math.cos(bisection) * slice.explode + sw; - var yOffset = center.y + Math.sin(bisection) * slice.explode + sw; - - this.plotSlice(xOffset, yOffset, radius, slice.startAngle, slice.endAngle, false, vScale); - - ctx.fillStyle = 'rgba(0,0,0,0.1)'; - ctx.fill(); - }, this); - } - - if (options.HtmlText) { - html = ['
']; - } - - slices.each(function (slice, index) { - var bisection = (slice.startAngle + slice.endAngle) / 2; - var color = options.colors[index]; - - var xOffset = center.x + Math.cos(bisection) * slice.explode; - var yOffset = center.y + Math.sin(bisection) * slice.explode; - - this.plotSlice(xOffset, yOffset, radius, slice.startAngle, slice.endAngle, false, vScale); - - if(series.pie.fill){ - ctx.fillStyle = Flotr.parseColor(color).scale(null, null, null, series.pie.fillOpacity).toString(); - ctx.fill(); - } - ctx.lineWidth = lw; - ctx.strokeStyle = color; - ctx.stroke(); - - /*ctx.save(); - ctx.scale(1, vScale); - - ctx.moveTo(xOffset, yOffset); - ctx.beginPath(); - ctx.lineTo(xOffset, yOffset+plotTickness); - ctx.lineTo(xOffset+Math.cos(slice.startAngle)*radius, yOffset+Math.sin(slice.startAngle)*radius+plotTickness); - ctx.lineTo(xOffset+Math.cos(slice.startAngle)*radius, yOffset+Math.sin(slice.startAngle)*radius); - ctx.lineTo(xOffset, yOffset); - ctx.closePath(); - ctx.fill();ctx.stroke(); - - ctx.moveTo(xOffset, yOffset); - ctx.beginPath(); - ctx.lineTo(xOffset, yOffset+plotTickness); - ctx.lineTo(xOffset+Math.cos(slice.endAngle)*radius, yOffset+Math.sin(slice.endAngle)*radius+plotTickness); - ctx.lineTo(xOffset+Math.cos(slice.endAngle)*radius, yOffset+Math.sin(slice.endAngle)*radius); - ctx.lineTo(xOffset, yOffset); - ctx.closePath(); - ctx.fill();ctx.stroke(); - - ctx.moveTo(xOffset+Math.cos(slice.startAngle)*radius, yOffset+Math.sin(slice.startAngle)*radius); - ctx.beginPath(); - ctx.lineTo(xOffset+Math.cos(slice.startAngle)*radius, yOffset+Math.sin(slice.startAngle)*radius+plotTickness); - ctx.arc(xOffset, yOffset+plotTickness, radius, slice.startAngle, slice.endAngle, false); - ctx.lineTo(xOffset+Math.cos(slice.endAngle)*radius, yOffset+Math.sin(slice.endAngle)*radius); - ctx.arc(xOffset, yOffset, radius, slice.endAngle, slice.startAngle, true); - ctx.closePath(); - ctx.fill();ctx.stroke(); - - ctx.scale(1, 1/vScale); - this.plotSlice(xOffset, yOffset+plotTickness, radius, slice.startAngle, slice.endAngle, false, vScale); - ctx.stroke(); - if(series.pie.fill){ - ctx.fillStyle = Flotr.parseColor(color).scale(null, null, null, series.pie.fillOpacity).toString(); - ctx.fill(); - } - - ctx.restore();*/ - - var label = options.pie.labelFormatter(slice); - - var textAlignRight = (Math.cos(bisection) < 0); - var distX = xOffset + Math.cos(bisection) * (series.pie.explode + radius); - var distY = yOffset + Math.sin(bisection) * (series.pie.explode + radius); - - if (slice.fraction && label) { - if (options.HtmlText) { - var divStyle = 'position:absolute;top:' + (distY - 5) + 'px;'; //@todo: change - if (textAlignRight) { - divStyle += 'right:'+(this.canvasWidth - distX)+'px;text-align:right;'; - } - else { - divStyle += 'left:'+distX+'px;text-align:left;'; - } - html.push('
' + label + '
'); - } - else { - style.halign = textAlignRight ? 'r' : 'l'; - ctx.drawText( - label, - distX, - distY + style.size / 2, - style - ); - } - } - }, this); - - if (options.HtmlText) { - html.push('
'); - this.el.insert(html.join('')); - } - - ctx.restore(); - options.pie.drawn = true; - } - }, - plotSlice: function(x, y, radius, startAngle, endAngle, fill, vScale) { - var ctx = this.ctx; - vScale = vScale || 1; - - ctx.save(); - ctx.scale(1, vScale); - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.arc (x, y, radius, startAngle, endAngle, fill); - ctx.lineTo(x, y); - ctx.closePath(); - ctx.restore(); - }, - plotPie: function() {}, - /** - * Function: insertLegend - * - * Function adds a legend div to the canvas container or draws it on the canvas. - * - * Parameters: - * none - * - * Returns: - * void - */ - insertLegend: function(){ - if(!this.options.legend.show) - return; - - var series = this.series, - plotOffset = this.plotOffset, - options = this.options, - fragments = [], - rowStarted = false, - ctx = this.ctx, - i; - - var noLegendItems = series.findAll(function(s) {return (s.label && !s.hide)}).size(); - - if (noLegendItems) { - if (!options.HtmlText && this.textEnabled) { - var style = { - size: options.fontSize*1.1, - color: options.grid.color - }; - - // @todo: take css into account - //var dummyDiv = this.el.insert('
'); - - var p = options.legend.position, - m = options.legend.margin, - lbw = options.legend.labelBoxWidth, - lbh = options.legend.labelBoxHeight, - lbm = options.legend.labelBoxMargin, - offsetX = plotOffset.left + m, - offsetY = plotOffset.top + m; - - // We calculate the labels' max width - var labelMaxWidth = 0; - for(i = series.length - 1; i > -1; --i){ - if(!series[i].label || series[i].hide) continue; - var label = options.legend.labelFormatter(series[i].label); - labelMaxWidth = Math.max(labelMaxWidth, ctx.measureText(label, style)); - } - - var legendWidth = Math.round(lbw + lbm*3 + labelMaxWidth), - legendHeight = Math.round(noLegendItems*(lbm+lbh) + lbm); - - if(p.charAt(0) == 's') offsetY = plotOffset.top + this.plotHeight - (m + legendHeight); - if(p.charAt(1) == 'e') offsetX = plotOffset.left + this.plotWidth - (m + legendWidth); - - // Legend box - var color = Flotr.parseColor(options.legend.backgroundColor || 'rgb(240,240,240)').scale(null, null, null, options.legend.backgroundOpacity || 0.1).toString(); - - ctx.fillStyle = color; - ctx.fillRect(offsetX, offsetY, legendWidth, legendHeight); - ctx.strokeStyle = options.legend.labelBoxBorderColor; - ctx.strokeRect(Flotr.toPixel(offsetX), Flotr.toPixel(offsetY), legendWidth, legendHeight); - - // Legend labels - var x = offsetX + lbm; - var y = offsetY + lbm; - for(i = 0; i < series.length; i++){ - if(!series[i].label || series[i].hide) continue; - var label = options.legend.labelFormatter(series[i].label); - - ctx.fillStyle = series[i].color; - ctx.fillRect(x, y, lbw-1, lbh-1); - - ctx.strokeStyle = options.legend.labelBoxBorderColor; - ctx.lineWidth = 1; - ctx.strokeRect(Math.ceil(x)-1.5, Math.ceil(y)-1.5, lbw+2, lbh+2); - - // Legend text - ctx.drawText( - label, - x + lbw + lbm, - y + (lbh + style.size - ctx.fontDescent(style))/2, - style - ); - - y += lbh + lbm; - } - } - else { - for(i = 0; i < series.length; ++i){ - if(!series[i].label || series[i].hide) continue; - - if(i % options.legend.noColumns == 0){ - fragments.push(rowStarted ? '' : ''); - rowStarted = true; - } - - var label = options.legend.labelFormatter(series[i].label); - - fragments.push('
' + - '' + label + ''); - } - if(rowStarted) fragments.push(''); - - if(fragments.length > 0){ - var table = '' + fragments.join("") + '
'; - if(options.legend.container != null){ - $(options.legend.container).update(table); - }else{ - var pos = ''; - var p = options.legend.position, m = options.legend.margin; - - if(p.charAt(0) == 'n') pos += 'top:' + (m + plotOffset.top) + 'px;'; - else if(p.charAt(0) == 's') pos += 'bottom:' + (m + plotOffset.bottom) + 'px;'; - if(p.charAt(1) == 'e') pos += 'right:' + (m + plotOffset.right) + 'px;'; - else if(p.charAt(1) == 'w') pos += 'left:' + (m + plotOffset.left) + 'px;'; - - var div = this.el.insert('
' + table + '
').select('div.flotr-legend').first(); - - if(options.legend.backgroundOpacity != 0.0){ - /** - * Put in the transparent background separately to avoid blended labels and - * label boxes. - */ - var c = options.legend.backgroundColor; - if(c == null){ - var tmp = (options.grid.backgroundColor != null) ? options.grid.backgroundColor : Flotr.extractColor(div); - c = Flotr.parseColor(tmp).adjust(null, null, null, 1).toString(); - } - this.el.insert('
').select('div.flotr-legend-bg').first().setStyle({ - 'opacity': options.legend.backgroundOpacity - }); - } - } - } - } - } - }, - /** - * Function: getEventPosition - * - * Calculates the coordinates from a mouse event object. - * - * Parameters: - * event - Mouse Event object. - * - * Returns: - * Object with x and y coordinates of the mouse. - */ - getEventPosition: function (event){ - var offset = this.overlay.cumulativeOffset(), - rx = (event.pageX - offset.left - this.plotOffset.left), - ry = (event.pageY - offset.top - this.plotOffset.top), - ax = 0, ay = 0 - - if(event.pageX == null && event.clientX != null){ - var de = document.documentElement, b = document.body; - ax = event.clientX + (de && de.scrollLeft || b.scrollLeft || 0); - ay = event.clientY + (de && de.scrollTop || b.scrollTop || 0); - }else{ - ax = event.pageX; - ay = event.pageY; - } - - return { - x: this.axes.x.min + rx / this.axes.x.scale, - x2: this.axes.x2.min + rx / this.axes.x2.scale, - y: this.axes.y.max - ry / this.axes.y.scale, - y2: this.axes.y2.max - ry / this.axes.y2.scale, - relX: rx, - relY: ry, - absX: ax, - absY: ay - }; - }, - /** - * Function: clickHandler - * - * Handler observes the 'click' event and fires the 'flotr:click' event. - * - * Parameters: - * event - 'click' Event object. - * - * Returns: - * void - */ - clickHandler: function(event){ - if(this.ignoreClick){ - this.ignoreClick = false; - return; - } - this.el.fire('flotr:click', [this.getEventPosition(event), this]); - }, - /** - * Function: mouseMoveHandler - * - * Handler observes mouse movement over the graph area. Fires the - * 'flotr:mousemove' event. - * - * Parameters: - * event - 'mousemove' Event object. - * - * Returns: - * void - */ - mouseMoveHandler: function(event){ - var pos = this.getEventPosition(event); - - this.lastMousePos.pageX = pos.absX; - this.lastMousePos.pageY = pos.absY; - if(this.selectionInterval == null && (this.options.mouse.track || this.series.any(function(s){return s.mouse && s.mouse.track;}))){ - this.hit(pos); - } - - this.el.fire('flotr:mousemove', [event, pos, this]); - }, - /** - * Function: mouseDownHandler - * - * Handler observes the 'mousedown' event. - * - * Parameters: - * event - 'mousedown' Event object. - * - * Returns: - * void - */ - mouseDownHandler: function (event){ - if(event.isRightClick()) { - event.stop(); - var overlay = this.overlay; - overlay.hide(); - - function cancelContextMenu () { - overlay.show(); - $(document).stopObserving('mousemove', cancelContextMenu); - } - $(document).observe('mousemove', cancelContextMenu); - return; - } - - if(!this.options.selection.mode || !event.isLeftClick()) return; - - this.setSelectionPos(this.selection.first, event); - if(this.selectionInterval != null){ - clearInterval(this.selectionInterval); - } - this.lastMousePos.pageX = null; - this.selectionInterval = setInterval(this.updateSelection.bind(this), 1000/this.options.selection.fps); - - this.mouseUpHandler = this.mouseUpHandler.bind(this); - $(document).observe('mouseup', this.mouseUpHandler); - }, - /** - * Function: (private) fireSelectEvent - * - * Fires the 'flotr:select' event when the user made a selection. - * - * Parameters: - * none - * - * Returns: - * void - */ - fireSelectEvent: function(){ - var a = this.axes, selection = this.selection, - x1 = (selection.first.x <= selection.second.x) ? selection.first.x : selection.second.x, - x2 = (selection.first.x <= selection.second.x) ? selection.second.x : selection.first.x, - y1 = (selection.first.y >= selection.second.y) ? selection.first.y : selection.second.y, - y2 = (selection.first.y >= selection.second.y) ? selection.second.y : selection.first.y; - - x1 = a.x.min + x1 / a.x.scale; - x2 = a.x.min + x2 / a.x.scale; - y1 = a.y.max - y1 / a.y.scale; - y2 = a.y.max - y2 / a.y.scale; - - this.el.fire('flotr:select', [{x1:x1, y1:y1, x2:x2, y2:y2}, this]); - }, - /** - * Function: (private) mouseUpHandler - * - * Handler observes the mouseup event for the document. - * - * Parameters: - * event - 'mouseup' Event object. - * - * Returns: - * void - */ - mouseUpHandler: function(event){ - $(document).stopObserving('mouseup', this.mouseUpHandler); - event.stop(); - - if(this.selectionInterval != null){ - clearInterval(this.selectionInterval); - this.selectionInterval = null; - } - - this.setSelectionPos(this.selection.second, event); - this.clearSelection(); - - if(this.selectionIsSane()){ - this.drawSelection(); - this.fireSelectEvent(); - this.ignoreClick = true; - } - }, - /** - * Function: setSelectionPos - * - * Calculates the position of the selection. - * - * Parameters: - * pos - Position object. - * event - Event object. - * - * Returns: - * void - */ - setSelectionPos: function(pos, event) { - var options = this.options, - offset = $(this.overlay).cumulativeOffset(); - - if(options.selection.mode.indexOf('x') == -1){ - pos.x = (pos == this.selection.first) ? 0 : this.plotWidth; - }else{ - pos.x = event.pageX - offset.left - this.plotOffset.left; - pos.x = Math.min(Math.max(0, pos.x), this.plotWidth); - } - - if (options.selection.mode.indexOf('y') == -1){ - pos.y = (pos == this.selection.first) ? 0 : this.plotHeight; - }else{ - pos.y = event.pageY - offset.top - this.plotOffset.top; - pos.y = Math.min(Math.max(0, pos.y), this.plotHeight); - } - }, - /** - * Function: updateSelection - * - * Updates (draws) the selection box. - * - * Parameters: - * none - * - * Returns: - * void - */ - updateSelection: function(){ - if(this.lastMousePos.pageX == null) return; - - this.setSelectionPos(this.selection.second, this.lastMousePos); - this.clearSelection(); - - if(this.selectionIsSane()) this.drawSelection(); - }, - /** - * Function: clearSelection - * - * Removes the selection box from the overlay canvas. - * - * Parameters: - * none - * - * Returns: - * void - */ - clearSelection: function() { - if(this.prevSelection == null) return; - - var prevSelection = this.prevSelection, - octx = this.octx, - plotOffset = this.plotOffset, - x = Math.min(prevSelection.first.x, prevSelection.second.x), - y = Math.min(prevSelection.first.y, prevSelection.second.y), - w = Math.abs(prevSelection.second.x - prevSelection.first.x), - h = Math.abs(prevSelection.second.y - prevSelection.first.y); - - octx.clearRect(x + plotOffset.left - octx.lineWidth, - y + plotOffset.top - octx.lineWidth, - w + octx.lineWidth*2, - h + octx.lineWidth*2); - - this.prevSelection = null; - }, - /** - * Function: setSelection - * - * Allows the user the manually select an area. - * - * Parameters: - * area - Object with coordinates to select. - * - * Returns: - * void - */ - setSelection: function(area){ - var options = this.options, - xa = this.axes.x, - ya = this.axes.y, - vertScale = yaxis.scale, - hozScale = xaxis.scale, - selX = options.selection.mode.indexOf('x') != -1, - selY = options.selection.mode.indexOf('y') != -1; - - this.clearSelection(); - - this.selection.first.y = selX ? 0 : (ya.max - area.y1) * vertScale; - this.selection.second.y = selX ? this.plotHeight : (ya.max - area.y2) * vertScale; - this.selection.first.x = selY ? 0 : (area.x1 - xa.min) * hozScale; - this.selection.second.x = selY ? this.plotWidth : (area.x2 - xa.min) * hozScale; - - this.drawSelection(); - this.fireSelectEvent(); - }, - /** - * Function: (private) drawSelection - * - * Draws the selection box. - * - * Parameters: - * none - * - * Returns: - * void - */ - drawSelection: function() { - var prevSelection = this.prevSelection, - selection = this.selection, - octx = this.octx, - options = this.options, - plotOffset = this.plotOffset; - - if(prevSelection != null && - selection.first.x == prevSelection.first.x && - selection.first.y == prevSelection.first.y && - selection.second.x == prevSelection.second.x && - selection.second.y == prevSelection.second.y) - return; - - octx.strokeStyle = Flotr.parseColor(options.selection.color).scale(null, null, null, 0.8).toString(); - octx.lineWidth = 1; - octx.lineJoin = 'round'; - octx.fillStyle = Flotr.parseColor(options.selection.color).scale(null, null, null, 0.4).toString(); - - this.prevSelection = { - first: { x: selection.first.x, y: selection.first.y }, - second: { x: selection.second.x, y: selection.second.y } - }; - - var x = Math.min(selection.first.x, selection.second.x), - y = Math.min(selection.first.y, selection.second.y), - w = Math.abs(selection.second.x - selection.first.x), - h = Math.abs(selection.second.y - selection.first.y); - - octx.fillRect(x + plotOffset.left, y + plotOffset.top, w, h); - octx.strokeRect(x + plotOffset.left, y + plotOffset.top, w, h); - }, - /** - * Function: (private) selectionIsSane - * - * Determines whether or not the selection is sane and should be drawn. - * - * Parameters: - * none - * - * Returns: - * boolean - True when sane, false otherwise. - */ - selectionIsSane: function(){ - var selection = this.selection; - return Math.abs(selection.second.x - selection.first.x) >= 5 && - Math.abs(selection.second.y - selection.first.y) >= 5; - }, - /** - * Function: clearHit - * - * Removes the mouse tracking point from the overlay. - * - * Parameters: - * none - * - * Returns: - * void - */ - clearHit: function(){ - if(this.prevHit){ - var options = this.options, - plotOffset = this.plotOffset, - prevHit = this.prevHit; - - this.octx.clearRect( - this.tHoz(prevHit.x) + plotOffset.left - options.points.radius*2, - this.tVert(prevHit.y) + plotOffset.top - options.points.radius*2, - options.points.radius*3 + options.points.lineWidth*3, - options.points.radius*3 + options.points.lineWidth*3 - ); - this.prevHit = null; - } - }, - /** - * Function: hit - * - * Retrieves the nearest data point from the mouse cursor. If it's within - * a certain range, draw a point on the overlay canvas and display the x and y - * value of the data. - * - * Parameters: - * mouse - Object that holds the relative x and y coordinates of the cursor. - * - * Returns: - * void - */ - hit: function(mouse){ - var series = this.series, - options = this.options, - prevHit = this.prevHit, - plotOffset = this.plotOffset, - octx = this.octx, - data, xsens, ysens, - /** - * Nearest data element. - */ - i, n = { - dist:Number.MAX_VALUE, - x:null, - y:null, - relX:mouse.relX, - relY:mouse.relY, - absX:mouse.absX, - absY:mouse.absY, - mouse:null, - radarData:null - }; - - for(i = 0; i < series.length; i++){ - s = series[i]; - if(!s.mouse.track) continue; - data = s.data; - xsens = (s.xaxis.scale*s.mouse.sensibility); - ysens = (s.yaxis.scale*s.mouse.sensibility); - - for(var j = 0, xpow, ypow; j < data.length; j++){ - if (data[j][1] === null) continue; - xpow = Math.pow(s.xaxis.scale*(data[j][0] - mouse.x), 2); - ypow = Math.pow(s.yaxis.scale*(data[j][1] - mouse.y), 2); - if(xpow < xsens && ypow < ysens && Math.sqrt(xpow+ypow) < n.dist){ - n.dist = Math.sqrt(xpow+ypow); - n.x = data[j][0]; - n.y = data[j][1]; - n.radarLabel = data[j][2]; - n.radarData = data[j][3]; - n.mouse = s.mouse; - } - } - } - - if(n.mouse && n.mouse.track && !prevHit || (prevHit && (n.x != prevHit.x || n.y != prevHit.y))){ - var mt = this.mouseTrack || this.el.select(".flotr-mouse-value")[0], - pos = '', - p = options.mouse.position, - m = options.mouse.margin, - elStyle = 'opacity:0.7;background-color:#000;color:#fff;display:none;position:absolute;padding:2px 8px;-moz-border-radius:4px;border-radius:4px;white-space:nowrap;'; - - if (!options.mouse.relative) { // absolute to the canvas - if(p.charAt(0) == 'n') pos += 'top:' + (m + plotOffset.top) + 'px;'; - else if(p.charAt(0) == 's') pos += 'bottom:' + (m + plotOffset.bottom) + 'px;'; - if(p.charAt(1) == 'e') pos += 'right:' + (m + plotOffset.right) + 'px;'; - else if(p.charAt(1) == 'w') pos += 'left:' + (m + plotOffset.left) + 'px;'; - } - else { // relative to the mouse - if(p.charAt(0) == 'n') pos += 'bottom:' + (m - plotOffset.top - this.tVert(n.y) + this.canvasHeight) + 'px;'; - else if(p.charAt(0) == 's') pos += 'top:' + (m + plotOffset.top + this.tVert(n.y)) + 'px;'; - if(p.charAt(1) == 'e') pos += 'left:' + (m + plotOffset.left + this.tHoz(n.x)) + 'px;'; - else if(p.charAt(1) == 'w') pos += 'right:' + (m - plotOffset.left - this.tHoz(n.x) + this.canvasWidth) + 'px;'; - } - - elStyle += pos; - - if(!mt){ - this.el.insert('
'); - mt = this.mouseTrack = this.el.select('.flotr-mouse-value').first(); - } - else { - this.mouseTrack = mt.setStyle(elStyle); - } - - if(n.x !== null && n.y !== null){ - mt.show(); - - this.clearHit(); - if(n.mouse.lineColor != null){ - octx.save(); - octx.translate(plotOffset.left, plotOffset.top); - octx.lineWidth = options.points.lineWidth; - octx.strokeStyle = n.mouse.lineColor; - octx.fillStyle = '#ffffff'; - octx.beginPath(); - octx.arc(this.tHoz(n.x), this.tVert(n.y), options.mouse.radius, 0, 2 * Math.PI, true); - octx.fill(); - octx.stroke(); - octx.restore(); - } - this.prevHit = n; - - var decimals = n.mouse.trackDecimals; - if(decimals == null || decimals < 0) decimals = 0; - - mt.innerHTML = n.mouse.trackFormatter({x: n.x.toFixed(decimals), y: n.y.toFixed(decimals), - radarLabel: n.radarLabel, radarData: n.radarData.toFixed(decimals)}); - mt.fire('flotr:hit', [n, this]); - } - else if(prevHit){ - mt.hide(); - this.clearHit(); - } - } - }, - saveImage: function (type, width, height, replaceCanvas) { - var image = null; - switch (type) { - case 'jpeg': - case 'jpg': image = Canvas2Image.saveAsJPEG(this.canvas, replaceCanvas, width, height); break; - default: - case 'png': image = Canvas2Image.saveAsPNG(this.canvas, replaceCanvas, width, height); break; - case 'bmp': image = Canvas2Image.saveAsBMP(this.canvas, replaceCanvas, width, height); break; - } - if (Object.isElement(image) && replaceCanvas) { - this.restoreCanvas(); - this.canvas.hide(); - this.overlay.hide(); - this.el.insert(image.setStyle({position: 'absolute'})); - } - }, - restoreCanvas: function() { - this.canvas.show(); - this.overlay.show(); - this.el.select('img').invoke('remove'); - } -}); - -Flotr.Color = Class.create({ - initialize: function(r, g, b, a){ - this.rgba = ['r','g','b','a']; - var x = 4; - while(-1<--x){ - this[this.rgba[x]] = arguments[x] || ((x==3) ? 1.0 : 0); - } - this.normalize(); - }, - - adjust: function(rd, gd, bd, ad) { - var x = 4; - while(-1<--x){ - if(arguments[x] != null) - this[this.rgba[x]] += arguments[x]; - } - return this.normalize(); - }, - - clone: function(){ - return new Flotr.Color(this.r, this.b, this.g, this.a); - }, - - limit: function(val,minVal,maxVal){ - return Math.max(Math.min(val, maxVal), minVal); - }, - - normalize: function(){ - var limit = this.limit; - this.r = limit(parseInt(this.r), 0, 255); - this.g = limit(parseInt(this.g), 0, 255); - this.b = limit(parseInt(this.b), 0, 255); - this.a = limit(this.a, 0, 1); - return this; - }, - - scale: function(rf, gf, bf, af){ - var x = 4; - while(-1<--x){ - if(arguments[x] != null) - this[this.rgba[x]] *= arguments[x]; - } - return this.normalize(); - }, - - distance: function(color){ - if (!color) return; - color = new Flotr.parseColor(color); - var dist = 0; - var x = 3; - while(-1<--x){ - dist += Math.abs(this[this.rgba[x]] - color[this.rgba[x]]); - } - return dist; - }, - - toString: function(){ - return (this.a >= 1.0) ? 'rgb('+[this.r,this.g,this.b].join(',')+')' : 'rgba('+[this.r,this.g,this.b,this.a].join(',')+')'; - } -}); - -Flotr.Color.lookupColors = { - aqua:[0,255,255], - azure:[240,255,255], - beige:[245,245,220], - black:[0,0,0], - blue:[0,0,255], - brown:[165,42,42], - cyan:[0,255,255], - darkblue:[0,0,139], - darkcyan:[0,139,139], - darkgrey:[169,169,169], - darkgreen:[0,100,0], - darkkhaki:[189,183,107], - darkmagenta:[139,0,139], - darkolivegreen:[85,107,47], - darkorange:[255,140,0], - darkorchid:[153,50,204], - darkred:[139,0,0], - darksalmon:[233,150,122], - darkviolet:[148,0,211], - fuchsia:[255,0,255], - gold:[255,215,0], - green:[0,128,0], - indigo:[75,0,130], - khaki:[240,230,140], - lightblue:[173,216,230], - lightcyan:[224,255,255], - lightgreen:[144,238,144], - lightgrey:[211,211,211], - lightpink:[255,182,193], - lightyellow:[255,255,224], - lime:[0,255,0], - magenta:[255,0,255], - maroon:[128,0,0], - navy:[0,0,128], - olive:[128,128,0], - orange:[255,165,0], - pink:[255,192,203], - purple:[128,0,128], - violet:[128,0,128], - red:[255,0,0], - silver:[192,192,192], - white:[255,255,255], - yellow:[255,255,0] -}; - -// not used yet -Flotr.Date = { - format: function(d, format) { - if (!d) return; - - var leftPad = function(n) { - n = n.toString(); - return n.length == 1 ? "0" + n : n; - }; - - var r = []; - var escape = false; - - for (var i = 0; i < format.length; ++i) { - var c = format.charAt(i); - - if (escape) { - switch (c) { - case 'h': c = d.getUTCHours().toString(); break; - case 'H': c = leftPad(d.getUTCHours()); break; - case 'M': c = leftPad(d.getUTCMinutes()); break; - case 'S': c = leftPad(d.getUTCSeconds()); break; - case 'd': c = d.getUTCDate().toString(); break; - case 'm': c = (d.getUTCMonth() + 1).toString(); break; - case 'y': c = d.getUTCFullYear().toString(); break; - case 'b': c = Flotr.Date.monthNames[d.getUTCMonth()]; break; - } - r.push(c); - escape = false; - } - else { - if (c == "%") - escape = true; - else - r.push(c); - } - } - return r.join(""); - }, - timeUnits: { - "second": 1000, - "minute": 60 * 1000, - "hour": 60 * 60 * 1000, - "day": 24 * 60 * 60 * 1000, - "month": 30 * 24 * 60 * 60 * 1000, - "year": 365.2425 * 24 * 60 * 60 * 1000 - }, - // the allowed tick sizes, after 1 year we use an integer algorithm - spec: [ - [1, "second"], [2, "second"], [5, "second"], [10, "second"], [30, "second"], - [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], [30, "minute"], - [1, "hour"], [2, "hour"], [4, "hour"], [8, "hour"], [12, "hour"], - [1, "day"], [2, "day"], [3, "day"], - [0.25, "month"], [0.5, "month"], [1, "month"], [2, "month"], [3, "month"], [6, "month"], - [1, "year"] - ], - monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] -}; --- a/js/flotr/lib/base64.js +++ /dev/null @@ -1,113 +1,1 @@ -/* Copyright (C) 1999 Masanao Izumo - * Version: 1.0 - * LastModified: Dec 25 1999 - * This library is free. You can redistribute it and/or modify it. - */ - -/* - * Interfaces: - * b64 = base64encode(data); - * data = base64decode(b64); - */ - -(function() { - -var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -var base64DecodeChars = [ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1]; - -function base64encode(str) { - var out, i, len; - var c1, c2, c3; - - len = str.length; - i = 0; - out = ""; - while(i < len) { - c1 = str.charCodeAt(i++) & 0xff; - if(i == len) - { - out += base64EncodeChars.charAt(c1 >> 2); - out += base64EncodeChars.charAt((c1 & 0x3) << 4); - out += "=="; - break; - } - c2 = str.charCodeAt(i++); - if(i == len) - { - out += base64EncodeChars.charAt(c1 >> 2); - out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); - out += base64EncodeChars.charAt((c2 & 0xF) << 2); - out += "="; - break; - } - c3 = str.charCodeAt(i++); - out += base64EncodeChars.charAt(c1 >> 2); - out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); - out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)); - out += base64EncodeChars.charAt(c3 & 0x3F); - } - return out; -} - -function base64decode(str) { - var c1, c2, c3, c4; - var i, len, out; - - len = str.length; - i = 0; - out = ""; - while(i < len) { - /* c1 */ - do { - c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; - } while(i < len && c1 == -1); - if(c1 == -1) - break; - - /* c2 */ - do { - c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff]; - } while(i < len && c2 == -1); - if(c2 == -1) - break; - - out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4)); - - /* c3 */ - do { - c3 = str.charCodeAt(i++) & 0xff; - if(c3 == 61) - return out; - c3 = base64DecodeChars[c3]; - } while(i < len && c3 == -1); - if(c3 == -1) - break; - - out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2)); - - /* c4 */ - do { - c4 = str.charCodeAt(i++) & 0xff; - if(c4 == 61) - return out; - c4 = base64DecodeChars[c4]; - } while(i < len && c4 == -1); - if(c4 == -1) - break; - out += String.fromCharCode(((c3 & 0x03) << 6) | c4); - } - return out; -} - -if (!window.btoa) window.btoa = base64encode; -if (!window.atob) window.atob = base64decode; - -})(); + --- a/js/flotr/lib/canvas2image.js +++ /dev/null @@ -1,230 +1,1 @@ -/* - * Canvas2Image v0.1 - * Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com - * MIT License [http://www.opensource.org/licenses/mit-license.php] - */ - -var Canvas2Image = (function() { - // check if we have canvas support - var oCanvas = document.createElement("canvas"); - - // no canvas, bail out. - if (!oCanvas.getContext) { - return { - saveAsBMP : function(){}, - saveAsPNG : function(){}, - saveAsJPEG : function(){} - } - } - - var bHasImageData = !!(oCanvas.getContext("2d").getImageData); - var bHasDataURL = !!(oCanvas.toDataURL); - var bHasBase64 = !!(window.btoa); - - var strDownloadMime = "image/octet-stream"; - - // ok, we're good - var readCanvasData = function(oCanvas) { - var iWidth = parseInt(oCanvas.width); - var iHeight = parseInt(oCanvas.height); - return oCanvas.getContext("2d").getImageData(0,0,iWidth,iHeight); - } - - // base64 encodes either a string or an array of charcodes - var encodeData = function(data) { - var strData = ""; - if (typeof data == "string") { - strData = data; - } else { - var aData = data; - for (var i = 0; i < aData.length; i++) { - strData += String.fromCharCode(aData[i]); - } - } - return btoa(strData); - } - - // creates a base64 encoded string containing BMP data - // takes an imagedata object as argument - var createBMP = function(oData) { - var aHeader = []; - - var iWidth = oData.width; - var iHeight = oData.height; - - aHeader.push(0x42); // magic 1 - aHeader.push(0x4D); - - var iFileSize = iWidth*iHeight*3 + 54; // total header size = 54 bytes - aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); - aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); - aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256); - aHeader.push(iFileSize % 256); - - aHeader.push(0); // reserved - aHeader.push(0); - aHeader.push(0); // reserved - aHeader.push(0); - - aHeader.push(54); // data offset - aHeader.push(0); - aHeader.push(0); - aHeader.push(0); - - var aInfoHeader = []; - aInfoHeader.push(40); // info header size - aInfoHeader.push(0); - aInfoHeader.push(0); - aInfoHeader.push(0); - - var iImageWidth = iWidth; - aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); - aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); - aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256); - aInfoHeader.push(iImageWidth % 256); - - var iImageHeight = iHeight; - aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); - aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); - aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256); - aInfoHeader.push(iImageHeight % 256); - - aInfoHeader.push(1); // num of planes - aInfoHeader.push(0); - - aInfoHeader.push(24); // num of bits per pixel - aInfoHeader.push(0); - - aInfoHeader.push(0); // compression = none - aInfoHeader.push(0); - aInfoHeader.push(0); - aInfoHeader.push(0); - - var iDataSize = iWidth*iHeight*3; - aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); - aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); - aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256); - aInfoHeader.push(iDataSize % 256); - - for (var i = 0; i < 16; i++) { - aInfoHeader.push(0); // these bytes not used - } - - var iPadding = (4 - ((iWidth * 3) % 4)) % 4; - - var aImgData = oData.data; - - var strPixelData = ""; - var y = iHeight; - do { - var iOffsetY = iWidth*(y-1)*4; - var strPixelRow = ""; - for (var x=0;x object containing the imagedata - var makeImageObject = function(strSource) { - var oImgElement = document.createElement("img"); - oImgElement.src = strSource; - return oImgElement; - } - - var scaleCanvas = function(oCanvas, iWidth, iHeight) { - if (iWidth && iHeight) { - var oSaveCanvas = document.createElement("canvas"); - - oSaveCanvas.width = iWidth; - oSaveCanvas.height = iHeight; - oSaveCanvas.style.width = iWidth+"px"; - oSaveCanvas.style.height = iHeight+"px"; - - var oSaveCtx = oSaveCanvas.getContext("2d"); - - oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, iWidth); - - return oSaveCanvas; - } - return oCanvas; - } - - return { - saveAsPNG : function(oCanvas, bReturnImg, iWidth, iHeight) { - if (!bHasDataURL) { - return false; - } - var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); - var strData = oScaledCanvas.toDataURL("image/png"); - if (bReturnImg) { - return makeImageObject(strData); - } else { - saveFile(strData.replace("image/png", strDownloadMime)); - } - return true; - }, - - saveAsJPEG : function(oCanvas, bReturnImg, iWidth, iHeight) { - if (!bHasDataURL) { - return false; - } - - var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); - var strMime = "image/jpeg"; - var strData = oScaledCanvas.toDataURL(strMime); - - // check if browser actually supports jpeg by looking for the mime type in the data uri. - // if not, return false - if (strData.indexOf(strMime) != 5) { - return false; - } - - if (bReturnImg) { - return makeImageObject(strData); - } else { - saveFile(strData.replace(strMime, strDownloadMime)); - } - return true; - }, - - saveAsBMP : function(oCanvas, bReturnImg, iWidth, iHeight) { - if (!(bHasImageData && bHasBase64)) { - return false; - } - - var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight); - - var oData = readCanvasData(oScaledCanvas); - var strImgData = createBMP(oData); - if (bReturnImg) { - return makeImageObject(makeDataURI(strImgData, "image/bmp")); - } else { - saveFile(makeDataURI(strImgData, strDownloadMime)); - } - return true; - } - }; - -})(); + --- a/js/flotr/lib/canvastext.js +++ /dev/null @@ -1,397 +1,1 @@ -/** - * This code is released to the public domain by Jim Studt, 2007. - * He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/ - * It as been modified by Fabien Ménager to handle font style like size, weight, color and rotation. - * A partial support for accentuated letters as been added too. - */ -var CanvasText = { - /** The letters definition. It is a list of letters, - * with their width, and the coordinates of points compositing them. - * The syntax for the points is : [x, y], null value means "pen up" - */ - letters: { - '\n':{ width: -1, points: [] }, - ' ': { width: 10, points: [] }, - '!': { width: 10, points: [[5,21],[5,7],null,[5,2],[4,1],[5,0],[6,1],[5,2]] }, - '"': { width: 16, points: [[4,21],[4,14],null,[12,21],[12,14]] }, - '#': { width: 21, points: [[11,25],[4,-7],null,[17,25],[10,-7],null,[4,12],[18,12],null,[3,6],[17,6]] }, - '$': { width: 20, points: [[8,25],[8,-4],null,[12,25],[12,-4],null,[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, - '%': { width: 24, points: [[21,21],[3,0],null,[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],null,[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] }, - '&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] }, - '\'':{ width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] }, - '(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] }, - ')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] }, - '*': { width: 16, points: [[8,21],[8,9],null,[3,18],[13,12],null,[13,18],[3,12]] }, - '+': { width: 26, points: [[13,18],[13,0],null,[4,9],[22,9]] }, - ',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, - '-': { width: 26, points: [[4,9],[22,9]] }, - '.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] }, - '/': { width: 22, points: [[20,25],[2,-7]] }, - '0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] }, - '1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] }, - '2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] }, - '3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, - '4': { width: 20, points: [[13,21],[3,7],[18,7],null,[13,21],[13,0]] }, - '5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, - '6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] }, - '7': { width: 20, points: [[17,21],[7,0],null,[3,21],[17,21]] }, - '8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] }, - '9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] }, - ':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],null,[5,2],[4,1],[5,0],[6,1],[5,2]] }, - ';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],null,[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, - '<': { width: 24, points: [[20,18],[4,9],[20,0]] }, - '=': { width: 26, points: [[4,12],[22,12],null,[4,6],[22,6]] }, - '>': { width: 24, points: [[4,18],[20,9],[4,0]] }, - '?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],null,[9,2],[8,1],[9,0],[10,1],[9,2]] }, - '@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],null,[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],null,[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],null,[19,16],[18,8],[18,6],[19,5]] }, - 'A': { width: 18, points: [[9,21],[1,0],null,[9,21],[17,0],null,[4,7],[14,7]] }, - 'B': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],null,[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] }, - 'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] }, - 'D': { width: 21, points: [[4,21],[4,0],null,[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] }, - 'E': { width: 19, points: [[4,21],[4,0],null,[4,21],[17,21],null,[4,11],[12,11],null,[4,0],[17,0]] }, - 'F': { width: 18, points: [[4,21],[4,0],null,[4,21],[17,21],null,[4,11],[12,11]] }, - 'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],null,[13,8],[18,8]] }, - 'H': { width: 22, points: [[4,21],[4,0],null,[18,21],[18,0],null,[4,11],[18,11]] }, - 'I': { width: 8, points: [[4,21],[4,0]] }, - 'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] }, - 'K': { width: 21, points: [[4,21],[4,0],null,[18,21],[4,7],null,[9,12],[18,0]] }, - 'L': { width: 17, points: [[4,21],[4,0],null,[4,0],[16,0]] }, - 'M': { width: 24, points: [[4,21],[4,0],null,[4,21],[12,0],null,[20,21],[12,0],null,[20,21],[20,0]] }, - 'N': { width: 22, points: [[4,21],[4,0],null,[4,21],[18,0],null,[18,21],[18,0]] }, - 'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] }, - 'P': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] }, - 'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],null,[12,4],[18,-2]] }, - 'R': { width: 21, points: [[4,21],[4,0],null,[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],null,[11,11],[18,0]] }, - 'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, - 'T': { width: 16, points: [[8,21],[8,0],null,[1,21],[15,21]] }, - 'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] }, - 'V': { width: 18, points: [[1,21],[9,0],null,[17,21],[9,0]] }, - 'W': { width: 24, points: [[2,21],[7,0],null,[12,21],[7,0],null,[12,21],[17,0],null,[22,21],[17,0]] }, - 'X': { width: 20, points: [[3,21],[17,0],null,[17,21],[3,0]] }, - 'Y': { width: 18, points: [[1,21],[9,11],[9,0],null,[17,21],[9,11]] }, - 'Z': { width: 20, points: [[17,21],[3,0],null,[3,21],[17,21],null,[3,0],[17,0]] }, - '[': { width: 14, points: [[4,25],[4,-7],null,[5,25],[5,-7],null,[4,25],[11,25],null,[4,-7],[11,-7]] }, - '\\':{ width: 14, points: [[0,21],[14,-3]] }, - ']': { width: 14, points: [[9,25],[9,-7],null,[10,25],[10,-7],null,[3,25],[10,25],null,[3,-7],[10,-7]] }, - '^': { width: 14, points: [[3,10],[8,18],[13,10]] }, - '_': { width: 16, points: [[0,-2],[16,-2]] }, - '`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] }, - 'a': { width: 19, points: [[15,14],[15,0],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'b': { width: 19, points: [[4,21],[4,0],null,[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, - 'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'd': { width: 19, points: [[15,21],[15,0],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],null,[2,14],[9,14]] }, - 'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'h': { width: 19, points: [[4,21],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, - 'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],null,[4,14],[4,0]] }, - 'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],null,[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] }, - 'k': { width: 17, points: [[4,21],[4,0],null,[14,14],[4,4],null,[8,8],[15,0]] }, - 'l': { width: 8, points: [[4,21],[4,0]] }, - 'm': { width: 30, points: [[4,14],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],null,[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] }, - 'n': { width: 19, points: [[4,14],[4,0],null,[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, - 'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] }, - 'p': { width: 19, points: [[4,14],[4,-7],null,[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, - 'q': { width: 19, points: [[15,14],[15,-7],null,[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, - 'r': { width: 13, points: [[4,14],[4,0],null,[4,8],[5,11],[7,13],[9,14],[12,14]] }, - 's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] }, - 't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],null,[2,14],[9,14]] }, - 'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],null,[15,14],[15,0]] }, - 'v': { width: 16, points: [[2,14],[8,0],null,[14,14],[8,0]] }, - 'w': { width: 22, points: [[3,14],[7,0],null,[11,14],[7,0],null,[11,14],[15,0],null,[19,14],[15,0]] }, - 'x': { width: 17, points: [[3,14],[14,0],null,[14,14],[3,0]] }, - 'y': { width: 16, points: [[2,14],[8,0],null,[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] }, - 'z': { width: 17, points: [[14,14],[3,0],null,[3,14],[14,14],null,[3,0],[14,0]] }, - '{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],null,[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],null,[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] }, - '|': { width: 8, points: [[4,25],[4,-7]] }, - '}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],null,[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],null,[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] }, - '~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],null,[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] }, - 'é': { diacritic: '´', letter: 'e' }, - 'è': { diacritic: '`', letter: 'e' }, - 'ê': { diacritic: '^', letter: 'e' }, - 'ë': { diacritic: '¨', letter: 'e' }, - 'à': { diacritic: '`', letter: 'a' }, - 'ç': { diacritic: '¸', letter: 'c' }, - 'ñ': { diacritic: '~', letter: 'n' }, - 'ô': { diacritic: '^', letter: 'o' }, - 'É': { diacritic: '´', letter: 'E' }, - 'È': { diacritic: '`', letter: 'E' }, - 'Ê': { diacritic: '^', letter: 'E' }, - 'Ë': { diacritic: '¨', letter: 'E' }, - 'À': { diacritic: '`', letter: 'A' }, - 'Ç': { diacritic: '¸', letter: 'C' }, - 'Ñ': { diacritic: '~', letter: 'N' }, - 'Ô': { diacritic: '^', letter: 'O' } - }, - - specialchars: { - 'pi': { width: 19, points: [[6,14],[6,0],null,[14,14],[14,0],null,[2,13],[6,16],[13,13],[17,16]] } - }, - - /** Diacritics, used to draw accentuated letters */ - diacritics: { - '¸': { entity: 'cedil', points: [[6,-4],[4,-6],[2,-7],[1,-7]] }, - '´': { entity: 'acute', points: [[8,19],[13,22]] }, - '`': { entity: 'grave', points: [[7,22],[12,19]] }, - '^': { entity: 'circ', points: [[5.5,19],[9.5,23],[12.5,19]] }, - '¨': { entity: 'trema', points: [[5,21],[6,20],[7,21],[6,22],[5,21],null,[12,21],[13,20],[14,21],[13,22],[12,21]] }, - '~': { entity: 'tilde', points: [[4,18],[7,22],[10,18],[13,22]] } - }, - - /** The default font styling */ - style: { - size: 8, // font height in pixels - font: null, // not yet implemented - color: '#000000', // - weight: 1, // float, 1 for 'normal' - halign: 'l', // l: left, r: right, c: center - valign: 'b', // t: top, m: middle, b: bottom - adjustAlign: false, // modifies the alignments if the angle is different from 0 to make the spin point always at the good position - angle: 0, // in radians, anticlockwise - tracking: 1, // space between the letters, float, 1 for 'normal' - boundingBoxColor: '#ff0000', //null // color of the bounding box (null to hide), can be used for debug and font drawing - originPointColor: '#000000' //null // color of the bounding box (null to hide), can be used for debug and font drawing - }, - - debug: false, - _bufferLexemes: {}, - - /** Get the letter data corresponding to a char - * @param {String} ch - The char - */ - letter: function(ch) { - return CanvasText.letters[ch]; - }, - - parseLexemes: function(str) { - if (CanvasText._bufferLexemes[str]) - return CanvasText._bufferLexemes[str]; - - var i, c, matches = str.match(/&[A-Za-z]{2,5};|\s|./g); - var result = [], chars = []; - for (i = 0; i < matches.length; i++) { - c = matches[i]; - if (c.length == 1) - chars.push(c); - else { - var entity = c.substring(1, c.length-1); - if (CanvasText.specialchars[entity]) - chars.push(entity); - else - chars = chars.concat(c.toArray()); - } - } - for (i = 0; i < chars.length; i++) { - c = chars[i]; - if (c = CanvasText.letters[c] || CanvasText.specialchars[c]) - result.push(c); - } - return CanvasText._bufferLexemes[str] = result.compact(); - }, - - /** Get the font ascent for a given style - * @param {Object} style - The reference style - */ - ascent: function(style) { - style = style || {}; - return (style.size || CanvasText.style.size); - }, - - /** Get the font descent for a given style - * @param {Object} style - The reference style - * */ - descent: function(style) { - style = style || {}; - return 7.0*(style.size || CanvasText.style.size)/25.0; - }, - - /** Measure the text horizontal size - * @param {String} str - The text - * @param {Object} style - Text style - * */ - measure: function(str, style) { - if (!str) return; - style = style || {}; - - var i, width, lexemes = CanvasText.parseLexemes(str), - total = 0; - - for (i = lexemes.length-1; i > -1; --i) { - c = lexemes[i]; - width = (c.diacritic) ? CanvasText.letter(c.letter).width : c.width; - total += width * (style.tracking || CanvasText.style.tracking) * (style.size || CanvasText.style.size) / 25.0; - } - return total; - }, - - getDimensions: function(str, style) { - var width = CanvasText.measure(str, style), - height = style.size || CanvasText.style.size, - angle = style.angle || CanvasText.style.angle; - - if (style.angle == 0) return {width: width, height: height}; - return { - width: Math.abs(Math.cos(angle) * width) + Math.abs(Math.sin(angle) * height), - height: Math.abs(Math.sin(angle) * width) + Math.abs(Math.cos(angle) * height) - } - }, - - getBestAlign: function(angle, style) { - angle += CanvasText.getAngleFromAlign(style.halign, style.valign); - var a = {h:'c', v:'m'}; - if (Math.round(Math.cos(angle)*1000)/1000 != 0) - a.h = (Math.cos(angle) > 0 ? 'r' : 'l'); - - if (Math.round(Math.sin(angle)*1000)/1000 != 0) - a.v = (Math.sin(angle) > 0 ? 't' : 'b'); - return a; - }, - - getAngleFromAlign: function(halign, valign) { - var pi = Math.PI, table = { - 'rm': 0, - 'rt': pi/4, - 'ct': pi/2, - 'lt': 3*(pi/4), - 'lm': pi, - 'lb': -3*(pi/4), - 'cb': -pi/2, - 'rb': -pi/4, - 'cm': 0 - } - return table[halign+valign]; - }, - - /** Draws serie of points at given coordinates - * @param {Canvas context} ctx - The canvas context - * @param {Array} points - The points to draw - * @param {Number} x - The X coordinate - * @param {Number} y - The Y coordinate - * @param {Number} mag - The scale - */ - drawPoints: function (ctx, points, x, y, mag, offset) { - var i, a, penUp = true, needStroke = 0; - offset = offset || {x:0, y:0}; - - ctx.beginPath(); - for (i = 0; i < points.length; i++) { - a = points[i]; - if (!a) { - penUp = true; - continue; - } - if (penUp) { - ctx.moveTo(x + a[0]*mag + offset.x, y - a[1]*mag + offset.y); - penUp = false; - } - else { - ctx.lineTo(x + a[0]*mag + offset.x, y - a[1]*mag + offset.y); - } - } - ctx.stroke(); - }, - - /** Draws a text at given coordinates and with a given style - * @param {Canvas context} ctx - The canvas context - * @param {String} str - The text to draw - * @param {Number} xOrig - The X coordinate - * @param {Number} yOrig - The Y coordinate - * @param {Object} style - The font style - */ - draw: function(ctx, str, xOrig, yOrig, style) { - if (!str) return; - style = style || CanvasText.style; - style.halign = style.halign || CanvasText.style.halign; - style.valign = style.valign || CanvasText.style.valign; - style.angle = style.angle || CanvasText.style.angle; - style.size = style.size || CanvasText.style.size; - style.adjustAlign = style.adjustAlign || CanvasText.style.adjustAlign; - - var i, c, total = 0, - mag = style.size / 25.0, - x = 0, y = 0, - lexemes = CanvasText.parseLexemes(str); - - var offset = {x:0, y:0}, - measure = CanvasText.measure(str, style), - align; - - if (style.adjustAlign) { - align = CanvasText.getBestAlign(style.angle, style); - style.halign = align.h; - style.valign = align.v; - } - - switch (style.halign) { - case 'l': break; - case 'c': offset.x = -measure / 2; break; - case 'r': offset.x = -measure; break; - } - - switch (style.valign) { - case 'b': break; - case 'm': offset.y = style.size / 2; break; - case 't': offset.y = style.size; break; - } - - ctx.save(); - ctx.translate(xOrig, yOrig); - ctx.rotate(style.angle); - ctx.lineCap = "round"; - ctx.lineWidth = 2.0 * mag * (style.weight || CanvasText.style.weight); - ctx.strokeStyle = style.color || CanvasText.style.color; - - for (i = 0; i < lexemes.length; i++) { - c = lexemes[i]; - if (c.width == -1) { - x = 0; - y = style.size * 1.4; - continue; - } - - var points = c.points, - width = c.width; - - if (c.diacritic) { - var dia = CanvasText.diacritics[c.diacritic]; - var char = CanvasText.letter(c.letter); - - CanvasText.drawPoints(ctx, dia.points, x, y - (c.letter.toUpperCase() == c.letter ? 3 : 0), mag, offset); - points = char.points; - width = char.width; - } - - CanvasText.drawPoints(ctx, points, x, y, mag, offset); - - if (CanvasText.debug) { - ctx.save(); - ctx.lineJoin = "miter"; - ctx.lineWidth = 0.5; - ctx.strokeStyle = (style.boundingBoxColor || CanvasText.style.boundingBoxColor); - ctx.strokeRect(x+offset.x, y+offset.y, width*mag, -style.size); - - ctx.fillStyle = (style.originPointColor || CanvasText.style.originPointColor); - ctx.beginPath(); - ctx.arc(0, 0, 1.5, 0, Math.PI*2, true); - ctx.fill(); - - ctx.restore(); - } - - x += width*mag*(style.tracking || CanvasText.style.tracking); - } - ctx.restore(); - return total; - }, - - /** Enables the text function for a Canvas context - * @param {Canvas context} ctx - The canvas context - */ - enable: function(ctx) { - ctx.drawText = function(text, x, y, style) { return CanvasText.draw(ctx, text, x, y, style); }; - ctx.measureText = function(text, style) { return CanvasText.measure(text, style); }; - ctx.getTextBounds = function(text, style) { return CanvasText.getDimensions(text, style); }; - ctx.fontAscent = function(style) { return CanvasText.ascent(style); }; - ctx.fontDescent = function(style) { return CanvasText.descent(style); }; - } -}; + --- a/js/flotr/lib/excanvas.js +++ /dev/null @@ -1,885 +1,1 @@ -// Copyright 2006 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Known Issues: -// -// * Patterns are not implemented. -// * Radial gradient are not implemented. The VML version of these look very -// different from the canvas one. -// * Clipping paths are not implemented. -// * Coordsize. The width and height attribute have higher priority than the -// width and height style values which isn't correct. -// * Painting mode isn't implemented. -// * Canvas width/height should is using content-box by default. IE in -// Quirks mode will draw the canvas using border-box. Either change your -// doctype to HTML5 -// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) -// or use Box Sizing Behavior from WebFX -// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) -// * Non uniform scaling does not correctly scale strokes. -// * Optimize. There is always room for speed improvements. - -// Only add this code if we do not already have a canvas implementation -if (!document.createElement('canvas').getContext) { - -(function() { - - // alias some functions to make (compiled) code shorter - var m = Math; - var mr = m.round; - var ms = m.sin; - var mc = m.cos; - var abs = m.abs; - var sqrt = m.sqrt; - - // this is used for sub pixel precision - var Z = 10; - var Z2 = Z / 2; - - /** - * This funtion is assigned to the elements as element.getContext(). - * @this {HTMLElement} - * @return {CanvasRenderingContext2D_} - */ - function getContext() { - return this.context_ || - (this.context_ = new CanvasRenderingContext2D_(this)); - } - - var slice = Array.prototype.slice; - - /** - * Binds a function to an object. The returned function will always use the - * passed in {@code obj} as {@code this}. - * - * Example: - * - * g = bind(f, obj, a, b) - * g(c, d) // will do f.call(obj, a, b, c, d) - * - * @param {Function} f The function to bind the object to - * @param {Object} obj The object that should act as this when the function - * is called - * @param {*} var_args Rest arguments that will be used as the initial - * arguments when the function is called - * @return {Function} A new function that has bound this - */ - function bind(f, obj, var_args) { - var a = slice.call(arguments, 2); - return function() { - return f.apply(obj, a.concat(slice.call(arguments))); - }; - } - - var G_vmlCanvasManager_ = { - init: function(opt_doc) { - if (/MSIE/.test(navigator.userAgent) && !window.opera) { - var doc = opt_doc || document; - // Create a dummy element so that IE will allow canvas elements to be - // recognized. - doc.createElement('canvas'); - doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); - } - }, - - init_: function(doc) { - // create xmlns - if (!doc.namespaces['g_vml_']) { - doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', - '#default#VML'); - - } - if (!doc.namespaces['g_o_']) { - doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', - '#default#VML'); - } - - // Setup default CSS. Only add one style sheet per document - if (!doc.styleSheets['ex_canvas_']) { - var ss = doc.createStyleSheet(); - ss.owningElement.id = 'ex_canvas_'; - ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + - // default size is 300x150 in Gecko and Opera - 'text-align:left;width:300px;height:150px}' + - 'g_vml_\\:*{behavior:url(#default#VML)}' + - 'g_o_\\:*{behavior:url(#default#VML)}'; - - } - - // find all canvas elements - var els = doc.getElementsByTagName('canvas'); - for (var i = 0; i < els.length; i++) { - this.initElement(els[i]); - } - }, - - /** - * Public initializes a canvas element so that it can be used as canvas - * element from now on. This is called automatically before the page is - * loaded but if you are creating elements using createElement you need to - * make sure this is called on the element. - * @param {HTMLElement} el The canvas element to initialize. - * @return {HTMLElement} the element that was created. - */ - initElement: function(el) { - if (!el.getContext) { - - el.getContext = getContext; - - // Remove fallback content. There is no way to hide text nodes so we - // just remove all childNodes. We could hide all elements and remove - // text nodes but who really cares about the fallback content. - el.innerHTML = ''; - - // do not use inline function because that will leak memory - el.attachEvent('onpropertychange', onPropertyChange); - el.attachEvent('onresize', onResize); - - var attrs = el.attributes; - if (attrs.width && attrs.width.specified) { - // TODO: use runtimeStyle and coordsize - // el.getContext().setWidth_(attrs.width.nodeValue); - el.style.width = attrs.width.nodeValue + 'px'; - } else { - el.width = el.clientWidth; - } - if (attrs.height && attrs.height.specified) { - // TODO: use runtimeStyle and coordsize - // el.getContext().setHeight_(attrs.height.nodeValue); - el.style.height = attrs.height.nodeValue + 'px'; - } else { - el.height = el.clientHeight; - } - //el.getContext().setCoordsize_() - } - return el; - } - }; - - function onPropertyChange(e) { - var el = e.srcElement; - - switch (e.propertyName) { - case 'width': - el.style.width = el.attributes.width.nodeValue + 'px'; - el.getContext().clearRect(); - break; - case 'height': - el.style.height = el.attributes.height.nodeValue + 'px'; - el.getContext().clearRect(); - break; - } - } - - function onResize(e) { - var el = e.srcElement; - if (el.firstChild) { - el.firstChild.style.width = el.clientWidth + 'px'; - el.firstChild.style.height = el.clientHeight + 'px'; - } - } - - G_vmlCanvasManager_.init(); - - // precompute "00" to "FF" - var dec2hex = []; - for (var i = 0; i < 16; i++) { - for (var j = 0; j < 16; j++) { - dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); - } - } - - function createMatrixIdentity() { - return [ - [1, 0, 0], - [0, 1, 0], - [0, 0, 1] - ]; - } - - function matrixMultiply(m1, m2) { - var result = createMatrixIdentity(); - - for (var x = 0; x < 3; x++) { - for (var y = 0; y < 3; y++) { - var sum = 0; - - for (var z = 0; z < 3; z++) { - sum += m1[x][z] * m2[z][y]; - } - - result[x][y] = sum; - } - } - return result; - } - - function copyState(o1, o2) { - o2.fillStyle = o1.fillStyle; - o2.lineCap = o1.lineCap; - o2.lineJoin = o1.lineJoin; - o2.lineWidth = o1.lineWidth; - o2.miterLimit = o1.miterLimit; - o2.shadowBlur = o1.shadowBlur; - o2.shadowColor = o1.shadowColor; - o2.shadowOffsetX = o1.shadowOffsetX; - o2.shadowOffsetY = o1.shadowOffsetY; - o2.strokeStyle = o1.strokeStyle; - o2.globalAlpha = o1.globalAlpha; - o2.arcScaleX_ = o1.arcScaleX_; - o2.arcScaleY_ = o1.arcScaleY_; - o2.lineScale_ = o1.lineScale_; - } - - function processStyle(styleString) { - var str, alpha = 1; - - styleString = String(styleString); - if (styleString.substring(0, 3) == 'rgb') { - var start = styleString.indexOf('(', 3); - var end = styleString.indexOf(')', start + 1); - var guts = styleString.substring(start + 1, end).split(','); - - str = '#'; - for (var i = 0; i < 3; i++) { - str += dec2hex[Number(guts[i])]; - } - - if (guts.length == 4 && styleString.substr(3, 1) == 'a') { - alpha = guts[3]; - } - } else { - str = styleString; - } - - return {color: str, alpha: alpha}; - } - - function processLineCap(lineCap) { - switch (lineCap) { - case 'butt': - return 'flat'; - case 'round': - return 'round'; - case 'square': - default: - return 'square'; - } - } - - /** - * This class implements CanvasRenderingContext2D interface as described by - * the WHATWG. - * @param {HTMLElement} surfaceElement The element that the 2D context should - * be associated with - */ - function CanvasRenderingContext2D_(surfaceElement) { - this.m_ = createMatrixIdentity(); - - this.mStack_ = []; - this.aStack_ = []; - this.currentPath_ = []; - - // Canvas context properties - this.strokeStyle = '#000'; - this.fillStyle = '#000'; - - this.lineWidth = 1; - this.lineJoin = 'miter'; - this.lineCap = 'butt'; - this.miterLimit = Z * 1; - this.globalAlpha = 1; - this.canvas = surfaceElement; - - var el = surfaceElement.ownerDocument.createElement('div'); - el.style.width = surfaceElement.clientWidth + 'px'; - el.style.height = surfaceElement.clientHeight + 'px'; - el.style.overflow = 'hidden'; - el.style.position = 'absolute'; - surfaceElement.appendChild(el); - - this.element_ = el; - this.arcScaleX_ = 1; - this.arcScaleY_ = 1; - this.lineScale_ = 1; - } - - var contextPrototype = CanvasRenderingContext2D_.prototype; - contextPrototype.clearRect = function() { - this.element_.innerHTML = ''; - }; - - contextPrototype.beginPath = function() { - // TODO: Branch current matrix so that save/restore has no effect - // as per safari docs. - this.currentPath_ = []; - }; - - contextPrototype.moveTo = function(aX, aY) { - var p = this.getCoords_(aX, aY); - this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); - this.currentX_ = p.x; - this.currentY_ = p.y; - }; - - contextPrototype.lineTo = function(aX, aY) { - var p = this.getCoords_(aX, aY); - this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); - - this.currentX_ = p.x; - this.currentY_ = p.y; - }; - - contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, - aCP2x, aCP2y, - aX, aY) { - var p = this.getCoords_(aX, aY); - var cp1 = this.getCoords_(aCP1x, aCP1y); - var cp2 = this.getCoords_(aCP2x, aCP2y); - bezierCurveTo(this, cp1, cp2, p); - }; - - // Helper function that takes the already fixed cordinates. - function bezierCurveTo(self, cp1, cp2, p) { - self.currentPath_.push({ - type: 'bezierCurveTo', - cp1x: cp1.x, - cp1y: cp1.y, - cp2x: cp2.x, - cp2y: cp2.y, - x: p.x, - y: p.y - }); - self.currentX_ = p.x; - self.currentY_ = p.y; - } - - contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { - // the following is lifted almost directly from - // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes - - var cp = this.getCoords_(aCPx, aCPy); - var p = this.getCoords_(aX, aY); - - var cp1 = { - x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), - y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) - }; - var cp2 = { - x: cp1.x + (p.x - this.currentX_) / 3.0, - y: cp1.y + (p.y - this.currentY_) / 3.0 - }; - - bezierCurveTo(this, cp1, cp2, p); - }; - - contextPrototype.arc = function(aX, aY, aRadius, - aStartAngle, aEndAngle, aClockwise) { - aRadius *= Z; - var arcType = aClockwise ? 'at' : 'wa'; - - var xStart = aX + mc(aStartAngle) * aRadius - Z2; - var yStart = aY + ms(aStartAngle) * aRadius - Z2; - - var xEnd = aX + mc(aEndAngle) * aRadius - Z2; - var yEnd = aY + ms(aEndAngle) * aRadius - Z2; - - // IE won't render arches drawn counter clockwise if xStart == xEnd. - if (xStart == xEnd && !aClockwise) { - xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something - // that can be represented in binary - } - - var p = this.getCoords_(aX, aY); - var pStart = this.getCoords_(xStart, yStart); - var pEnd = this.getCoords_(xEnd, yEnd); - - this.currentPath_.push({type: arcType, - x: p.x, - y: p.y, - radius: aRadius, - xStart: pStart.x, - yStart: pStart.y, - xEnd: pEnd.x, - yEnd: pEnd.y}); - - }; - - contextPrototype.rect = function(aX, aY, aWidth, aHeight) { - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - }; - - contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { - var oldPath = this.currentPath_; - this.beginPath(); - - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - this.stroke(); - - this.currentPath_ = oldPath; - }; - - contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { - var oldPath = this.currentPath_; - this.beginPath(); - - this.moveTo(aX, aY); - this.lineTo(aX + aWidth, aY); - this.lineTo(aX + aWidth, aY + aHeight); - this.lineTo(aX, aY + aHeight); - this.closePath(); - this.fill(); - - this.currentPath_ = oldPath; - }; - - contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { - var gradient = new CanvasGradient_('gradient'); - gradient.x0_ = aX0; - gradient.y0_ = aY0; - gradient.x1_ = aX1; - gradient.y1_ = aY1; - return gradient; - }; - - contextPrototype.createRadialGradient = function(aX0, aY0, aR0, - aX1, aY1, aR1) { - var gradient = new CanvasGradient_('gradientradial'); - gradient.x0_ = aX0; - gradient.y0_ = aY0; - gradient.r0_ = aR0; - gradient.x1_ = aX1; - gradient.y1_ = aY1; - gradient.r1_ = aR1; - return gradient; - }; - - contextPrototype.drawImage = function(image, var_args) { - var dx, dy, dw, dh, sx, sy, sw, sh; - - // to find the original width we overide the width and height - var oldRuntimeWidth = image.runtimeStyle.width; - var oldRuntimeHeight = image.runtimeStyle.height; - image.runtimeStyle.width = 'auto'; - image.runtimeStyle.height = 'auto'; - - // get the original size - var w = image.width; - var h = image.height; - - // and remove overides - image.runtimeStyle.width = oldRuntimeWidth; - image.runtimeStyle.height = oldRuntimeHeight; - - if (arguments.length == 3) { - dx = arguments[1]; - dy = arguments[2]; - sx = sy = 0; - sw = dw = w; - sh = dh = h; - } else if (arguments.length == 5) { - dx = arguments[1]; - dy = arguments[2]; - dw = arguments[3]; - dh = arguments[4]; - sx = sy = 0; - sw = w; - sh = h; - } else if (arguments.length == 9) { - sx = arguments[1]; - sy = arguments[2]; - sw = arguments[3]; - sh = arguments[4]; - dx = arguments[5]; - dy = arguments[6]; - dw = arguments[7]; - dh = arguments[8]; - } else { - throw Error('Invalid number of arguments'); - } - - var d = this.getCoords_(dx, dy); - - var w2 = sw / 2; - var h2 = sh / 2; - - var vmlStr = []; - - var W = 10; - var H = 10; - - // For some reason that I've now forgotten, using divs didn't work - vmlStr.push(' ' , - '', - ''); - - this.element_.insertAdjacentHTML('BeforeEnd', - vmlStr.join('')); - }; - - contextPrototype.stroke = function(aFill) { - var lineStr = []; - var lineOpen = false; - var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); - var color = a.color; - var opacity = a.alpha * this.globalAlpha; - - var W = 10; - var H = 10; - - lineStr.push(''); - - if (!aFill) { - var lineWidth = this.lineScale_ * this.lineWidth; - - // VML cannot correctly render a line if the width is less than 1px. - // In that case, we dilute the color to make the line look thinner. - if (lineWidth < 1) { - opacity *= lineWidth; - } - - lineStr.push( - '' - ); - } else if (typeof this.fillStyle == 'object') { - var fillStyle = this.fillStyle; - var angle = 0; - var focus = {x: 0, y: 0}; - - // additional offset - var shift = 0; - // scale factor for offset - var expansion = 1; - - if (fillStyle.type_ == 'gradient') { - var x0 = fillStyle.x0_ / this.arcScaleX_; - var y0 = fillStyle.y0_ / this.arcScaleY_; - var x1 = fillStyle.x1_ / this.arcScaleX_; - var y1 = fillStyle.y1_ / this.arcScaleY_; - var p0 = this.getCoords_(x0, y0); - var p1 = this.getCoords_(x1, y1); - var dx = p1.x - p0.x; - var dy = p1.y - p0.y; - angle = Math.atan2(dx, dy) * 180 / Math.PI; - - // The angle should be a non-negative number. - if (angle < 0) { - angle += 360; - } - - // Very small angles produce an unexpected result because they are - // converted to a scientific notation string. - if (angle < 1e-6) { - angle = 0; - } - } else { - var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_); - var width = max.x - min.x; - var height = max.y - min.y; - focus = { - x: (p0.x - min.x) / width, - y: (p0.y - min.y) / height - }; - - width /= this.arcScaleX_ * Z; - height /= this.arcScaleY_ * Z; - var dimension = m.max(width, height); - shift = 2 * fillStyle.r0_ / dimension; - expansion = 2 * fillStyle.r1_ / dimension - shift; - } - - // We need to sort the color stops in ascending order by offset, - // otherwise IE won't interpret it correctly. - var stops = fillStyle.colors_; - stops.sort(function(cs1, cs2) { - return cs1.offset - cs2.offset; - }); - - var length = stops.length; - var color1 = stops[0].color; - var color2 = stops[length - 1].color; - var opacity1 = stops[0].alpha * this.globalAlpha; - var opacity2 = stops[length - 1].alpha * this.globalAlpha; - - var colors = []; - for (var i = 0; i < length; i++) { - var stop = stops[i]; - colors.push(stop.offset * expansion + shift + ' ' + stop.color); - } - - // When colors attribute is used, the meanings of opacity and o:opacity2 - // are reversed. - lineStr.push(''); - } else { - lineStr.push(''); - } - - lineStr.push(''); - - this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); - }; - - contextPrototype.fill = function() { - this.stroke(true); - } - - contextPrototype.closePath = function() { - this.currentPath_.push({type: 'close'}); - }; - - /** - * @private - */ - contextPrototype.getCoords_ = function(aX, aY) { - var m = this.m_; - return { - x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, - y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 - } - }; - - contextPrototype.save = function() { - var o = {}; - copyState(this, o); - this.aStack_.push(o); - this.mStack_.push(this.m_); - this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); - }; - - contextPrototype.restore = function() { - copyState(this.aStack_.pop(), this); - this.m_ = this.mStack_.pop(); - }; - - contextPrototype.translate = function(aX, aY) { - var m1 = [ - [1, 0, 0], - [0, 1, 0], - [aX, aY, 1] - ]; - - this.m_ = matrixMultiply(m1, this.m_); - }; - - contextPrototype.rotate = function(aRot) { - var c = mc(aRot); - var s = ms(aRot); - - var m1 = [ - [c, s, 0], - [-s, c, 0], - [0, 0, 1] - ]; - - this.m_ = matrixMultiply(m1, this.m_); - }; - - contextPrototype.scale = function(aX, aY) { - this.arcScaleX_ *= aX; - this.arcScaleY_ *= aY; - var m1 = [ - [aX, 0, 0], - [0, aY, 0], - [0, 0, 1] - ]; - - var m = this.m_ = matrixMultiply(m1, this.m_); - - // Get the line scale. - // Determinant of this.m_ means how much the area is enlarged by the - // transformation. So its square root can be used as a scale factor - // for width. - var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; - this.lineScale_ = sqrt(abs(det)); - }; - - /******** STUBS ********/ - contextPrototype.clip = function() { - // TODO: Implement - }; - - contextPrototype.arcTo = function() { - // TODO: Implement - }; - - contextPrototype.createPattern = function() { - return new CanvasPattern_; - }; - - // Gradient / Pattern Stubs - function CanvasGradient_(aType) { - this.type_ = aType; - this.x0_ = 0; - this.y0_ = 0; - this.r0_ = 0; - this.x1_ = 0; - this.y1_ = 0; - this.r1_ = 0; - this.colors_ = []; - } - - CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { - aColor = processStyle(aColor); - this.colors_.push({offset: aOffset, - color: aColor.color, - alpha: aColor.alpha}); - }; - - function CanvasPattern_() {} - - // set up externs - G_vmlCanvasManager = G_vmlCanvasManager_; - CanvasRenderingContext2D = CanvasRenderingContext2D_; - CanvasGradient = CanvasGradient_; - CanvasPattern = CanvasPattern_; - -})(); - -} // if - --- a/js/flotr/lib/prototype-1.6.0.2.js +++ /dev/null @@ -1,4221 +1,1 @@ -/* Prototype JavaScript framework, version 1.6.0.2 - * (c) 2005-2008 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://www.prototypejs.org/ - * - *--------------------------------------------------------------------------*/ - -var Prototype = { - Version: '1.6.0.2', - - Browser: { - IE: !!(window.attachEvent && !window.opera), - Opera: !!window.opera, - WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, - Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, - MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) - }, - - BrowserFeatures: { - XPath: !!document.evaluate, - ElementExtensions: !!window.HTMLElement, - SpecificElementExtensions: - document.createElement('div').__proto__ && - document.createElement('div').__proto__ !== - document.createElement('form').__proto__ - }, - - ScriptFragment: ']*>([\\S\\s]*?)<\/script>', - JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, - - emptyFunction: function() { }, - K: function(x) { return x } -}; - -if (Prototype.Browser.MobileSafari) - Prototype.BrowserFeatures.SpecificElementExtensions = false; - - -/* Based on Alex Arnell's inheritance implementation. */ -var Class = { - create: function() { - var parent = null, properties = $A(arguments); - if (Object.isFunction(properties[0])) - parent = properties.shift(); - - function klass() { - this.initialize.apply(this, arguments); - } - - Object.extend(klass, Class.Methods); - klass.superclass = parent; - klass.subclasses = []; - - if (parent) { - var subclass = function() { }; - subclass.prototype = parent.prototype; - klass.prototype = new subclass; - parent.subclasses.push(klass); - } - - for (var i = 0; i < properties.length; i++) - klass.addMethods(properties[i]); - - if (!klass.prototype.initialize) - klass.prototype.initialize = Prototype.emptyFunction; - - klass.prototype.constructor = klass; - - return klass; - } -}; - -Class.Methods = { - addMethods: function(source) { - var ancestor = this.superclass && this.superclass.prototype; - var properties = Object.keys(source); - - if (!Object.keys({ toString: true }).length) - properties.push("toString", "valueOf"); - - for (var i = 0, length = properties.length; i < length; i++) { - var property = properties[i], value = source[property]; - if (ancestor && Object.isFunction(value) && - value.argumentNames().first() == "$super") { - var method = value, value = Object.extend((function(m) { - return function() { return ancestor[m].apply(this, arguments) }; - })(property).wrap(method), { - valueOf: function() { return method }, - toString: function() { return method.toString() } - }); - } - this.prototype[property] = value; - } - - return this; - } -}; - -var Abstract = { }; - -Object.extend = function(destination, source) { - for (var property in source) - destination[property] = source[property]; - return destination; -}; - -Object.extend(Object, { - inspect: function(object) { - try { - if (Object.isUndefined(object)) return 'undefined'; - if (object === null) return 'null'; - return object.inspect ? object.inspect() : String(object); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } - }, - - toJSON: function(object) { - var type = typeof object; - switch (type) { - case 'undefined': - case 'function': - case 'unknown': return; - case 'boolean': return object.toString(); - } - - if (object === null) return 'null'; - if (object.toJSON) return object.toJSON(); - if (Object.isElement(object)) return; - - var results = []; - for (var property in object) { - var value = Object.toJSON(object[property]); - if (!Object.isUndefined(value)) - results.push(property.toJSON() + ': ' + value); - } - - return '{' + results.join(', ') + '}'; - }, - - toQueryString: function(object) { - return $H(object).toQueryString(); - }, - - toHTML: function(object) { - return object && object.toHTML ? object.toHTML() : String.interpret(object); - }, - - keys: function(object) { - var keys = []; - for (var property in object) - keys.push(property); - return keys; - }, - - values: function(object) { - var values = []; - for (var property in object) - values.push(object[property]); - return values; - }, - - clone: function(object) { - return Object.extend({ }, object); - }, - - isElement: function(object) { - return object && object.nodeType == 1; - }, - - isArray: function(object) { - return object != null && typeof object == "object" && - 'splice' in object && 'join' in object; - }, - - isHash: function(object) { - return object instanceof Hash; - }, - - isFunction: function(object) { - return typeof object == "function"; - }, - - isString: function(object) { - return typeof object == "string"; - }, - - isNumber: function(object) { - return typeof object == "number"; - }, - - isUndefined: function(object) { - return typeof object == "undefined"; - } -}); - -Object.extend(Function.prototype, { - argumentNames: function() { - var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip"); - return names.length == 1 && !names[0] ? [] : names; - }, - - bind: function() { - if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; - var __method = this, args = $A(arguments), object = args.shift(); - return function() { - return __method.apply(object, args.concat($A(arguments))); - } - }, - - bindAsEventListener: function() { - var __method = this, args = $A(arguments), object = args.shift(); - return function(event) { - return __method.apply(object, [event || window.event].concat(args)); - } - }, - - curry: function() { - if (!arguments.length) return this; - var __method = this, args = $A(arguments); - return function() { - return __method.apply(this, args.concat($A(arguments))); - } - }, - - delay: function() { - var __method = this, args = $A(arguments), timeout = args.shift() * 1000; - return window.setTimeout(function() { - return __method.apply(__method, args); - }, timeout); - }, - - wrap: function(wrapper) { - var __method = this; - return function() { - return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); - } - }, - - methodize: function() { - if (this._methodized) return this._methodized; - var __method = this; - return this._methodized = function() { - return __method.apply(null, [this].concat($A(arguments))); - }; - } -}); - -Function.prototype.defer = Function.prototype.delay.curry(0.01); - -Date.prototype.toJSON = function() { - return '"' + this.getUTCFullYear() + '-' + - (this.getUTCMonth() + 1).toPaddedString(2) + '-' + - this.getUTCDate().toPaddedString(2) + 'T' + - this.getUTCHours().toPaddedString(2) + ':' + - this.getUTCMinutes().toPaddedString(2) + ':' + - this.getUTCSeconds().toPaddedString(2) + 'Z"'; -}; - -var Try = { - these: function() { - var returnValue; - - for (var i = 0, length = arguments.length; i < length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) { } - } - - return returnValue; - } -}; - -RegExp.prototype.match = RegExp.prototype.test; - -RegExp.escape = function(str) { - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); -}; - -/*--------------------------------------------------------------------------*/ - -var PeriodicalExecuter = Class.create({ - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - execute: function() { - this.callback(this); - }, - - stop: function() { - if (!this.timer) return; - clearInterval(this.timer); - this.timer = null; - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.execute(); - } finally { - this.currentlyExecuting = false; - } - } - } -}); -Object.extend(String, { - interpret: function(value) { - return value == null ? '' : String(value); - }, - specialChar: { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\\': '\\\\' - } -}); - -Object.extend(String.prototype, { - gsub: function(pattern, replacement) { - var result = '', source = this, match; - replacement = arguments.callee.prepareReplacement(replacement); - - while (source.length > 0) { - if (match = source.match(pattern)) { - result += source.slice(0, match.index); - result += String.interpret(replacement(match)); - source = source.slice(match.index + match[0].length); - } else { - result += source, source = ''; - } - } - return result; - }, - - sub: function(pattern, replacement, count) { - replacement = this.gsub.prepareReplacement(replacement); - count = Object.isUndefined(count) ? 1 : count; - - return this.gsub(pattern, function(match) { - if (--count < 0) return match[0]; - return replacement(match); - }); - }, - - scan: function(pattern, iterator) { - this.gsub(pattern, iterator); - return String(this); - }, - - truncate: function(length, truncation) { - length = length || 30; - truncation = Object.isUndefined(truncation) ? '...' : truncation; - return this.length > length ? - this.slice(0, length - truncation.length) + truncation : String(this); - }, - - strip: function() { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - }, - - stripTags: function() { - return this.replace(/<\/?[^>]+>/gi, ''); - }, - - stripScripts: function() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - }, - - extractScripts: function() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); - var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - }, - - evalScripts: function() { - return this.extractScripts().map(function(script) { return eval(script) }); - }, - - escapeHTML: function() { - var self = arguments.callee; - self.text.data = this; - return self.div.innerHTML; - }, - - unescapeHTML: function() { - var div = new Element('div'); - div.innerHTML = this.stripTags(); - return div.childNodes[0] ? (div.childNodes.length > 1 ? - $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : - div.childNodes[0].nodeValue) : ''; - }, - - toQueryParams: function(separator) { - var match = this.strip().match(/([^?#]*)(#.*)?$/); - if (!match) return { }; - - return match[1].split(separator || '&').inject({ }, function(hash, pair) { - if ((pair = pair.split('='))[0]) { - var key = decodeURIComponent(pair.shift()); - var value = pair.length > 1 ? pair.join('=') : pair[0]; - if (value != undefined) value = decodeURIComponent(value); - - if (key in hash) { - if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; - hash[key].push(value); - } - else hash[key] = value; - } - return hash; - }); - }, - - toArray: function() { - return this.split(''); - }, - - succ: function() { - return this.slice(0, this.length - 1) + - String.fromCharCode(this.charCodeAt(this.length - 1) + 1); - }, - - times: function(count) { - return count < 1 ? '' : new Array(count + 1).join(this); - }, - - camelize: function() { - var parts = this.split('-'), len = parts.length; - if (len == 1) return parts[0]; - - var camelized = this.charAt(0) == '-' - ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) - : parts[0]; - - for (var i = 1; i < len; i++) - camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); - - return camelized; - }, - - capitalize: function() { - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); - }, - - underscore: function() { - return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); - }, - - dasherize: function() { - return this.gsub(/_/,'-'); - }, - - inspect: function(useDoubleQuotes) { - var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { - var character = String.specialChar[match[0]]; - return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); - }); - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; - return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - }, - - toJSON: function() { - return this.inspect(true); - }, - - unfilterJSON: function(filter) { - return this.sub(filter || Prototype.JSONFilter, '#{1}'); - }, - - isJSON: function() { - var str = this; - if (str.blank()) return false; - str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); - return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); - }, - - evalJSON: function(sanitize) { - var json = this.unfilterJSON(); - try { - if (!sanitize || json.isJSON()) return eval('(' + json + ')'); - } catch (e) { } - throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); - }, - - include: function(pattern) { - return this.indexOf(pattern) > -1; - }, - - startsWith: function(pattern) { - return this.indexOf(pattern) === 0; - }, - - endsWith: function(pattern) { - var d = this.length - pattern.length; - return d >= 0 && this.lastIndexOf(pattern) === d; - }, - - empty: function() { - return this == ''; - }, - - blank: function() { - return /^\s*$/.test(this); - }, - - interpolate: function(object, pattern) { - return new Template(this, pattern).evaluate(object); - } -}); - -if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { - escapeHTML: function() { - return this.replace(/&/g,'&').replace(//g,'>'); - }, - unescapeHTML: function() { - return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); - } -}); - -String.prototype.gsub.prepareReplacement = function(replacement) { - if (Object.isFunction(replacement)) return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; -}; - -String.prototype.parseQuery = String.prototype.toQueryParams; - -Object.extend(String.prototype.escapeHTML, { - div: document.createElement('div'), - text: document.createTextNode('') -}); - -with (String.prototype.escapeHTML) div.appendChild(text); - -var Template = Class.create({ - initialize: function(template, pattern) { - this.template = template.toString(); - this.pattern = pattern || Template.Pattern; - }, - - evaluate: function(object) { - if (Object.isFunction(object.toTemplateReplacements)) - object = object.toTemplateReplacements(); - - return this.template.gsub(this.pattern, function(match) { - if (object == null) return ''; - - var before = match[1] || ''; - if (before == '\\') return match[2]; - - var ctx = object, expr = match[3]; - var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; - match = pattern.exec(expr); - if (match == null) return before; - - while (match != null) { - var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; - ctx = ctx[comp]; - if (null == ctx || '' == match[3]) break; - expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); - match = pattern.exec(expr); - } - - return before + String.interpret(ctx); - }); - } -}); -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; - -var $break = { }; - -var Enumerable = { - each: function(iterator, context) { - var index = 0; - iterator = iterator.bind(context); - try { - this._each(function(value) { - iterator(value, index++); - }); - } catch (e) { - if (e != $break) throw e; - } - return this; - }, - - eachSlice: function(number, iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var index = -number, slices = [], array = this.toArray(); - while ((index += number) < array.length) - slices.push(array.slice(index, index+number)); - return slices.collect(iterator, context); - }, - - all: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result = true; - this.each(function(value, index) { - result = result && !!iterator(value, index); - if (!result) throw $break; - }); - return result; - }, - - any: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result = false; - this.each(function(value, index) { - if (result = !!iterator(value, index)) - throw $break; - }); - return result; - }, - - collect: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var results = []; - this.each(function(value, index) { - results.push(iterator(value, index)); - }); - return results; - }, - - detect: function(iterator, context) { - iterator = iterator.bind(context); - var result; - this.each(function(value, index) { - if (iterator(value, index)) { - result = value; - throw $break; - } - }); - return result; - }, - - findAll: function(iterator, context) { - iterator = iterator.bind(context); - var results = []; - this.each(function(value, index) { - if (iterator(value, index)) - results.push(value); - }); - return results; - }, - - grep: function(filter, iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var results = []; - - if (Object.isString(filter)) - filter = new RegExp(filter); - - this.each(function(value, index) { - if (filter.match(value)) - results.push(iterator(value, index)); - }); - return results; - }, - - include: function(object) { - if (Object.isFunction(this.indexOf)) - if (this.indexOf(object) != -1) return true; - - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - }, - - inGroupsOf: function(number, fillWith) { - fillWith = Object.isUndefined(fillWith) ? null : fillWith; - return this.eachSlice(number, function(slice) { - while(slice.length < number) slice.push(fillWith); - return slice; - }); - }, - - inject: function(memo, iterator, context) { - iterator = iterator.bind(context); - this.each(function(value, index) { - memo = iterator(memo, value, index); - }); - return memo; - }, - - invoke: function(method) { - var args = $A(arguments).slice(1); - return this.map(function(value) { - return value[method].apply(value, args); - }); - }, - - max: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result; - this.each(function(value, index) { - value = iterator(value, index); - if (result == null || value >= result) - result = value; - }); - return result; - }, - - min: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var result; - this.each(function(value, index) { - value = iterator(value, index); - if (result == null || value < result) - result = value; - }); - return result; - }, - - partition: function(iterator, context) { - iterator = iterator ? iterator.bind(context) : Prototype.K; - var trues = [], falses = []; - this.each(function(value, index) { - (iterator(value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - }, - - pluck: function(property) { - var results = []; - this.each(function(value) { - results.push(value[property]); - }); - return results; - }, - - reject: function(iterator, context) { - iterator = iterator.bind(context); - var results = []; - this.each(function(value, index) { - if (!iterator(value, index)) - results.push(value); - }); - return results; - }, - - sortBy: function(iterator, context) { - iterator = iterator.bind(context); - return this.map(function(value, index) { - return {value: value, criteria: iterator(value, index)}; - }).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }).pluck('value'); - }, - - toArray: function() { - return this.map(); - }, - - zip: function() { - var iterator = Prototype.K, args = $A(arguments); - if (Object.isFunction(args.last())) - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - return iterator(collections.pluck(index)); - }); - }, - - size: function() { - return this.toArray().length; - }, - - inspect: function() { - return '#'; - } -}; - -Object.extend(Enumerable, { - map: Enumerable.collect, - find: Enumerable.detect, - select: Enumerable.findAll, - filter: Enumerable.findAll, - member: Enumerable.include, - entries: Enumerable.toArray, - every: Enumerable.all, - some: Enumerable.any -}); -function $A(iterable) { - if (!iterable) return []; - if (iterable.toArray) return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; -} - -if (Prototype.Browser.WebKit) { - $A = function(iterable) { - if (!iterable) return []; - if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && - iterable.toArray) return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; - }; -} - -Array.from = $A; - -Object.extend(Array.prototype, Enumerable); - -if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; - -Object.extend(Array.prototype, { - _each: function(iterator) { - for (var i = 0, length = this.length; i < length; i++) - iterator(this[i]); - }, - - clear: function() { - this.length = 0; - return this; - }, - - first: function() { - return this[0]; - }, - - last: function() { - return this[this.length - 1]; - }, - - compact: function() { - return this.select(function(value) { - return value != null; - }); - }, - - flatten: function() { - return this.inject([], function(array, value) { - return array.concat(Object.isArray(value) ? - value.flatten() : [value]); - }); - }, - - without: function() { - var values = $A(arguments); - return this.select(function(value) { - return !values.include(value); - }); - }, - - reverse: function(inline) { - return (inline !== false ? this : this.toArray())._reverse(); - }, - - reduce: function() { - return this.length > 1 ? this : this[0]; - }, - - uniq: function(sorted) { - return this.inject([], function(array, value, index) { - if (0 == index || (sorted ? array.last() != value : !array.include(value))) - array.push(value); - return array; - }); - }, - - intersect: function(array) { - return this.uniq().findAll(function(item) { - return array.detect(function(value) { return item === value }); - }); - }, - - clone: function() { - return [].concat(this); - }, - - size: function() { - return this.length; - }, - - inspect: function() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - }, - - toJSON: function() { - var results = []; - this.each(function(object) { - var value = Object.toJSON(object); - if (!Object.isUndefined(value)) results.push(value); - }); - return '[' + results.join(', ') + ']'; - } -}); - -// use native browser JS 1.6 implementation if available -if (Object.isFunction(Array.prototype.forEach)) - Array.prototype._each = Array.prototype.forEach; - -if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { - i || (i = 0); - var length = this.length; - if (i < 0) i = length + i; - for (; i < length; i++) - if (this[i] === item) return i; - return -1; -}; - -if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { - i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; - var n = this.slice(0, i).reverse().indexOf(item); - return (n < 0) ? n : i - n - 1; -}; - -Array.prototype.toArray = Array.prototype.clone; - -function $w(string) { - if (!Object.isString(string)) return []; - string = string.strip(); - return string ? string.split(/\s+/) : []; -} - -if (Prototype.Browser.Opera){ - Array.prototype.concat = function() { - var array = []; - for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); - for (var i = 0, length = arguments.length; i < length; i++) { - if (Object.isArray(arguments[i])) { - for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) - array.push(arguments[i][j]); - } else { - array.push(arguments[i]); - } - } - return array; - }; -} -Object.extend(Number.prototype, { - toColorPart: function() { - return this.toPaddedString(2, 16); - }, - - succ: function() { - return this + 1; - }, - - times: function(iterator) { - $R(0, this, true).each(iterator); - return this; - }, - - toPaddedString: function(length, radix) { - var string = this.toString(radix || 10); - return '0'.times(length - string.length) + string; - }, - - toJSON: function() { - return isFinite(this) ? this.toString() : 'null'; - } -}); - -$w('abs round ceil floor').each(function(method){ - Number.prototype[method] = Math[method].methodize(); -}); -function $H(object) { - return new Hash(object); -}; - -var Hash = Class.create(Enumerable, (function() { - - function toQueryPair(key, value) { - if (Object.isUndefined(value)) return key; - return key + '=' + encodeURIComponent(String.interpret(value)); - } - - return { - initialize: function(object) { - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); - }, - - _each: function(iterator) { - for (var key in this._object) { - var value = this._object[key], pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - }, - - set: function(key, value) { - return this._object[key] = value; - }, - - get: function(key) { - return this._object[key]; - }, - - unset: function(key) { - var value = this._object[key]; - delete this._object[key]; - return value; - }, - - toObject: function() { - return Object.clone(this._object); - }, - - keys: function() { - return this.pluck('key'); - }, - - values: function() { - return this.pluck('value'); - }, - - index: function(value) { - var match = this.detect(function(pair) { - return pair.value === value; - }); - return match && match.key; - }, - - merge: function(object) { - return this.clone().update(object); - }, - - update: function(object) { - return new Hash(object).inject(this, function(result, pair) { - result.set(pair.key, pair.value); - return result; - }); - }, - - toQueryString: function() { - return this.map(function(pair) { - var key = encodeURIComponent(pair.key), values = pair.value; - - if (values && typeof values == 'object') { - if (Object.isArray(values)) - return values.map(toQueryPair.curry(key)).join('&'); - } - return toQueryPair(key, values); - }).join('&'); - }, - - inspect: function() { - return '#'; - }, - - toJSON: function() { - return Object.toJSON(this.toObject()); - }, - - clone: function() { - return new Hash(this); - } - } -})()); - -Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; -Hash.from = $H; -var ObjectRange = Class.create(Enumerable, { - initialize: function(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - }, - - _each: function(iterator) { - var value = this.start; - while (this.include(value)) { - iterator(value); - value = value.succ(); - } - }, - - include: function(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } -}); - -var $R = function(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -}; - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new XMLHttpRequest()}, - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')} - ) || false; - }, - - activeRequestCount: 0 -}; - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responder) { - if (!this.include(responder)) - this.responders.push(responder); - }, - - unregister: function(responder) { - this.responders = this.responders.without(responder); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (Object.isFunction(responder[callback])) { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) { } - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { Ajax.activeRequestCount++ }, - onComplete: function() { Ajax.activeRequestCount-- } -}); - -Ajax.Base = Class.create({ - initialize: function(options) { - this.options = { - method: 'post', - asynchronous: true, - contentType: 'application/x-www-form-urlencoded', - encoding: 'UTF-8', - parameters: '', - evalJSON: true, - evalJS: true - }; - Object.extend(this.options, options || { }); - - this.options.method = this.options.method.toLowerCase(); - - if (Object.isString(this.options.parameters)) - this.options.parameters = this.options.parameters.toQueryParams(); - else if (Object.isHash(this.options.parameters)) - this.options.parameters = this.options.parameters.toObject(); - } -}); - -Ajax.Request = Class.create(Ajax.Base, { - _complete: false, - - initialize: function($super, url, options) { - $super(options); - this.transport = Ajax.getTransport(); - this.request(url); - }, - - request: function(url) { - this.url = url; - this.method = this.options.method; - var params = Object.clone(this.options.parameters); - - if (!['get', 'post'].include(this.method)) { - // simulate other verbs over post - params['_method'] = this.method; - this.method = 'post'; - } - - this.parameters = params; - - if (params = Object.toQueryString(params)) { - // when GET, append parameters to URL - if (this.method == 'get') - this.url += (this.url.include('?') ? '&' : '?') + params; - else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) - params += '&_='; - } - - try { - var response = new Ajax.Response(this); - if (this.options.onCreate) this.options.onCreate(response); - Ajax.Responders.dispatch('onCreate', this, response); - - this.transport.open(this.method.toUpperCase(), this.url, - this.options.asynchronous); - - if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); - - this.transport.onreadystatechange = this.onStateChange.bind(this); - this.setRequestHeaders(); - - this.body = this.method == 'post' ? (this.options.postBody || params) : null; - this.transport.send(this.body); - - /* Force Firefox to handle ready state 4 for synchronous requests */ - if (!this.options.asynchronous && this.transport.overrideMimeType) - this.onStateChange(); - - } - catch (e) { - this.dispatchException(e); - } - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState > 1 && !((readyState == 4) && this._complete)) - this.respondToReadyState(this.transport.readyState); - }, - - setRequestHeaders: function() { - var headers = { - 'X-Requested-With': 'XMLHttpRequest', - 'X-Prototype-Version': Prototype.Version, - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' - }; - - if (this.method == 'post') { - headers['Content-type'] = this.options.contentType + - (this.options.encoding ? '; charset=' + this.options.encoding : ''); - - /* Force "Connection: close" for older Mozilla browsers to work - * around a bug where XMLHttpRequest sends an incorrect - * Content-length header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType && - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) - headers['Connection'] = 'close'; - } - - // user-defined headers - if (typeof this.options.requestHeaders == 'object') { - var extras = this.options.requestHeaders; - - if (Object.isFunction(extras.push)) - for (var i = 0, length = extras.length; i < length; i += 2) - headers[extras[i]] = extras[i+1]; - else - $H(extras).each(function(pair) { headers[pair.key] = pair.value }); - } - - for (var name in headers) - this.transport.setRequestHeader(name, headers[name]); - }, - - success: function() { - var status = this.getStatus(); - return !status || (status >= 200 && status < 300); - }, - - getStatus: function() { - try { - return this.transport.status || 0; - } catch (e) { return 0 } - }, - - respondToReadyState: function(readyState) { - var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); - - if (state == 'Complete') { - try { - this._complete = true; - (this.options['on' + response.status] - || this.options['on' + (this.success() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - var contentType = response.getHeader('Content-type'); - if (this.options.evalJS == 'force' - || (this.options.evalJS && this.isSameOrigin() && contentType - && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) - this.evalResponse(); - } - - try { - (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); - Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - if (state == 'Complete') { - // avoid memory leak in MSIE: clean up - this.transport.onreadystatechange = Prototype.emptyFunction; - } - }, - - isSameOrigin: function() { - var m = this.url.match(/^\s*https?:\/\/[^\/]*/); - return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ - protocol: location.protocol, - domain: document.domain, - port: location.port ? ':' + location.port : '' - })); - }, - - getHeader: function(name) { - try { - return this.transport.getResponseHeader(name) || null; - } catch (e) { return null } - }, - - evalResponse: function() { - try { - return eval((this.transport.responseText || '').unfilterJSON()); - } catch (e) { - this.dispatchException(e); - } - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - -Ajax.Response = Class.create({ - initialize: function(request){ - this.request = request; - var transport = this.transport = request.transport, - readyState = this.readyState = transport.readyState; - - if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { - this.status = this.getStatus(); - this.statusText = this.getStatusText(); - this.responseText = String.interpret(transport.responseText); - this.headerJSON = this._getHeaderJSON(); - } - - if(readyState == 4) { - var xml = transport.responseXML; - this.responseXML = Object.isUndefined(xml) ? null : xml; - this.responseJSON = this._getResponseJSON(); - } - }, - - status: 0, - statusText: '', - - getStatus: Ajax.Request.prototype.getStatus, - - getStatusText: function() { - try { - return this.transport.statusText || ''; - } catch (e) { return '' } - }, - - getHeader: Ajax.Request.prototype.getHeader, - - getAllHeaders: function() { - try { - return this.getAllResponseHeaders(); - } catch (e) { return null } - }, - - getResponseHeader: function(name) { - return this.transport.getResponseHeader(name); - }, - - getAllResponseHeaders: function() { - return this.transport.getAllResponseHeaders(); - }, - - _getHeaderJSON: function() { - var json = this.getHeader('X-JSON'); - if (!json) return null; - json = decodeURIComponent(escape(json)); - try { - return json.evalJSON(this.request.options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - }, - - _getResponseJSON: function() { - var options = this.request.options; - if (!options.evalJSON || (options.evalJSON != 'force' && - !(this.getHeader('Content-type') || '').include('application/json')) || - this.responseText.blank()) - return null; - try { - return this.responseText.evalJSON(options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - } -}); - -Ajax.Updater = Class.create(Ajax.Request, { - initialize: function($super, container, url, options) { - this.container = { - success: (container.success || container), - failure: (container.failure || (container.success ? null : container)) - }; - - options = Object.clone(options); - var onComplete = options.onComplete; - options.onComplete = (function(response, json) { - this.updateContent(response.responseText); - if (Object.isFunction(onComplete)) onComplete(response, json); - }).bind(this); - - $super(url, options); - }, - - updateContent: function(responseText) { - var receiver = this.container[this.success() ? 'success' : 'failure'], - options = this.options; - - if (!options.evalScripts) responseText = responseText.stripScripts(); - - if (receiver = $(receiver)) { - if (options.insertion) { - if (Object.isString(options.insertion)) { - var insertion = { }; insertion[options.insertion] = responseText; - receiver.insert(insertion); - } - else options.insertion(receiver, responseText); - } - else receiver.update(responseText); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { - initialize: function($super, container, url, options) { - $super(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = { }; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.options.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(response) { - if (this.options.decay) { - this.decay = (response.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = response.responseText; - } - this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); -function $(element) { - if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) - elements.push($(arguments[i])); - return elements; - } - if (Object.isString(element)) - element = document.getElementById(element); - return Element.extend(element); -} - -if (Prototype.BrowserFeatures.XPath) { - document._getElementsByXPath = function(expression, parentElement) { - var results = []; - var query = document.evaluate(expression, $(parentElement) || document, - null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - for (var i = 0, length = query.snapshotLength; i < length; i++) - results.push(Element.extend(query.snapshotItem(i))); - return results; - }; -} - -/*--------------------------------------------------------------------------*/ - -if (!window.Node) var Node = { }; - -if (!Node.ELEMENT_NODE) { - // DOM level 2 ECMAScript Language Binding - Object.extend(Node, { - ELEMENT_NODE: 1, - ATTRIBUTE_NODE: 2, - TEXT_NODE: 3, - CDATA_SECTION_NODE: 4, - ENTITY_REFERENCE_NODE: 5, - ENTITY_NODE: 6, - PROCESSING_INSTRUCTION_NODE: 7, - COMMENT_NODE: 8, - DOCUMENT_NODE: 9, - DOCUMENT_TYPE_NODE: 10, - DOCUMENT_FRAGMENT_NODE: 11, - NOTATION_NODE: 12 - }); -} - -(function() { - var element = this.Element; - this.Element = function(tagName, attributes) { - attributes = attributes || { }; - tagName = tagName.toLowerCase(); - var cache = Element.cache; - if (Prototype.Browser.IE && attributes.name) { - tagName = '<' + tagName + ' name="' + attributes.name + '">'; - delete attributes.name; - return Element.writeAttribute(document.createElement(tagName), attributes); - } - if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); - return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); - }; - Object.extend(this.Element, element || { }); -}).call(window); - -Element.cache = { }; - -Element.Methods = { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function(element) { - element = $(element); - Element[Element.visible(element) ? 'hide' : 'show'](element); - return element; - }, - - hide: function(element) { - $(element).style.display = 'none'; - return element; - }, - - show: function(element) { - $(element).style.display = ''; - return element; - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - return element; - }, - - update: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) return element.update().insert(content); - content = Object.toHTML(content); - element.innerHTML = content.stripScripts(); - content.evalScripts.bind(content).defer(); - return element; - }, - - replace: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - else if (!Object.isElement(content)) { - content = Object.toHTML(content); - var range = element.ownerDocument.createRange(); - range.selectNode(element); - content.evalScripts.bind(content).defer(); - content = range.createContextualFragment(content.stripScripts()); - } - element.parentNode.replaceChild(content, element); - return element; - }, - - insert: function(element, insertions) { - element = $(element); - - if (Object.isString(insertions) || Object.isNumber(insertions) || - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) - insertions = {bottom:insertions}; - - var content, insert, tagName, childNodes; - - for (var position in insertions) { - content = insertions[position]; - position = position.toLowerCase(); - insert = Element._insertionTranslations[position]; - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - insert(element, content); - continue; - } - - content = Object.toHTML(content); - - tagName = ((position == 'before' || position == 'after') - ? element.parentNode : element).tagName.toUpperCase(); - - childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - - if (position == 'top' || position == 'after') childNodes.reverse(); - childNodes.each(insert.curry(element)); - - content.evalScripts.bind(content).defer(); - } - - return element; - }, - - wrap: function(element, wrapper, attributes) { - element = $(element); - if (Object.isElement(wrapper)) - $(wrapper).writeAttribute(attributes || { }); - else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); - else wrapper = new Element('div', wrapper); - if (element.parentNode) - element.parentNode.replaceChild(wrapper, element); - wrapper.appendChild(element); - return wrapper; - }, - - inspect: function(element) { - element = $(element); - var result = '<' + element.tagName.toLowerCase(); - $H({'id': 'id', 'className': 'class'}).each(function(pair) { - var property = pair.first(), attribute = pair.last(); - var value = (element[property] || '').toString(); - if (value) result += ' ' + attribute + '=' + value.inspect(true); - }); - return result + '>'; - }, - - recursivelyCollect: function(element, property) { - element = $(element); - var elements = []; - while (element = element[property]) - if (element.nodeType == 1) - elements.push(Element.extend(element)); - return elements; - }, - - ancestors: function(element) { - return $(element).recursivelyCollect('parentNode'); - }, - - descendants: function(element) { - return $(element).select("*"); - }, - - firstDescendant: function(element) { - element = $(element).firstChild; - while (element && element.nodeType != 1) element = element.nextSibling; - return $(element); - }, - - immediateDescendants: function(element) { - if (!(element = $(element).firstChild)) return []; - while (element && element.nodeType != 1) element = element.nextSibling; - if (element) return [element].concat($(element).nextSiblings()); - return []; - }, - - previousSiblings: function(element) { - return $(element).recursivelyCollect('previousSibling'); - }, - - nextSiblings: function(element) { - return $(element).recursivelyCollect('nextSibling'); - }, - - siblings: function(element) { - element = $(element); - return element.previousSiblings().reverse().concat(element.nextSiblings()); - }, - - match: function(element, selector) { - if (Object.isString(selector)) - selector = new Selector(selector); - return selector.match($(element)); - }, - - up: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(element.parentNode); - var ancestors = element.ancestors(); - return Object.isNumber(expression) ? ancestors[expression] : - Selector.findElement(ancestors, expression, index); - }, - - down: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return element.firstDescendant(); - return Object.isNumber(expression) ? element.descendants()[expression] : - element.select(expression)[index || 0]; - }, - - previous: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element)); - var previousSiblings = element.previousSiblings(); - return Object.isNumber(expression) ? previousSiblings[expression] : - Selector.findElement(previousSiblings, expression, index); - }, - - next: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element)); - var nextSiblings = element.nextSiblings(); - return Object.isNumber(expression) ? nextSiblings[expression] : - Selector.findElement(nextSiblings, expression, index); - }, - - select: function() { - var args = $A(arguments), element = $(args.shift()); - return Selector.findChildElements(element, args); - }, - - adjacent: function() { - var args = $A(arguments), element = $(args.shift()); - return Selector.findChildElements(element.parentNode, args).without(element); - }, - - identify: function(element) { - element = $(element); - var id = element.readAttribute('id'), self = arguments.callee; - if (id) return id; - do { id = 'anonymous_element_' + self.counter++ } while ($(id)); - element.writeAttribute('id', id); - return id; - }, - - readAttribute: function(element, name) { - element = $(element); - if (Prototype.Browser.IE) { - var t = Element._attributeTranslations.read; - if (t.values[name]) return t.values[name](element, name); - if (t.names[name]) name = t.names[name]; - if (name.include(':')) { - return (!element.attributes || !element.attributes[name]) ? null : - element.attributes[name].value; - } - } - return element.getAttribute(name); - }, - - writeAttribute: function(element, name, value) { - element = $(element); - var attributes = { }, t = Element._attributeTranslations.write; - - if (typeof name == 'object') attributes = name; - else attributes[name] = Object.isUndefined(value) ? true : value; - - for (var attr in attributes) { - name = t.names[attr] || attr; - value = attributes[attr]; - if (t.values[attr]) name = t.values[attr](element, value); - if (value === false || value === null) - element.removeAttribute(name); - else if (value === true) - element.setAttribute(name, name); - else element.setAttribute(name, value); - } - return element; - }, - - getHeight: function(element) { - return $(element).getDimensions().height; - }, - - getWidth: function(element) { - return $(element).getDimensions().width; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - var elementClassName = element.className; - return (elementClassName.length > 0 && (elementClassName == className || - new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - if (!element.hasClassName(className)) - element.className += (element.className ? ' ' : '') + className; - return element; - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - element.className = element.className.replace( - new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); - return element; - }, - - toggleClassName: function(element, className) { - if (!(element = $(element))) return; - return element[element.hasClassName(className) ? - 'removeClassName' : 'addClassName'](className); - }, - - // removes whitespace-only text node children - cleanWhitespace: function(element) { - element = $(element); - var node = element.firstChild; - while (node) { - var nextNode = node.nextSibling; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - element.removeChild(node); - node = nextNode; - } - return element; - }, - - empty: function(element) { - return $(element).innerHTML.blank(); - }, - - descendantOf: function(element, ancestor) { - element = $(element), ancestor = $(ancestor); - var originalAncestor = ancestor; - - if (element.compareDocumentPosition) - return (element.compareDocumentPosition(ancestor) & 8) === 8; - - if (element.sourceIndex && !Prototype.Browser.Opera) { - var e = element.sourceIndex, a = ancestor.sourceIndex, - nextAncestor = ancestor.nextSibling; - if (!nextAncestor) { - do { ancestor = ancestor.parentNode; } - while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode); - } - if (nextAncestor && nextAncestor.sourceIndex) - return (e > a && e < nextAncestor.sourceIndex); - } - - while (element = element.parentNode) - if (element == originalAncestor) return true; - return false; - }, - - scrollTo: function(element) { - element = $(element); - var pos = element.cumulativeOffset(); - window.scrollTo(pos[0], pos[1]); - return element; - }, - - getStyle: function(element, style) { - element = $(element); - style = style == 'float' ? 'cssFloat' : style.camelize(); - var value = element.style[style]; - if (!value) { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css[style] : null; - } - if (style == 'opacity') return value ? parseFloat(value) : 1.0; - return value == 'auto' ? null : value; - }, - - getOpacity: function(element) { - return $(element).getStyle('opacity'); - }, - - setStyle: function(element, styles) { - element = $(element); - var elementStyle = element.style, match; - if (Object.isString(styles)) { - element.style.cssText += ';' + styles; - return styles.include('opacity') ? - element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; - } - for (var property in styles) - if (property == 'opacity') element.setOpacity(styles[property]); - else - elementStyle[(property == 'float' || property == 'cssFloat') ? - (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : - property] = styles[property]; - - return element; - }, - - setOpacity: function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - return element; - }, - - getDimensions: function(element) { - element = $(element); - var display = $(element).getStyle('display'); - if (display != 'none' && display != null) // Safari bug - return {width: element.offsetWidth, height: element.offsetHeight}; - - // All *Width and *Height properties give 0 on elements with display none, - // so enable the element temporarily - var els = element.style; - var originalVisibility = els.visibility; - var originalPosition = els.position; - var originalDisplay = els.display; - els.visibility = 'hidden'; - els.position = 'absolute'; - els.display = 'block'; - var originalWidth = element.clientWidth; - var originalHeight = element.clientHeight; - els.display = originalDisplay; - els.position = originalPosition; - els.visibility = originalVisibility; - return {width: originalWidth, height: originalHeight}; - }, - - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - // Opera returns the offset relative to the positioning context, when an - // element is position relative but top and left have not been defined - if (window.opera) { - element.style.top = 0; - element.style.left = 0; - } - } - return element; - }, - - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - return element; - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return element; - element._overflow = Element.getStyle(element, 'overflow') || 'auto'; - if (element._overflow !== 'hidden') - element.style.overflow = 'hidden'; - return element; - }, - - undoClipping: function(element) { - element = $(element); - if (!element._overflow) return element; - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; - element._overflow = null; - return element; - }, - - cumulativeOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - positionedOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - if (element.tagName == 'BODY') break; - var p = Element.getStyle(element, 'position'); - if (p !== 'static') break; - } - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - absolutize: function(element) { - element = $(element); - if (element.getStyle('position') == 'absolute') return; - // Position.prepare(); // To be done manually by Scripty when it needs it. - - var offsets = element.positionedOffset(); - var top = offsets[1]; - var left = offsets[0]; - var width = element.clientWidth; - var height = element.clientHeight; - - element._originalLeft = left - parseFloat(element.style.left || 0); - element._originalTop = top - parseFloat(element.style.top || 0); - element._originalWidth = element.style.width; - element._originalHeight = element.style.height; - - element.style.position = 'absolute'; - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.width = width + 'px'; - element.style.height = height + 'px'; - return element; - }, - - relativize: function(element) { - element = $(element); - if (element.getStyle('position') == 'relative') return; - // Position.prepare(); // To be done manually by Scripty when it needs it. - - element.style.position = 'relative'; - var top = parseFloat(element.style.top || 0) - (element._originalTop || 0); - var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0); - - element.style.top = top + 'px'; - element.style.left = left + 'px'; - element.style.height = element._originalHeight; - element.style.width = element._originalWidth; - return element; - }, - - cumulativeScrollOffset: function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return Element._returnOffset(valueL, valueT); - }, - - getOffsetParent: function(element) { - if (element.offsetParent) return $(element.offsetParent); - if (element == document.body) return $(element); - - while ((element = element.parentNode) && element != document.body) - if (Element.getStyle(element, 'position') != 'static') - return $(element); - - return $(document.body); - }, - - viewportOffset: function(forElement) { - var valueT = 0, valueL = 0; - - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - - // Safari fix - if (element.offsetParent == document.body && - Element.getStyle(element, 'position') == 'absolute') break; - - } while (element = element.offsetParent); - - element = forElement; - do { - if (!Prototype.Browser.Opera || element.tagName == 'BODY') { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } - } while (element = element.parentNode); - - return Element._returnOffset(valueL, valueT); - }, - - clonePosition: function(element, source) { - var options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, arguments[2] || { }); - - // find page position of source - source = $(source); - var p = source.viewportOffset(); - - // find coordinate system to use - element = $(element); - var delta = [0, 0]; - var parent = null; - // delta [0,0] will do fine with position: fixed elements, - // position:absolute needs offsetParent deltas - if (Element.getStyle(element, 'position') == 'absolute') { - parent = element.getOffsetParent(); - delta = parent.viewportOffset(); - } - - // correct by body offsets (fixes Safari) - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } - - // set position - if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if (options.setWidth) element.style.width = source.offsetWidth + 'px'; - if (options.setHeight) element.style.height = source.offsetHeight + 'px'; - return element; - } -}; - -Element.Methods.identify.counter = 1; - -Object.extend(Element.Methods, { - getElementsBySelector: Element.Methods.select, - childElements: Element.Methods.immediateDescendants -}); - -Element._attributeTranslations = { - write: { - names: { - className: 'class', - htmlFor: 'for' - }, - values: { } - } -}; - -if (Prototype.Browser.Opera) { - Element.Methods.getStyle = Element.Methods.getStyle.wrap( - function(proceed, element, style) { - switch (style) { - case 'left': case 'top': case 'right': case 'bottom': - if (proceed(element, 'position') === 'static') return null; - case 'height': case 'width': - // returns '0px' for hidden elements; we want it to return null - if (!Element.visible(element)) return null; - - // returns the border-box dimensions rather than the content-box - // dimensions, so we subtract padding and borders from the value - var dim = parseInt(proceed(element, style), 10); - - if (dim !== element['offset' + style.capitalize()]) - return dim + 'px'; - - var properties; - if (style === 'height') { - properties = ['border-top-width', 'padding-top', - 'padding-bottom', 'border-bottom-width']; - } - else { - properties = ['border-left-width', 'padding-left', - 'padding-right', 'border-right-width']; - } - return properties.inject(dim, function(memo, property) { - var val = proceed(element, property); - return val === null ? memo : memo - parseInt(val, 10); - }) + 'px'; - default: return proceed(element, style); - } - } - ); - - Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( - function(proceed, element, attribute) { - if (attribute === 'title') return element.title; - return proceed(element, attribute); - } - ); -} - -else if (Prototype.Browser.IE) { - // IE doesn't report offsets correctly for static elements, so we change them - // to "relative" to get the values, then change them back. - Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( - function(proceed, element) { - element = $(element); - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - - $w('positionedOffset viewportOffset').each(function(method) { - Element.Methods[method] = Element.Methods[method].wrap( - function(proceed, element) { - element = $(element); - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - // Trigger hasLayout on the offset parent so that IE6 reports - // accurate offsetTop and offsetLeft values for position: fixed. - var offsetParent = element.getOffsetParent(); - if (offsetParent && offsetParent.getStyle('position') === 'fixed') - offsetParent.setStyle({ zoom: 1 }); - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - }); - - Element.Methods.getStyle = function(element, style) { - element = $(element); - style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); - var value = element.style[style]; - if (!value && element.currentStyle) value = element.currentStyle[style]; - - if (style == 'opacity') { - if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) - if (value[1]) return parseFloat(value[1]) / 100; - return 1.0; - } - - if (value == 'auto') { - if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) - return element['offset' + style.capitalize()] + 'px'; - return null; - } - return value; - }; - - Element.Methods.setOpacity = function(element, value) { - function stripAlpha(filter){ - return filter.replace(/alpha\([^\)]*\)/gi,''); - } - element = $(element); - var currentStyle = element.currentStyle; - if ((currentStyle && !currentStyle.hasLayout) || - (!currentStyle && element.style.zoom == 'normal')) - element.style.zoom = 1; - - var filter = element.getStyle('filter'), style = element.style; - if (value == 1 || value === '') { - (filter = stripAlpha(filter)) ? - style.filter = filter : style.removeAttribute('filter'); - return element; - } else if (value < 0.00001) value = 0; - style.filter = stripAlpha(filter) + - 'alpha(opacity=' + (value * 100) + ')'; - return element; - }; - - Element._attributeTranslations = { - read: { - names: { - 'class': 'className', - 'for': 'htmlFor' - }, - values: { - _getAttr: function(element, attribute) { - return element.getAttribute(attribute, 2); - }, - _getAttrNode: function(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ""; - }, - _getEv: function(element, attribute) { - attribute = element.getAttribute(attribute); - return attribute ? attribute.toString().slice(23, -2) : null; - }, - _flag: function(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - }, - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; - } - } - } - }; - - Element._attributeTranslations.write = { - names: Object.extend({ - cellpadding: 'cellPadding', - cellspacing: 'cellSpacing' - }, Element._attributeTranslations.read.names), - values: { - checked: function(element, value) { - element.checked = !!value; - }, - - style: function(element, value) { - element.style.cssText = value ? value : ''; - } - } - }; - - Element._attributeTranslations.has = {}; - - $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + - 'encType maxLength readOnly longDesc').each(function(attr) { - Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; - Element._attributeTranslations.has[attr.toLowerCase()] = attr; - }); - - (function(v) { - Object.extend(v, { - href: v._getAttr, - src: v._getAttr, - type: v._getAttr, - action: v._getAttrNode, - disabled: v._flag, - checked: v._flag, - readonly: v._flag, - multiple: v._flag, - onload: v._getEv, - onunload: v._getEv, - onclick: v._getEv, - ondblclick: v._getEv, - onmousedown: v._getEv, - onmouseup: v._getEv, - onmouseover: v._getEv, - onmousemove: v._getEv, - onmouseout: v._getEv, - onfocus: v._getEv, - onblur: v._getEv, - onkeypress: v._getEv, - onkeydown: v._getEv, - onkeyup: v._getEv, - onsubmit: v._getEv, - onreset: v._getEv, - onselect: v._getEv, - onchange: v._getEv - }); - })(Element._attributeTranslations.read.values); -} - -else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1) ? 0.999999 : - (value === '') ? '' : (value < 0.00001) ? 0 : value; - return element; - }; -} - -else if (Prototype.Browser.WebKit) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - - if (value == 1) - if(element.tagName == 'IMG' && element.width) { - element.width++; element.width--; - } else try { - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch (e) { } - - return element; - }; - - // Safari returns margins on body which is incorrect if the child is absolutely - // positioned. For performance reasons, redefine Element#cumulativeOffset for - // KHTML/WebKit only. - Element.Methods.cumulativeOffset = function(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) - if (Element.getStyle(element, 'position') == 'absolute') break; - - element = element.offsetParent; - } while (element); - - return Element._returnOffset(valueL, valueT); - }; -} - -if (Prototype.Browser.IE || Prototype.Browser.Opera) { - // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements - Element.Methods.update = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) return element.update().insert(content); - - content = Object.toHTML(content); - var tagName = element.tagName.toUpperCase(); - - if (tagName in Element._insertionTranslations.tags) { - $A(element.childNodes).each(function(node) { element.removeChild(node) }); - Element._getContentFromAnonymousElement(tagName, content.stripScripts()) - .each(function(node) { element.appendChild(node) }); - } - else element.innerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -if ('outerHTML' in document.createElement('div')) { - Element.Methods.replace = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - element.parentNode.replaceChild(content, element); - return element; - } - - content = Object.toHTML(content); - var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); - - if (Element._insertionTranslations.tags[tagName]) { - var nextSibling = element.next(); - var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - parent.removeChild(element); - if (nextSibling) - fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); - else - fragments.each(function(node) { parent.appendChild(node) }); - } - else element.outerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -Element._returnOffset = function(l, t) { - var result = [l, t]; - result.left = l; - result.top = t; - return result; -}; - -Element._getContentFromAnonymousElement = function(tagName, html) { - var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]; - if (t) { - div.innerHTML = t[0] + html + t[1]; - t[2].times(function() { div = div.firstChild }); - } else div.innerHTML = html; - return $A(div.childNodes); -}; - -Element._insertionTranslations = { - before: function(element, node) { - element.parentNode.insertBefore(node, element); - }, - top: function(element, node) { - element.insertBefore(node, element.firstChild); - }, - bottom: function(element, node) { - element.appendChild(node); - }, - after: function(element, node) { - element.parentNode.insertBefore(node, element.nextSibling); - }, - tags: { - TABLE: ['', '
', 1], - TBODY: ['', '
', 2], - TR: ['', '
', 3], - TD: ['
', '
', 4], - SELECT: ['', 1] - } -}; - -(function() { - Object.extend(this.tags, { - THEAD: this.tags.TBODY, - TFOOT: this.tags.TBODY, - TH: this.tags.TD - }); -}).call(Element._insertionTranslations); - -Element.Methods.Simulated = { - hasAttribute: function(element, attribute) { - attribute = Element._attributeTranslations.has[attribute] || attribute; - var node = $(element).getAttributeNode(attribute); - return node && node.specified; - } -}; - -Element.Methods.ByTag = { }; - -Object.extend(Element, Element.Methods); - -if (!Prototype.BrowserFeatures.ElementExtensions && - document.createElement('div').__proto__) { - window.HTMLElement = { }; - window.HTMLElement.prototype = document.createElement('div').__proto__; - Prototype.BrowserFeatures.ElementExtensions = true; -} - -Element.extend = (function() { - if (Prototype.BrowserFeatures.SpecificElementExtensions) - return Prototype.K; - - var Methods = { }, ByTag = Element.Methods.ByTag; - - var extend = Object.extend(function(element) { - if (!element || element._extendedByPrototype || - element.nodeType != 1 || element == window) return element; - - var methods = Object.clone(Methods), - tagName = element.tagName, property, value; - - // extend methods for specific tags - if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); - - for (property in methods) { - value = methods[property]; - if (Object.isFunction(value) && !(property in element)) - element[property] = value.methodize(); - } - - element._extendedByPrototype = Prototype.emptyFunction; - return element; - - }, { - refresh: function() { - // extend methods for all tags (Safari doesn't need this) - if (!Prototype.BrowserFeatures.ElementExtensions) { - Object.extend(Methods, Element.Methods); - Object.extend(Methods, Element.Methods.Simulated); - } - } - }); - - extend.refresh(); - return extend; -})(); - -Element.hasAttribute = function(element, attribute) { - if (element.hasAttribute) return element.hasAttribute(attribute); - return Element.Methods.Simulated.hasAttribute(element, attribute); -}; - -Element.addMethods = function(methods) { - var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; - - if (!methods) { - Object.extend(Form, Form.Methods); - Object.extend(Form.Element, Form.Element.Methods); - Object.extend(Element.Methods.ByTag, { - "FORM": Object.clone(Form.Methods), - "INPUT": Object.clone(Form.Element.Methods), - "SELECT": Object.clone(Form.Element.Methods), - "TEXTAREA": Object.clone(Form.Element.Methods) - }); - } - - if (arguments.length == 2) { - var tagName = methods; - methods = arguments[1]; - } - - if (!tagName) Object.extend(Element.Methods, methods || { }); - else { - if (Object.isArray(tagName)) tagName.each(extend); - else extend(tagName); - } - - function extend(tagName) { - tagName = tagName.toUpperCase(); - if (!Element.Methods.ByTag[tagName]) - Element.Methods.ByTag[tagName] = { }; - Object.extend(Element.Methods.ByTag[tagName], methods); - } - - function copy(methods, destination, onlyIfAbsent) { - onlyIfAbsent = onlyIfAbsent || false; - for (var property in methods) { - var value = methods[property]; - if (!Object.isFunction(value)) continue; - if (!onlyIfAbsent || !(property in destination)) - destination[property] = value.methodize(); - } - } - - function findDOMClass(tagName) { - var klass; - var trans = { - "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", - "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", - "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", - "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", - "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": - "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": - "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": - "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": - "FrameSet", "IFRAME": "IFrame" - }; - if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName.capitalize() + 'Element'; - if (window[klass]) return window[klass]; - - window[klass] = { }; - window[klass].prototype = document.createElement(tagName).__proto__; - return window[klass]; - } - - if (F.ElementExtensions) { - copy(Element.Methods, HTMLElement.prototype); - copy(Element.Methods.Simulated, HTMLElement.prototype, true); - } - - if (F.SpecificElementExtensions) { - for (var tag in Element.Methods.ByTag) { - var klass = findDOMClass(tag); - if (Object.isUndefined(klass)) continue; - copy(T[tag], klass.prototype); - } - } - - Object.extend(Element, Element.Methods); - delete Element.ByTag; - - if (Element.extend.refresh) Element.extend.refresh(); - Element.cache = { }; -}; - -document.viewport = { - getDimensions: function() { - var dimensions = { }; - var B = Prototype.Browser; - $w('width height').each(function(d) { - var D = d.capitalize(); - dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] : - (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D]; - }); - return dimensions; - }, - - getWidth: function() { - return this.getDimensions().width; - }, - - getHeight: function() { - return this.getDimensions().height; - }, - - getScrollOffsets: function() { - return Element._returnOffset( - window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); - } -}; -/* Portions of the Selector class are derived from Jack Slocum’s DomQuery, - * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style - * license. Please see http://www.yui-ext.com/ for more information. */ - -var Selector = Class.create({ - initialize: function(expression) { - this.expression = expression.strip(); - this.compileMatcher(); - }, - - shouldUseXPath: function() { - if (!Prototype.BrowserFeatures.XPath) return false; - - var e = this.expression; - - // Safari 3 chokes on :*-of-type and :empty - if (Prototype.Browser.WebKit && - (e.include("-of-type") || e.include(":empty"))) - return false; - - // XPath can't do namespaced attributes, nor can it read - // the "checked" property from DOM nodes - if ((/(\[[\w-]*?:|:checked)/).test(this.expression)) - return false; - - return true; - }, - - compileMatcher: function() { - if (this.shouldUseXPath()) - return this.compileXPathMatcher(); - - var e = this.expression, ps = Selector.patterns, h = Selector.handlers, - c = Selector.criteria, le, p, m; - - if (Selector._cache[e]) { - this.matcher = Selector._cache[e]; - return; - } - - this.matcher = ["this.matcher = function(root) {", - "var r = root, h = Selector.handlers, c = false, n;"]; - - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - p = ps[i]; - if (m = e.match(p)) { - this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : - new Template(c[i]).evaluate(m)); - e = e.replace(m[0], ''); - break; - } - } - } - - this.matcher.push("return h.unique(n);\n}"); - eval(this.matcher.join('\n')); - Selector._cache[this.expression] = this.matcher; - }, - - compileXPathMatcher: function() { - var e = this.expression, ps = Selector.patterns, - x = Selector.xpath, le, m; - - if (Selector._cache[e]) { - this.xpath = Selector._cache[e]; return; - } - - this.matcher = ['.//*']; - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - if (m = e.match(ps[i])) { - this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : - new Template(x[i]).evaluate(m)); - e = e.replace(m[0], ''); - break; - } - } - } - - this.xpath = this.matcher.join(''); - Selector._cache[this.expression] = this.xpath; - }, - - findElements: function(root) { - root = root || document; - if (this.xpath) return document._getElementsByXPath(this.xpath, root); - return this.matcher(root); - }, - - match: function(element) { - this.tokens = []; - - var e = this.expression, ps = Selector.patterns, as = Selector.assertions; - var le, p, m; - - while (e && le !== e && (/\S/).test(e)) { - le = e; - for (var i in ps) { - p = ps[i]; - if (m = e.match(p)) { - // use the Selector.assertions methods unless the selector - // is too complex. - if (as[i]) { - this.tokens.push([i, Object.clone(m)]); - e = e.replace(m[0], ''); - } else { - // reluctantly do a document-wide search - // and look for a match in the array - return this.findElements(document).include(element); - } - } - } - } - - var match = true, name, matches; - for (var i = 0, token; token = this.tokens[i]; i++) { - name = token[0], matches = token[1]; - if (!Selector.assertions[name](element, matches)) { - match = false; break; - } - } - - return match; - }, - - toString: function() { - return this.expression; - }, - - inspect: function() { - return "#"; - } -}); - -Object.extend(Selector, { - _cache: { }, - - xpath: { - descendant: "//*", - child: "/*", - adjacent: "/following-sibling::*[1]", - laterSibling: '/following-sibling::*', - tagName: function(m) { - if (m[1] == '*') return ''; - return "[local-name()='" + m[1].toLowerCase() + - "' or local-name()='" + m[1].toUpperCase() + "']"; - }, - className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", - id: "[@id='#{1}']", - attrPresence: function(m) { - m[1] = m[1].toLowerCase(); - return new Template("[@#{1}]").evaluate(m); - }, - attr: function(m) { - m[1] = m[1].toLowerCase(); - m[3] = m[5] || m[6]; - return new Template(Selector.xpath.operators[m[2]]).evaluate(m); - }, - pseudo: function(m) { - var h = Selector.xpath.pseudos[m[1]]; - if (!h) return ''; - if (Object.isFunction(h)) return h(m); - return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); - }, - operators: { - '=': "[@#{1}='#{3}']", - '!=': "[@#{1}!='#{3}']", - '^=': "[starts-with(@#{1}, '#{3}')]", - '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']", - '*=': "[contains(@#{1}, '#{3}')]", - '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", - '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" - }, - pseudos: { - 'first-child': '[not(preceding-sibling::*)]', - 'last-child': '[not(following-sibling::*)]', - 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', - 'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]", - 'checked': "[@checked]", - 'disabled': "[@disabled]", - 'enabled': "[not(@disabled)]", - 'not': function(m) { - var e = m[6], p = Selector.patterns, - x = Selector.xpath, le, v; - - var exclusion = []; - while (e && le != e && (/\S/).test(e)) { - le = e; - for (var i in p) { - if (m = e.match(p[i])) { - v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m); - exclusion.push("(" + v.substring(1, v.length - 1) + ")"); - e = e.replace(m[0], ''); - break; - } - } - } - return "[not(" + exclusion.join(" and ") + ")]"; - }, - 'nth-child': function(m) { - return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m); - }, - 'nth-last-child': function(m) { - return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m); - }, - 'nth-of-type': function(m) { - return Selector.xpath.pseudos.nth("position() ", m); - }, - 'nth-last-of-type': function(m) { - return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); - }, - 'first-of-type': function(m) { - m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); - }, - 'last-of-type': function(m) { - m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); - }, - 'only-of-type': function(m) { - var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m); - }, - nth: function(fragment, m) { - var mm, formula = m[6], predicate; - if (formula == 'even') formula = '2n+0'; - if (formula == 'odd') formula = '2n+1'; - if (mm = formula.match(/^(\d+)$/)) // digit only - return '[' + fragment + "= " + mm[1] + ']'; - if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b - if (mm[1] == "-") mm[1] = -1; - var a = mm[1] ? Number(mm[1]) : 1; - var b = mm[2] ? Number(mm[2]) : 0; - predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + - "((#{fragment} - #{b}) div #{a} >= 0)]"; - return new Template(predicate).evaluate({ - fragment: fragment, a: a, b: b }); - } - } - } - }, - - criteria: { - tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', - className: 'n = h.className(n, r, "#{1}", c); c = false;', - id: 'n = h.id(n, r, "#{1}", c); c = false;', - attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;', - attr: function(m) { - m[3] = (m[5] || m[6]); - return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m); - }, - pseudo: function(m) { - if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); - return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m); - }, - descendant: 'c = "descendant";', - child: 'c = "child";', - adjacent: 'c = "adjacent";', - laterSibling: 'c = "laterSibling";' - }, - - patterns: { - // combinators must be listed first - // (and descendant needs to be last combinator) - laterSibling: /^\s*~\s*/, - child: /^\s*>\s*/, - adjacent: /^\s*\+\s*/, - descendant: /^\s/, - - // selectors follow - tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, - id: /^#([\w\-\*]+)(\b|$)/, - className: /^\.([\w\-\*]+)(\b|$)/, - pseudo: -/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/, - attrPresence: /^\[([\w]+)\]/, - attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ - }, - - // for Selector.match and Element#match - assertions: { - tagName: function(element, matches) { - return matches[1].toUpperCase() == element.tagName.toUpperCase(); - }, - - className: function(element, matches) { - return Element.hasClassName(element, matches[1]); - }, - - id: function(element, matches) { - return element.id === matches[1]; - }, - - attrPresence: function(element, matches) { - return Element.hasAttribute(element, matches[1]); - }, - - attr: function(element, matches) { - var nodeValue = Element.readAttribute(element, matches[1]); - return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]); - } - }, - - handlers: { - // UTILITY FUNCTIONS - // joins two collections - concat: function(a, b) { - for (var i = 0, node; node = b[i]; i++) - a.push(node); - return a; - }, - - // marks an array of nodes for counting - mark: function(nodes) { - var _true = Prototype.emptyFunction; - for (var i = 0, node; node = nodes[i]; i++) - node._countedByPrototype = _true; - return nodes; - }, - - unmark: function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node._countedByPrototype = undefined; - return nodes; - }, - - // mark each child node with its position (for nth calls) - // "ofType" flag indicates whether we're indexing for nth-of-type - // rather than nth-child - index: function(parentNode, reverse, ofType) { - parentNode._countedByPrototype = Prototype.emptyFunction; - if (reverse) { - for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) { - var node = nodes[i]; - if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; - } - } else { - for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++) - if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++; - } - }, - - // filters out duplicates and extends all nodes - unique: function(nodes) { - if (nodes.length == 0) return nodes; - var results = [], n; - for (var i = 0, l = nodes.length; i < l; i++) - if (!(n = nodes[i])._countedByPrototype) { - n._countedByPrototype = Prototype.emptyFunction; - results.push(Element.extend(n)); - } - return Selector.handlers.unmark(results); - }, - - // COMBINATOR FUNCTIONS - descendant: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - h.concat(results, node.getElementsByTagName('*')); - return results; - }, - - child: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) { - for (var j = 0, child; child = node.childNodes[j]; j++) - if (child.nodeType == 1 && child.tagName != '!') results.push(child); - } - return results; - }, - - adjacent: function(nodes) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - var next = this.nextElementSibling(node); - if (next) results.push(next); - } - return results; - }, - - laterSibling: function(nodes) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - h.concat(results, Element.nextSiblings(node)); - return results; - }, - - nextElementSibling: function(node) { - while (node = node.nextSibling) - if (node.nodeType == 1) return node; - return null; - }, - - previousElementSibling: function(node) { - while (node = node.previousSibling) - if (node.nodeType == 1) return node; - return null; - }, - - // TOKEN FUNCTIONS - tagName: function(nodes, root, tagName, combinator) { - var uTagName = tagName.toUpperCase(); - var results = [], h = Selector.handlers; - if (nodes) { - if (combinator) { - // fastlane for ordinary descendant combinators - if (combinator == "descendant") { - for (var i = 0, node; node = nodes[i]; i++) - h.concat(results, node.getElementsByTagName(tagName)); - return results; - } else nodes = this[combinator](nodes); - if (tagName == "*") return nodes; - } - for (var i = 0, node; node = nodes[i]; i++) - if (node.tagName.toUpperCase() === uTagName) results.push(node); - return results; - } else return root.getElementsByTagName(tagName); - }, - - id: function(nodes, root, id, combinator) { - var targetNode = $(id), h = Selector.handlers; - if (!targetNode) return []; - if (!nodes && root == document) return [targetNode]; - if (nodes) { - if (combinator) { - if (combinator == 'child') { - for (var i = 0, node; node = nodes[i]; i++) - if (targetNode.parentNode == node) return [targetNode]; - } else if (combinator == 'descendant') { - for (var i = 0, node; node = nodes[i]; i++) - if (Element.descendantOf(targetNode, node)) return [targetNode]; - } else if (combinator == 'adjacent') { - for (var i = 0, node; node = nodes[i]; i++) - if (Selector.handlers.previousElementSibling(targetNode) == node) - return [targetNode]; - } else nodes = h[combinator](nodes); - } - for (var i = 0, node; node = nodes[i]; i++) - if (node == targetNode) return [targetNode]; - return []; - } - return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : []; - }, - - className: function(nodes, root, className, combinator) { - if (nodes && combinator) nodes = this[combinator](nodes); - return Selector.handlers.byClassName(nodes, root, className); - }, - - byClassName: function(nodes, root, className) { - if (!nodes) nodes = Selector.handlers.descendant([root]); - var needle = ' ' + className + ' '; - for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { - nodeClassName = node.className; - if (nodeClassName.length == 0) continue; - if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle)) - results.push(node); - } - return results; - }, - - attrPresence: function(nodes, root, attr, combinator) { - if (!nodes) nodes = root.getElementsByTagName("*"); - if (nodes && combinator) nodes = this[combinator](nodes); - var results = []; - for (var i = 0, node; node = nodes[i]; i++) - if (Element.hasAttribute(node, attr)) results.push(node); - return results; - }, - - attr: function(nodes, root, attr, value, operator, combinator) { - if (!nodes) nodes = root.getElementsByTagName("*"); - if (nodes && combinator) nodes = this[combinator](nodes); - var handler = Selector.operators[operator], results = []; - for (var i = 0, node; node = nodes[i]; i++) { - var nodeValue = Element.readAttribute(node, attr); - if (nodeValue === null) continue; - if (handler(nodeValue, value)) results.push(node); - } - return results; - }, - - pseudo: function(nodes, name, value, root, combinator) { - if (nodes && combinator) nodes = this[combinator](nodes); - if (!nodes) nodes = root.getElementsByTagName("*"); - return Selector.pseudos[name](nodes, value, root); - } - }, - - pseudos: { - 'first-child': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (Selector.handlers.previousElementSibling(node)) continue; - results.push(node); - } - return results; - }, - 'last-child': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - if (Selector.handlers.nextElementSibling(node)) continue; - results.push(node); - } - return results; - }, - 'only-child': function(nodes, value, root) { - var h = Selector.handlers; - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) - results.push(node); - return results; - }, - 'nth-child': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root); - }, - 'nth-last-child': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, true); - }, - 'nth-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, false, true); - }, - 'nth-last-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, formula, root, true, true); - }, - 'first-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, "1", root, false, true); - }, - 'last-of-type': function(nodes, formula, root) { - return Selector.pseudos.nth(nodes, "1", root, true, true); - }, - 'only-of-type': function(nodes, formula, root) { - var p = Selector.pseudos; - return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root); - }, - - // handles the an+b logic - getIndices: function(a, b, total) { - if (a == 0) return b > 0 ? [b] : []; - return $R(1, total).inject([], function(memo, i) { - if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); - return memo; - }); - }, - - // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type - nth: function(nodes, formula, root, reverse, ofType) { - if (nodes.length == 0) return []; - if (formula == 'even') formula = '2n+0'; - if (formula == 'odd') formula = '2n+1'; - var h = Selector.handlers, results = [], indexed = [], m; - h.mark(nodes); - for (var i = 0, node; node = nodes[i]; i++) { - if (!node.parentNode._countedByPrototype) { - h.index(node.parentNode, reverse, ofType); - indexed.push(node.parentNode); - } - } - if (formula.match(/^\d+$/)) { // just a number - formula = Number(formula); - for (var i = 0, node; node = nodes[i]; i++) - if (node.nodeIndex == formula) results.push(node); - } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b - if (m[1] == "-") m[1] = -1; - var a = m[1] ? Number(m[1]) : 1; - var b = m[2] ? Number(m[2]) : 0; - var indices = Selector.pseudos.getIndices(a, b, nodes.length); - for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { - for (var j = 0; j < l; j++) - if (node.nodeIndex == indices[j]) results.push(node); - } - } - h.unmark(nodes); - h.unmark(indexed); - return results; - }, - - 'empty': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) { - // IE treats comments as element nodes - if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue; - results.push(node); - } - return results; - }, - - 'not': function(nodes, selector, root) { - var h = Selector.handlers, selectorType, m; - var exclusions = new Selector(selector).findElements(root); - h.mark(exclusions); - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node._countedByPrototype) results.push(node); - h.unmark(exclusions); - return results; - }, - - 'enabled': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (!node.disabled) results.push(node); - return results; - }, - - 'disabled': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (node.disabled) results.push(node); - return results; - }, - - 'checked': function(nodes, value, root) { - for (var i = 0, results = [], node; node = nodes[i]; i++) - if (node.checked) results.push(node); - return results; - } - }, - - operators: { - '=': function(nv, v) { return nv == v; }, - '!=': function(nv, v) { return nv != v; }, - '^=': function(nv, v) { return nv.startsWith(v); }, - '$=': function(nv, v) { return nv.endsWith(v); }, - '*=': function(nv, v) { return nv.include(v); }, - '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, - '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); } - }, - - split: function(expression) { - var expressions = []; - expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { - expressions.push(m[1].strip()); - }); - return expressions; - }, - - matchElements: function(elements, expression) { - var matches = $$(expression), h = Selector.handlers; - h.mark(matches); - for (var i = 0, results = [], element; element = elements[i]; i++) - if (element._countedByPrototype) results.push(element); - h.unmark(matches); - return results; - }, - - findElement: function(elements, expression, index) { - if (Object.isNumber(expression)) { - index = expression; expression = false; - } - return Selector.matchElements(elements, expression || '*')[index || 0]; - }, - - findChildElements: function(element, expressions) { - expressions = Selector.split(expressions.join(',')); - var results = [], h = Selector.handlers; - for (var i = 0, l = expressions.length, selector; i < l; i++) { - selector = new Selector(expressions[i].strip()); - h.concat(results, selector.findElements(element)); - } - return (l > 1) ? h.unique(results) : results; - } -}); - -if (Prototype.Browser.IE) { - Object.extend(Selector.handlers, { - // IE returns comment nodes on getElementsByTagName("*"). - // Filter them out. - concat: function(a, b) { - for (var i = 0, node; node = b[i]; i++) - if (node.tagName !== "!") a.push(node); - return a; - }, - - // IE improperly serializes _countedByPrototype in (inner|outer)HTML. - unmark: function(nodes) { - for (var i = 0, node; node = nodes[i]; i++) - node.removeAttribute('_countedByPrototype'); - return nodes; - } - }); -} - -function $$() { - return Selector.findChildElements(document, $A(arguments)); -} -var Form = { - reset: function(form) { - $(form).reset(); - return form; - }, - - serializeElements: function(elements, options) { - if (typeof options != 'object') options = { hash: !!options }; - else if (Object.isUndefined(options.hash)) options.hash = true; - var key, value, submitted = false, submit = options.submit; - - var data = elements.inject({ }, function(result, element) { - if (!element.disabled && element.name) { - key = element.name; value = $(element).getValue(); - if (value != null && (element.type != 'submit' || (!submitted && - submit !== false && (!submit || key == submit) && (submitted = true)))) { - if (key in result) { - // a key is already present; construct an array of values - if (!Object.isArray(result[key])) result[key] = [result[key]]; - result[key].push(value); - } - else result[key] = value; - } - } - return result; - }); - - return options.hash ? data : Object.toQueryString(data); - } -}; - -Form.Methods = { - serialize: function(form, options) { - return Form.serializeElements(Form.getElements(form), options); - }, - - getElements: function(form) { - return $A($(form).getElementsByTagName('*')).inject([], - function(elements, child) { - if (Form.Element.Serializers[child.tagName.toLowerCase()]) - elements.push(Element.extend(child)); - return elements; - } - ); - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) return $A(inputs).map(Element.extend); - - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || (name && input.name != name)) - continue; - matchingInputs.push(Element.extend(input)); - } - - return matchingInputs; - }, - - disable: function(form) { - form = $(form); - Form.getElements(form).invoke('disable'); - return form; - }, - - enable: function(form) { - form = $(form); - Form.getElements(form).invoke('enable'); - return form; - }, - - findFirstElement: function(form) { - var elements = $(form).getElements().findAll(function(element) { - return 'hidden' != element.type && !element.disabled; - }); - var firstByIndex = elements.findAll(function(element) { - return element.hasAttribute('tabIndex') && element.tabIndex >= 0; - }).sortBy(function(element) { return element.tabIndex }).first(); - - return firstByIndex ? firstByIndex : elements.find(function(element) { - return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); - }); - }, - - focusFirstElement: function(form) { - form = $(form); - form.findFirstElement().activate(); - return form; - }, - - request: function(form, options) { - form = $(form), options = Object.clone(options || { }); - - var params = options.parameters, action = form.readAttribute('action') || ''; - if (action.blank()) action = window.location.href; - options.parameters = form.serialize(true); - - if (params) { - if (Object.isString(params)) params = params.toQueryParams(); - Object.extend(options.parameters, params); - } - - if (form.hasAttribute('method') && !options.method) - options.method = form.method; - - return new Ajax.Request(action, options); - } -}; - -/*--------------------------------------------------------------------------*/ - -Form.Element = { - focus: function(element) { - $(element).focus(); - return element; - }, - - select: function(element) { - $(element).select(); - return element; - } -}; - -Form.Element.Methods = { - serialize: function(element) { - element = $(element); - if (!element.disabled && element.name) { - var value = element.getValue(); - if (value != undefined) { - var pair = { }; - pair[element.name] = value; - return Object.toQueryString(pair); - } - } - return ''; - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - return Form.Element.Serializers[method](element); - }, - - setValue: function(element, value) { - element = $(element); - var method = element.tagName.toLowerCase(); - Form.Element.Serializers[method](element, value); - return element; - }, - - clear: function(element) { - $(element).value = ''; - return element; - }, - - present: function(element) { - return $(element).value != ''; - }, - - activate: function(element) { - element = $(element); - try { - element.focus(); - if (element.select && (element.tagName.toLowerCase() != 'input' || - !['button', 'reset', 'submit'].include(element.type))) - element.select(); - } catch (e) { } - return element; - }, - - disable: function(element) { - element = $(element); - element.blur(); - element.disabled = true; - return element; - }, - - enable: function(element) { - element = $(element); - element.disabled = false; - return element; - } -}; - -/*--------------------------------------------------------------------------*/ - -var Field = Form.Element; -var $F = Form.Element.Methods.getValue; - -/*--------------------------------------------------------------------------*/ - -Form.Element.Serializers = { - input: function(element, value) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - return Form.Element.Serializers.inputSelector(element, value); - default: - return Form.Element.Serializers.textarea(element, value); - } - }, - - inputSelector: function(element, value) { - if (Object.isUndefined(value)) return element.checked ? element.value : null; - else element.checked = !!value; - }, - - textarea: function(element, value) { - if (Object.isUndefined(value)) return element.value; - else element.value = value; - }, - - select: function(element, index) { - if (Object.isUndefined(index)) - return this[element.type == 'select-one' ? - 'selectOne' : 'selectMany'](element); - else { - var opt, value, single = !Object.isArray(index); - for (var i = 0, length = element.length; i < length; i++) { - opt = element.options[i]; - value = this.optionValue(opt); - if (single) { - if (value == index) { - opt.selected = true; - return; - } - } - else opt.selected = index.include(value); - } - } - }, - - selectOne: function(element) { - var index = element.selectedIndex; - return index >= 0 ? this.optionValue(element.options[index]) : null; - }, - - selectMany: function(element) { - var values, length = element.length; - if (!length) return null; - - for (var i = 0, values = []; i < length; i++) { - var opt = element.options[i]; - if (opt.selected) values.push(this.optionValue(opt)); - } - return values; - }, - - optionValue: function(opt) { - // extend element because hasAttribute may not be native - return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; - } -}; - -/*--------------------------------------------------------------------------*/ - -Abstract.TimedObserver = Class.create(PeriodicalExecuter, { - initialize: function($super, element, frequency, callback) { - $super(callback, frequency); - this.element = $(element); - this.lastValue = this.getValue(); - }, - - execute: function() { - var value = this.getValue(); - if (Object.isString(this.lastValue) && Object.isString(value) ? - this.lastValue != value : String(this.lastValue) != String(value)) { - this.callback(this.element, value); - this.lastValue = value; - } - } -}); - -Form.Element.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = Class.create({ - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - Form.getElements(this.element).each(this.registerCallback, this); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - default: - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -}); - -Form.Element.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); -if (!window.Event) var Event = { }; - -Object.extend(Event, { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - KEY_HOME: 36, - KEY_END: 35, - KEY_PAGEUP: 33, - KEY_PAGEDOWN: 34, - KEY_INSERT: 45, - - cache: { }, - - relatedTarget: function(event) { - var element; - switch(event.type) { - case 'mouseover': element = event.fromElement; break; - case 'mouseout': element = event.toElement; break; - default: return null; - } - return Element.extend(element); - } -}); - -Event.Methods = (function() { - var isButton; - - if (Prototype.Browser.IE) { - var buttonMap = { 0: 1, 1: 4, 2: 2 }; - isButton = function(event, code) { - return event.button == buttonMap[code]; - }; - - } else if (Prototype.Browser.WebKit) { - isButton = function(event, code) { - switch (code) { - case 0: return event.which == 1 && !event.metaKey; - case 1: return event.which == 1 && event.metaKey; - default: return false; - } - }; - - } else { - isButton = function(event, code) { - return event.which ? (event.which === code + 1) : (event.button === code); - }; - } - - return { - isLeftClick: function(event) { return isButton(event, 0) }, - isMiddleClick: function(event) { return isButton(event, 1) }, - isRightClick: function(event) { return isButton(event, 2) }, - - element: function(event) { - var node = Event.extend(event).target; - return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node); - }, - - findElement: function(event, expression) { - var element = Event.element(event); - if (!expression) return element; - var elements = [element].concat(element.ancestors()); - return Selector.findElement(elements, expression, 0); - }, - - pointer: function(event) { - return { - x: event.pageX || (event.clientX + - (document.documentElement.scrollLeft || document.body.scrollLeft)), - y: event.pageY || (event.clientY + - (document.documentElement.scrollTop || document.body.scrollTop)) - }; - }, - - pointerX: function(event) { return Event.pointer(event).x }, - pointerY: function(event) { return Event.pointer(event).y }, - - stop: function(event) { - Event.extend(event); - event.preventDefault(); - event.stopPropagation(); - event.stopped = true; - } - }; -})(); - -Event.extend = (function() { - var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { - m[name] = Event.Methods[name].methodize(); - return m; - }); - - if (Prototype.Browser.IE) { - Object.extend(methods, { - stopPropagation: function() { this.cancelBubble = true }, - preventDefault: function() { this.returnValue = false }, - inspect: function() { return "[object Event]" } - }); - - return function(event) { - if (!event) return false; - if (event._extendedByPrototype) return event; - - event._extendedByPrototype = Prototype.emptyFunction; - var pointer = Event.pointer(event); - Object.extend(event, { - target: event.srcElement, - relatedTarget: Event.relatedTarget(event), - pageX: pointer.x, - pageY: pointer.y - }); - return Object.extend(event, methods); - }; - - } else { - Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__; - Object.extend(Event.prototype, methods); - return Prototype.K; - } -})(); - -Object.extend(Event, (function() { - var cache = Event.cache; - - function getEventID(element) { - if (element._prototypeEventID) return element._prototypeEventID[0]; - arguments.callee.id = arguments.callee.id || 1; - return element._prototypeEventID = [++arguments.callee.id]; - } - - function getDOMEventName(eventName) { - if (eventName && eventName.include(':')) return "dataavailable"; - return eventName; - } - - function getCacheForID(id) { - return cache[id] = cache[id] || { }; - } - - function getWrappersForEventName(id, eventName) { - var c = getCacheForID(id); - return c[eventName] = c[eventName] || []; - } - - function createWrapper(element, eventName, handler) { - var id = getEventID(element); - var c = getWrappersForEventName(id, eventName); - if (c.pluck("handler").include(handler)) return false; - - var wrapper = function(event) { - if (!Event || !Event.extend || - (event.eventName && event.eventName != eventName)) - return false; - - Event.extend(event); - handler.call(element, event); - }; - - wrapper.handler = handler; - c.push(wrapper); - return wrapper; - } - - function findWrapper(id, eventName, handler) { - var c = getWrappersForEventName(id, eventName); - return c.find(function(wrapper) { return wrapper.handler == handler }); - } - - function destroyWrapper(id, eventName, handler) { - var c = getCacheForID(id); - if (!c[eventName]) return false; - c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); - } - - function destroyCache() { - for (var id in cache) - for (var eventName in cache[id]) - cache[id][eventName] = null; - } - - if (window.attachEvent) { - window.attachEvent("onunload", destroyCache); - } - - return { - observe: function(element, eventName, handler) { - element = $(element); - var name = getDOMEventName(eventName); - - var wrapper = createWrapper(element, eventName, handler); - if (!wrapper) return element; - - if (element.addEventListener) { - element.addEventListener(name, wrapper, false); - } else { - element.attachEvent("on" + name, wrapper); - } - - return element; - }, - - stopObserving: function(element, eventName, handler) { - element = $(element); - var id = getEventID(element), name = getDOMEventName(eventName); - - if (!handler && eventName) { - getWrappersForEventName(id, eventName).each(function(wrapper) { - element.stopObserving(eventName, wrapper.handler); - }); - return element; - - } else if (!eventName) { - Object.keys(getCacheForID(id)).each(function(eventName) { - element.stopObserving(eventName); - }); - return element; - } - - var wrapper = findWrapper(id, eventName, handler); - if (!wrapper) return element; - - if (element.removeEventListener) { - element.removeEventListener(name, wrapper, false); - } else { - element.detachEvent("on" + name, wrapper); - } - - destroyWrapper(id, eventName, handler); - - return element; - }, - - fire: function(element, eventName, memo) { - element = $(element); - if (element == document && document.createEvent && !element.dispatchEvent) - element = document.documentElement; - - var event; - if (document.createEvent) { - event = document.createEvent("HTMLEvents"); - event.initEvent("dataavailable", true, true); - } else { - event = document.createEventObject(); - event.eventType = "ondataavailable"; - } - - event.eventName = eventName; - event.memo = memo || { }; - - if (document.createEvent) { - element.dispatchEvent(event); - } else { - element.fireEvent(event.eventType, event); - } - - return Event.extend(event); - } - }; -})()); - -Object.extend(Event, Event.Methods); - -Element.addMethods({ - fire: Event.fire, - observe: Event.observe, - stopObserving: Event.stopObserving -}); - -Object.extend(document, { - fire: Element.Methods.fire.methodize(), - observe: Element.Methods.observe.methodize(), - stopObserving: Element.Methods.stopObserving.methodize(), - loaded: false -}); - -(function() { - /* Support for the DOMContentLoaded event is based on work by Dan Webb, - Matthias Miller, Dean Edwards and John Resig. */ - - var timer; - - function fireContentLoadedEvent() { - if (document.loaded) return; - if (timer) window.clearInterval(timer); - document.fire("dom:loaded"); - document.loaded = true; - } - - if (document.addEventListener) { - if (Prototype.Browser.WebKit) { - timer = window.setInterval(function() { - if (/loaded|complete/.test(document.readyState)) - fireContentLoadedEvent(); - }, 0); - - Event.observe(window, "load", fireContentLoadedEvent); - - } else { - document.addEventListener("DOMContentLoaded", - fireContentLoadedEvent, false); - } - - } else { - document.write("' ); - - iframe_doc.close(); - - // Update the Iframe's hash, for great justice. - iframe.location.hash = hash; - } - }; - - })(); - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - // ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^ - // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - return self; - })(); - -})(jQuery,this); -/* -* jQuery Mobile Framework : "page" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { - -$.widget( "mobile.page", $.mobile.widget, { - options: { - backBtnText: "Back", - addBackBtn: true, - backBtnTheme: null, - degradeInputs: { - color: false, - date: false, - datetime: false, - "datetime-local": false, - email: false, - month: false, - number: false, - range: "number", - search: true, - tel: false, - time: false, - url: false, - week: false - }, - keepNative: null - }, - - _create: function() { - var $elem = this.element, - o = this.options; - - this.keepNative = ":jqmData(role='none'), :jqmData(role='nojs')" + (o.keepNative ? ", " + o.keepNative : ""); - - if ( this._trigger( "beforeCreate" ) === false ) { - return; - } - - //some of the form elements currently rely on the presence of ui-page and ui-content - // classes so we'll handle page and content roles outside of the main role processing - // loop below. - $elem.find( ":jqmData(role='page'), :jqmData(role='content')" ).andSelf().each(function() { - $(this).addClass( "ui-" + $(this).jqmData( "role" ) ); - }); - - $elem.find( ":jqmData(role='nojs')" ).addClass( "ui-nojs" ); - - // pre-find data els - var $dataEls = $elem.find( ":jqmData(role)" ).andSelf().each(function() { - var $this = $( this ), - role = $this.jqmData( "role" ), - theme = $this.jqmData( "theme" ); - - //apply theming and markup modifications to page,header,content,footer - if ( role === "header" || role === "footer" ) { - $this.addClass( "ui-bar-" + (theme || $this.parent( ":jqmData(role='page')" ).jqmData( "theme" ) || "a") ); - - // add ARIA role - $this.attr( "role", role === "header" ? "banner" : "contentinfo" ); - - //right,left buttons - var $headeranchors = $this.children( "a" ), - leftbtn = $headeranchors.hasClass( "ui-btn-left" ), - rightbtn = $headeranchors.hasClass( "ui-btn-right" ); - - if ( !leftbtn ) { - leftbtn = $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length; - } - - if ( !rightbtn ) { - rightbtn = $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length; - } - - // auto-add back btn on pages beyond first view - if ( o.addBackBtn && role === "header" && - $( ".ui-page" ).length > 1 && - $elem.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) && - !leftbtn && $this.jqmData( "backbtn" ) !== false ) { - - var backBtn = $( ""+ o.backBtnText +"" ).prependTo( $this ); - - //if theme is provided, override default inheritance - if( o.backBtnTheme ){ - backBtn.attr( "data-"+ $.mobile.ns +"theme", o.backBtnTheme ); - } - } - - //page title - $this.children( "h1, h2, h3, h4, h5, h6" ) - .addClass( "ui-title" ) - //regardless of h element number in src, it becomes h1 for the enhanced page - .attr({ "tabindex": "0", "role": "heading", "aria-level": "1" }); - - } else if ( role === "content" ) { - if ( theme ) { - $this.addClass( "ui-body-" + theme ); - } - - // add ARIA role - $this.attr( "role", "main" ); - - } else if ( role === "page" ) { - $this.addClass( "ui-body-" + (theme || "c") ); - } - - switch(role) { - case "header": - case "footer": - case "page": - case "content": - $this.addClass( "ui-" + role ); - break; - case "collapsible": - case "fieldcontain": - case "navbar": - case "listview": - case "dialog": - $this[ role ](); - break; - } - }); - - //enhance form controls - this._enhanceControls(); - - //links in bars, or those with data-role become buttons - $elem.find( ":jqmData(role='button'), .ui-bar > a, .ui-header > a, .ui-footer > a" ) - .not( ".ui-btn" ) - .not(this.keepNative) - .buttonMarkup(); - - $elem - .find(":jqmData(role='controlgroup')") - .controlgroup(); - - //links within content areas - $elem.find( "a:not(.ui-btn):not(.ui-link-inherit)" ) - .not(this.keepNative) - .addClass( "ui-link" ); - - //fix toolbars - $elem.fixHeaderFooter(); - }, - - _typeAttributeRegex: /\s+type=["']?\w+['"]?/, - - _enhanceControls: function() { - var o = this.options, self = this; - - // degrade inputs to avoid poorly implemented native functionality - this.element.find( "input" ).not(this.keepNative).each(function() { - var type = this.getAttribute( "type" ), - optType = o.degradeInputs[ type ] || "text"; - - if ( o.degradeInputs[ type ] ) { - $( this ).replaceWith( - $( "
" ).html( $(this).clone() ).html() - .replace( self._typeAttributeRegex, " type=\""+ optType +"\" data-" + $.mobile.ns + "type=\""+type+"\" " ) ); - } - }); - - // We re-find form elements since the degredation code above - // may have injected new elements. We cache the non-native control - // query to reduce the number of times we search through the entire page. - - var allControls = this.element.find("input, textarea, select, button"), - nonNativeControls = allControls.not(this.keepNative); - - // XXX: Temporary workaround for issue 785. Turn off autocorrect and - // autocomplete since the popup they use can't be dismissed by - // the user. Note that we test for the presence of the feature - // by looking for the autocorrect property on the input element. - - var textInputs = allControls.filter( "input[type=text]" ); - if (textInputs.length && typeof textInputs[0].autocorrect !== "undefined") { - textInputs.each(function(){ - // Set the attribute instead of the property just in case there - // is code that attempts to make modifications via HTML. - this.setAttribute("autocorrect", "off"); - this.setAttribute("autocomplete", "off"); - }); - } - - // enchance form controls - nonNativeControls - .filter( "[type='radio'], [type='checkbox']" ) - .checkboxradio(); - - nonNativeControls - .filter( "button, [type='button'], [type='submit'], [type='reset'], [type='image']" ) - .button(); - - nonNativeControls - .filter( "input, textarea" ) - .not( "[type='radio'], [type='checkbox'], [type='button'], [type='submit'], [type='reset'], [type='image'], [type='hidden']" ) - .textinput(); - - nonNativeControls - .filter( "input, select" ) - .filter( ":jqmData(role='slider'), :jqmData(type='range')" ) - .slider(); - - nonNativeControls - .filter( "select:not(:jqmData(role='slider'))" ) - .selectmenu(); - } -}); - -})( jQuery ); -/*! - * jQuery Mobile v@VERSION - * http://jquerymobile.com/ - * - * Copyright 2010, jQuery Project - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ - -(function( $, window, undefined ) { - - //jQuery.mobile configurable options - $.extend( $.mobile, { - - //namespace used framework-wide for data-attrs. Default is no namespace - ns: "", - - //define the url parameter used for referencing widget-generated sub-pages. - //Translates to to example.html&ui-page=subpageIdentifier - //hash segment before &ui-page= is used to make Ajax request - subPageUrlKey: "ui-page", - - //anchor links with a data-rel, or pages with a data-role, that match these selectors will be untrackable in history - //(no change in URL, not bookmarkable) - nonHistorySelectors: "dialog", - - //class assigned to page currently in view, and during transitions - activePageClass: "ui-page-active", - - //class used for "active" button state, from CSS framework - activeBtnClass: "ui-btn-active", - - //automatically handle clicks and form submissions through Ajax, when same-domain - ajaxEnabled: true, - - //automatically load and show pages based on location.hash - hashListeningEnabled: true, - - // TODO: deprecated - remove at 1.0 - //automatically handle link clicks through Ajax, when possible - ajaxLinksEnabled: true, - - // TODO: deprecated - remove at 1.0 - //automatically handle form submissions through Ajax, when possible - ajaxFormsEnabled: true, - - //set default transition - 'none' for no transitions - defaultTransition: "slide", - - //show loading message during Ajax requests - //if false, message will not appear, but loading classes will still be toggled on html el - loadingMessage: "loading", - - //error response message - appears when an Ajax page request fails - pageLoadErrorMessage: "Error Loading Page", - - //configure meta viewport tag's content attr: - //note: this feature is deprecated in A4 in favor of adding - //the meta viewport element directly in the markup - metaViewportContent: "width=device-width, minimum-scale=1, maximum-scale=1", - - //support conditions that must be met in order to proceed - //default enhanced qualifications are media query support OR IE 7+ - gradeA: function(){ - return $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7; - }, - - //TODO might be useful upstream in jquery itself ? - keyCode: { - ALT: 18, - BACKSPACE: 8, - CAPS_LOCK: 20, - COMMA: 188, - COMMAND: 91, - COMMAND_LEFT: 91, // COMMAND - COMMAND_RIGHT: 93, - CONTROL: 17, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - INSERT: 45, - LEFT: 37, - MENU: 93, // COMMAND_RIGHT - NUMPAD_ADD: 107, - NUMPAD_DECIMAL: 110, - NUMPAD_DIVIDE: 111, - NUMPAD_ENTER: 108, - NUMPAD_MULTIPLY: 106, - NUMPAD_SUBTRACT: 109, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SHIFT: 16, - SPACE: 32, - TAB: 9, - UP: 38, - WINDOWS: 91 // COMMAND - }, - - //scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value - silentScroll: function( ypos ) { - ypos = ypos || 0; - // prevent scrollstart and scrollstop events - $.event.special.scrollstart.enabled = false; - - setTimeout(function() { - window.scrollTo( 0, ypos ); - $(document).trigger( "silentscroll", { x: 0, y: ypos }); - },20); - - setTimeout(function() { - $.event.special.scrollstart.enabled = true; - }, 150 ); - } - }); - - //mobile version of data and removeData and hasData methods - //ensures all data is set and retrieved using jQuery Mobile's data namespace - $.fn.jqmData = function( prop, value ){ - return this.data( prop ? $.mobile.ns + prop : prop, value ); - }; - - $.jqmData = function( elem, prop, value ){ - return $.data( elem, prop && $.mobile.ns + prop, value ); - }; - - $.fn.jqmRemoveData = function( prop ){ - return this.removeData( $.mobile.ns + prop ); - }; - - $.jqmRemoveData = function( elem, prop ){ - return $.removeData( elem, prop && $.mobile.ns + prop ); - }; - - $.jqmHasData = function( elem, prop ){ - return $.hasData( elem, prop && $.mobile.ns + prop ); - }; - - - // Monkey-patching Sizzle to filter the :jqmData selector - var oldFind = $.find; - - $.find = function( selector, context, ret, extra ) { - selector = selector.replace(/:jqmData\(([^)]*)\)/g, "[data-" + ($.mobile.ns || "") + "$1]"); - - return oldFind.call( this, selector, context, ret, extra ); - }; - - $.extend( $.find, oldFind ); - - $.find.matches = function( expr, set ) { - return $.find( expr, null, null, set ); - }; - - $.find.matchesSelector = function( node, expr ) { - return $.find( expr, null, null, [node] ).length > 0; - }; -})( jQuery, this ); -/* -* jQuery Mobile Framework : core utilities for auto ajax navigation, base tag mgmt, -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { - - //define vars for interal use - var $window = $(window), - $html = $('html'), - $head = $('head'), - - //url path helpers for use in relative url management - path = { - - //get path from current hash, or from a file path - get: function( newPath ){ - if( newPath === undefined ){ - newPath = location.hash; - } - return path.stripHash( newPath ).replace(/[^\/]*\.[^\/*]+$/, ''); - }, - - //return the substring of a filepath before the sub-page key, for making a server request - getFilePath: function( path ){ - var splitkey = '&' + $.mobile.subPageUrlKey; - return path && path.split( splitkey )[0].split( dialogHashKey )[0]; - }, - - //set location hash to path - set: function( path ){ - location.hash = path; - }, - - //location pathname from intial directory request - origin: '', - - setOrigin: function(){ - path.origin = path.get( location.protocol + '//' + location.host + location.pathname ); - }, - - //prefix a relative url with the current path - // TODO rename to reflect conditional functionality - makeAbsolute: function( url ){ - // only create an absolute path when the hash can be used as one - return path.isPath(window.location.hash) ? path.get() + url : url; - }, - - // test if a given url (string) is a path - // NOTE might be exceptionally naive - isPath: function( url ){ - return /\//.test(url); - }, - - //return a url path with the window's location protocol/hostname/pathname removed - clean: function( url ){ - // Replace the protocol, host, and pathname only once at the beginning of the url to avoid - // problems when it's included as a part of a param - // Also, since all urls are absolute in IE, we need to remove the pathname as well. - var leadingUrlRootRegex = new RegExp("^" + location.protocol + "//" + location.host + location.pathname); - return url.replace(leadingUrlRootRegex, ""); - }, - - //just return the url without an initial # - stripHash: function( url ){ - return url.replace( /^#/, "" ); - }, - - //check whether a url is referencing the same domain, or an external domain or different protocol - //could be mailto, etc - isExternal: function( url ){ - return path.hasProtocol( path.clean( url ) ); - }, - - hasProtocol: function( url ){ - return (/^(:?\w+:)/).test( url ); - }, - - //check if the url is relative - isRelative: function( url ){ - return (/^[^\/|#]/).test( url ) && !path.hasProtocol( url ); - }, - - isEmbeddedPage: function( url ){ - return (/^#/).test( url ); - } - }, - - //will be defined when a link is clicked and given an active class - $activeClickedLink = null, - - //urlHistory is purely here to make guesses at whether the back or forward button was clicked - //and provide an appropriate transition - urlHistory = { - //array of pages that are visited during a single page load. each has a url and optional transition - stack: [], - - //maintain an index number for the active page in the stack - activeIndex: 0, - - //get active - getActive: function(){ - return urlHistory.stack[ urlHistory.activeIndex ]; - }, - - getPrev: function(){ - return urlHistory.stack[ urlHistory.activeIndex - 1 ]; - }, - - getNext: function(){ - return urlHistory.stack[ urlHistory.activeIndex + 1 ]; - }, - - // addNew is used whenever a new page is added - addNew: function( url, transition, title, storedTo ){ - //if there's forward history, wipe it - if( urlHistory.getNext() ){ - urlHistory.clearForward(); - } - - urlHistory.stack.push( {url : url, transition: transition, title: title, page: storedTo } ); - - urlHistory.activeIndex = urlHistory.stack.length - 1; - }, - - //wipe urls ahead of active index - clearForward: function(){ - urlHistory.stack = urlHistory.stack.slice( 0, urlHistory.activeIndex + 1 ); - }, - - directHashChange: function(opts){ - var back , forward, newActiveIndex; - - // check if url isp in history and if it's ahead or behind current page - $.each( urlHistory.stack, function( i, historyEntry ){ - - //if the url is in the stack, it's a forward or a back - if( opts.currentUrl === historyEntry.url ){ - //define back and forward by whether url is older or newer than current page - back = i < urlHistory.activeIndex; - forward = !back; - newActiveIndex = i; - } - }); - - // save new page index, null check to prevent falsey 0 result - this.activeIndex = newActiveIndex !== undefined ? newActiveIndex : this.activeIndex; - - if( back ){ - opts.isBack(); - } else if( forward ){ - opts.isForward(); - } - }, - - //disable hashchange event listener internally to ignore one change - //toggled internally when location.hash is updated to match the url of a successful page load - ignoreNextHashChange: true - }, - - //define first selector to receive focus when a page is shown - focusable = "[tabindex],a,button:visible,select:visible,input", - - //contains role for next page, if defined on clicked link via data-rel - nextPageRole = null, - - //queue to hold simultanious page transitions - pageTransitionQueue = [], - - // indicates whether or not page is in process of transitioning - isPageTransitioning = false, - - //nonsense hash change key for dialogs, so they create a history entry - dialogHashKey = "&ui-state=dialog", - - //existing base tag? - $base = $head.children("base"), - hostURL = location.protocol + '//' + location.host, - docLocation = path.get( hostURL + location.pathname ), - docBase = docLocation; - - if ($base.length){ - var href = $base.attr("href"); - if (href){ - if (href.search(/^[^:\/]+:\/\/[^\/]+\/?/) === -1){ - //the href is not absolute, we need to turn it into one - //so that we can turn paths stored in our location hash into - //relative paths. - if (href.charAt(0) === '/'){ - //site relative url - docBase = hostURL + href; - } - else { - //the href is a document relative url - docBase = docLocation + href; - //XXX: we need some code here to calculate the final path - // just in case the docBase contains up-level (../) references. - } - } - else { - //the href is an absolute url - docBase = href; - } - } - //make sure docBase ends with a slash - docBase = docBase + (docBase.charAt(docBase.length - 1) === '/' ? ' ' : '/'); - } - - //base element management, defined depending on dynamic base tag support - var base = $.support.dynamicBaseTag ? { - - //define base element, for use in routing asset urls that are referenced in Ajax-requested markup - element: ($base.length ? $base : $("", { href: docBase }).prependTo( $head )), - - //set the generated BASE element's href attribute to a new page's base path - set: function( href ){ - base.element.attr('href', docBase + path.get( href )); - }, - - //set the generated BASE element's href attribute to a new page's base path - reset: function(){ - base.element.attr('href', docBase ); - } - - } : undefined; - - - - //set location pathname from intial directory request - path.setOrigin(); - -/* - internal utility functions ---------------------------------------*/ - - - //direct focus to the page title, or otherwise first focusable element - function reFocus( page ){ - var pageTitle = page.find( ".ui-title:eq(0)" ); - if( pageTitle.length ){ - pageTitle.focus(); - } - else{ - page.find( focusable ).eq(0).focus(); - } - } - - //remove active classes after page transition or error - function removeActiveLinkClass( forceRemoval ){ - if( !!$activeClickedLink && (!$activeClickedLink.closest( '.ui-page-active' ).length || forceRemoval )){ - $activeClickedLink.removeClass( $.mobile.activeBtnClass ); - } - $activeClickedLink = null; - } - - //animation complete callback - $.fn.animationComplete = function( callback ){ - if($.support.cssTransitions){ - return $(this).one('webkitAnimationEnd', callback); - } - else{ - // defer execution for consistency between webkit/non webkit - setTimeout(callback, 0); - return $(this); - } - }; - - - -/* exposed $.mobile methods */ - - //update location.hash, with or without triggering hashchange event - //TODO - deprecate this one at 1.0 - $.mobile.updateHash = path.set; - - //expose path object on $.mobile - $.mobile.path = path; - - //expose base object on $.mobile - $.mobile.base = base; - - //url stack, useful when plugins need to be aware of previous pages viewed - //TODO: deprecate this one at 1.0 - $.mobile.urlstack = urlHistory.stack; - - //history stack - $.mobile.urlHistory = urlHistory; - - //enable cross-domain page support - $.mobile.allowCrossDomainPages = false; - - // changepage function - $.mobile.changePage = function( to, transition, reverse, changeHash, fromHashChange ){ - //from is always the currently viewed page - var toIsArray = $.type(to) === "array", - toIsObject = $.type(to) === "object", - from = toIsArray ? to[0] : $.mobile.activePage; - - to = toIsArray ? to[1] : to; - - var url = $.type(to) === "string" ? path.stripHash( to ) : "", - fileUrl = url, - data, - type = 'get', - isFormRequest = false, - duplicateCachedPage = null, - currPage = urlHistory.getActive(), - back = false, - forward = false - pageTitle = document.title; - - - // If we are trying to transition to the same page that we are currently on ignore the request. - // an illegal same page request is defined by the current page being the same as the url, as long as there's history - // and to is not an array or object (those are allowed to be "same") - if( currPage && urlHistory.stack.length > 1 && currPage.url === url && !toIsArray && !toIsObject ) { - return; - } - else if(isPageTransitioning) { - pageTransitionQueue.unshift(arguments); - return; - } - - isPageTransitioning = true; - - // if the changePage was sent from a hashChange event guess if it came from the history menu - // and match the transition accordingly - if( fromHashChange ){ - urlHistory.directHashChange({ - currentUrl: url, - isBack: function(){ - forward = !(back = true); - reverse = true; - transition = transition || currPage.transition; - }, - isForward: function(){ - forward = !(back = false); - transition = transition || urlHistory.getActive().transition; - } - }); - - //TODO forward = !back was breaking for some reason - } - - if( toIsObject && to.url ){ - url = to.url; - data = to.data; - type = to.type; - isFormRequest = true; - //make get requests bookmarkable - if( data && type === 'get' ){ - if($.type( data ) === "object" ){ - data = $.param(data); - } - - url += "?" + data; - data = undefined; - } - } - - //reset base to pathname for new request - if(base){ base.reset(); } - - //kill the keyboard - $( window.document.activeElement ).add( "input:focus, textarea:focus, select:focus" ).blur(); - - function defaultTransition(){ - if(transition === undefined){ - transition = ( nextPageRole && nextPageRole === 'dialog' ) ? 'pop' : $.mobile.defaultTransition; - } - } - - function releasePageTransitionLock(){ - isPageTransitioning = false; - if(pageTransitionQueue.length>0) { - $.mobile.changePage.apply($.mobile, pageTransitionQueue.pop()); - } - } - - //function for transitioning between two existing pages - function transitionPages() { - $.mobile.silentScroll(); - - //get current scroll distance - var currScroll = $window.scrollTop(), - perspectiveTransitions = [ "flip" ], - pageContainerClasses = []; - - //support deep-links to generated sub-pages - if( url.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ){ - to = $( ":jqmData(url='" + url + "')" ); - } - - if( from ){ - //set as data for returning to that spot - from.jqmData( "lastScroll", currScroll); - //trigger before show/hide events - from.data( "page" )._trigger( "beforehide", null, { nextPage: to } ); - } - to.data( "page" )._trigger( "beforeshow", null, { prevPage: from || $("") } ); - - function loadComplete(){ - - if( changeHash !== false && url ){ - //disable hash listening temporarily - urlHistory.ignoreNextHashChange = false; - //update hash and history - path.set( url ); - } - - //if title element wasn't found, try the page div data attr too - var newPageTitle = to.attr( ":jqmData(title)" ) || to.find(".ui-header .ui-title" ).text(); - if( !!newPageTitle && pageTitle == document.title ){ - pageTitle = newPageTitle; - } - - //add page to history stack if it's not back or forward - if( !back && !forward ){ - urlHistory.addNew( url, transition, pageTitle, to ); - } - - //set page title - document.title = urlHistory.getActive().title; - - removeActiveLinkClass(); - - //jump to top or prev scroll, sometimes on iOS the page has not rendered yet. I could only get by this with a setTimeout, but would like to avoid that. - $.mobile.silentScroll( to.jqmData( "lastScroll" ) ); - - reFocus( to ); - - //trigger show/hide events - if( from ){ - from.data( "page" )._trigger( "hide", null, { nextPage: to } ); - } - //trigger pageshow, define prevPage as either from or empty jQuery obj - to.data( "page" )._trigger( "show", null, { prevPage: from || $("") } ); - - //set "to" as activePage - $.mobile.activePage = to; - - //if there's a duplicateCachedPage, remove it from the DOM now that it's hidden - if (duplicateCachedPage !== null) { - duplicateCachedPage.remove(); - } - - //remove initial build class (only present on first pageshow) - $html.removeClass( "ui-mobile-rendering" ); - - releasePageTransitionLock(); - } - - function addContainerClass(className){ - $.mobile.pageContainer.addClass(className); - pageContainerClasses.push(className); - } - - function removeContainerClasses(){ - $.mobile - .pageContainer - .removeClass(pageContainerClasses.join(" ")); - - pageContainerClasses = []; - } - - if(transition && (transition !== 'none')){ - $.mobile.pageLoading( true ); - if( $.inArray(transition, perspectiveTransitions) >= 0 ){ - addContainerClass('ui-mobile-viewport-perspective'); - } - - addContainerClass('ui-mobile-viewport-transitioning'); - - if( from ){ - from.addClass( transition + " out " + ( reverse ? "reverse" : "" ) ); - } - to.addClass( $.mobile.activePageClass + " " + transition + - " in " + ( reverse ? "reverse" : "" ) ); - - // callback - remove classes, etc - to.animationComplete(function() { - to.add(from).removeClass("out in reverse " + transition ); - if( from ){ - from.removeClass( $.mobile.activePageClass ); - } - loadComplete(); - removeContainerClasses(); - }); - } - else{ - $.mobile.pageLoading( true ); - if( from ){ - from.removeClass( $.mobile.activePageClass ); - } - to.addClass( $.mobile.activePageClass ); - loadComplete(); - } - } - - //shared page enhancements - function enhancePage(){ - - //set next page role, if defined - if ( nextPageRole || to.jqmData('role') === 'dialog' ) { - url = urlHistory.getActive().url + dialogHashKey; - if(nextPageRole){ - to.attr( "data-" + $.mobile.ns + "role", nextPageRole ); - nextPageRole = null; - } - } - - //run page plugin - to.page(); - } - - //if url is a string - if( url ){ - to = $( ":jqmData(url='" + url + "')" ); - fileUrl = path.getFilePath(url); - } - else{ //find base url of element, if avail - var toID = to.attr( "data-" + $.mobile.ns + "url" ), - toIDfileurl = path.getFilePath(toID); - - if(toID !== toIDfileurl){ - fileUrl = toIDfileurl; - } - } - - // ensure a transition has been set where pop is undefined - defaultTransition(); - - // find the "to" page, either locally existing in the dom or by creating it through ajax - if ( to.length && !isFormRequest ) { - if( fileUrl && base ){ - base.set( fileUrl ); - } - enhancePage(); - transitionPages(); - } else { - - //if to exists in DOM, save a reference to it in duplicateCachedPage for removal after page change - if( to.length ){ - duplicateCachedPage = to; - } - - $.mobile.pageLoading(); - - $.ajax({ - url: fileUrl, - type: type, - data: data, - success: function( html ) { - //pre-parse html to check for a data-url, - //use it as the new fileUrl, base path, etc - var all = $("
"), - redirectLoc, - - //page title regexp - newPageTitle = html.match( /]*>([^<]*)/ ) && RegExp.$1, - - // TODO handle dialogs again - pageElemRegex = new RegExp(".*(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>).*"), - dataUrlRegex = new RegExp("\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?"); - - - // data-url must be provided for the base tag so resource requests can be directed to the - // correct url. loading into a temprorary element makes these requests immediately - if(pageElemRegex.test(html) && RegExp.$1 && dataUrlRegex.test(RegExp.$1) && RegExp.$1) { - redirectLoc = RegExp.$1; - } - - if( redirectLoc ){ - if(base){ - base.set( redirectLoc ); - } - url = fileUrl = path.getFilePath( redirectLoc ); - } - else { - if(base){ - base.set(fileUrl); - } - } - - //workaround to allow scripts to execute when included in page divs - all.get(0).innerHTML = html; - to = all.find( ":jqmData(role='page'), :jqmData(role='dialog')" ).first(); - - //finally, if it's defined now, set the page title for storage in urlHistory - if( newPageTitle ){ - pageTitle = newPageTitle; - } - - //rewrite src and href attrs to use a base url - if( !$.support.dynamicBaseTag ){ - var newPath = path.get( fileUrl ); - to.find( "[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]" ).each(function(){ - var thisAttr = $(this).is('[href]') ? 'href' : 'src', - thisUrl = $(this).attr(thisAttr); - - - //if full path exists and is same, chop it - helps IE out - thisUrl = thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' ); - - if( !/^(\w+:|#|\/)/.test(thisUrl) ){ - $(this).attr(thisAttr, newPath + thisUrl); - } - }); - } - - //append to page and enhance - to - .attr( "data-" + $.mobile.ns + "url", fileUrl ) - .appendTo( $.mobile.pageContainer ); - - enhancePage(); - setTimeout(function() { transitionPages(); }, 0); - }, - error: function() { - - //remove loading message - $.mobile.pageLoading( true ); - - //clear out the active button state - removeActiveLinkClass(true); - - //set base back to current path - if( base ){ - base.set( path.get() ); - } - - //release transition lock so navigation is free again - releasePageTransitionLock(); - - //show error message - $("

"+ $.mobile.pageLoadErrorMessage +"

") - .css({ "display": "block", "opacity": 0.96, "top": $(window).scrollTop() + 100 }) - .appendTo( $.mobile.pageContainer ) - .delay( 800 ) - .fadeOut( 400, function(){ - $(this).remove(); - }); - } - }); - } - - }; - - -/* Event Bindings - hashchange, submit, and click */ - - //bind to form submit events, handle with Ajax - $( "form" ).live('submit', function(event){ - if( !$.mobile.ajaxEnabled || - //TODO: deprecated - remove at 1.0 - !$.mobile.ajaxFormsEnabled || - $(this).is( ":jqmData(ajax='false')" ) ){ return; } - - var type = $(this).attr("method"), - url = path.clean( $(this).attr( "action" ) ), - target = $(this).attr("target"); - - //external submits use regular HTTP - if( path.isExternal( url ) || target ){ - return; - } - - //if it's a relative href, prefix href with base url - if( path.isRelative( url ) ){ - url = path.makeAbsolute( url ); - } - - $.mobile.changePage({ - url: url.length && url || path.get(), - type: type.length && type.toLowerCase() || "get", - data: $(this).serialize() - }, - $(this).jqmData("transition"), - $(this).jqmData("direction"), - true - ); - event.preventDefault(); - }); - - - //temporary fix for allowing 3rd party onclick handlers to still function. - var preventClickDefault = false, stopClickPropagation = false; - - //click routing - direct to HTTP or Ajax, accordingly - $( "a" ).live( "vclick", function(event) { - - var $this = $(this), - - //get href, if defined, otherwise fall to null # - href = $this.attr( "href" ) || "#", - - //cache a check for whether the link had a protocol - //if this is true and the link was same domain, we won't want - //to prefix the url with a base (esp helpful in IE, where every - //url is absolute - hadProtocol = path.hasProtocol( href ), - - //get href, remove same-domain protocol and host - url = path.clean( href ), - - //rel set to external - isRelExternal = $this.is( "[rel='external']" ), - - //rel set to external - isEmbeddedPage = path.isEmbeddedPage( url ), - - // Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR - // requests if the document doing the request was loaded via the file:// protocol. - // This is usually to allow the application to "phone home" and fetch app specific - // data. We normally let the browser handle external/cross-domain urls, but if the - // allowCrossDomainPages option is true, we will allow cross-domain http/https - // requests to go through our page loading logic. - isCrossDomainPageLoad = ($.mobile.allowCrossDomainPages && location.protocol === "file:" && url.search(/^https?:/) != -1), - - //check for protocol or rel and its not an embedded page - //TODO overlap in logic from isExternal, rel=external check should be - // moved into more comprehensive isExternalLink - isExternal = (path.isExternal(url) && !isCrossDomainPageLoad) || (isRelExternal && !isEmbeddedPage), - - //if target attr is specified we mimic _blank... for now - hasTarget = $this.is( "[target]" ), - - //if data-ajax attr is set to false, use the default behavior of a link - hasAjaxDisabled = $this.is( ":jqmData(ajax='false')" ); - - //reset our prevDefault value because I'm paranoid. - preventClickDefault = stopClickPropagation = false; - - //if there's a data-rel=back attr, go back in history - if( $this.is( ":jqmData(rel='back')" ) ){ - window.history.back(); - preventClickDefault = stopClickPropagation = true; - return; - } - - //prevent # urls from bubbling - //path.get() is replaced to combat abs url prefixing in IE - if( url.replace(path.get(), "") == "#" ){ - //for links created purely for interaction - ignore - //don't call preventDefault on the event here, vclick - //may have been triggered by a touchend, before any moues - //click event was dispatched and we want to make sure - //3rd party onclick handlers get triggered. If and when - //a mouse click event is generated, our live("click") handler - //will get triggered and do the preventDefault. - preventClickDefault = true; - return; - } - - $activeClickedLink = $this.closest( ".ui-btn" ).addClass( $.mobile.activeBtnClass ); - - if( isExternal || hasAjaxDisabled || hasTarget || !$.mobile.ajaxEnabled || - // TODO: deprecated - remove at 1.0 - !$.mobile.ajaxLinksEnabled ){ - //remove active link class if external (then it won't be there if you come back) - window.setTimeout(function() {removeActiveLinkClass(true);}, 200); - - //use default click handling - return; - } - - //use ajax - var transition = $this.jqmData( "transition" ), - direction = $this.jqmData("direction"), - reverse = (direction && direction === "reverse") || - // deprecated - remove by 1.0 - $this.jqmData( "back" ); - - //this may need to be more specific as we use data-rel more - nextPageRole = $this.attr( "data-" + $.mobile.ns + "rel" ); - - //if it's a relative href, prefix href with base url - if( path.isRelative( url ) && !hadProtocol ){ - url = path.makeAbsolute( url ); - } - - url = path.stripHash( url ); - - $.mobile.changePage( url, transition, reverse); - preventClickDefault = true; - }); - - $( "a" ).live( "click", function(event) { - if (preventClickDefault){ - event.preventDefault(); - preventClickDefault = false; - } - if (stopClickPropagation){ - event.stopPropagation(); - stopClickPropagation = false; - } - }); - - //hashchange event handler - $window.bind( "hashchange", function( e, triggered ) { - //find first page via hash - var to = path.stripHash( location.hash ), - //transition is false if it's the first page, undefined otherwise (and may be overridden by default) - transition = $.mobile.urlHistory.stack.length === 0 ? false : undefined; - - //if listening is disabled (either globally or temporarily), or it's a dialog hash - if( !$.mobile.hashListeningEnabled || !urlHistory.ignoreNextHashChange ){ - if( !urlHistory.ignoreNextHashChange ){ - urlHistory.ignoreNextHashChange = true; - } - - return; - } - - // special case for dialogs - if( urlHistory.stack.length > 1 && - to.indexOf( dialogHashKey ) > -1 ){ - - // If current active page is not a dialog skip the dialog and continue - // in the same direction - if(!$.mobile.activePage.is( ".ui-dialog" )) { - //determine if we're heading forward or backward and continue accordingly past - //the current dialog - urlHistory.directHashChange({ - currentUrl: to, - isBack: function(){ window.history.back(); }, - isForward: function(){ window.history.forward(); } - }); - - // prevent changepage - return; - } else { - var setTo = function(){ to = $.mobile.urlHistory.getActive().page; }; - // if the current active page is a dialog and we're navigating - // to a dialog use the dialog objected saved in the stack - urlHistory.directHashChange({ currentUrl: to, isBack: setTo, isForward: setTo }); - } - } - - //if to is defined, load it - if ( to ){ - $.mobile.changePage( to, transition, undefined, false, true ); - } - //there's no hash, go to the first page in the dom - else { - $.mobile.changePage( $.mobile.firstPage, transition, true, false, true ); - } - }); - -})( jQuery ); -/* -* jQuery Mobile Framework : "fixHeaderFooter" plugin - on-demand positioning for headers,footers -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.fn.fixHeaderFooter = function(options){ - if( !$.support.scrollTop ){ return this; } - - return this.each(function(){ - var $this = $(this); - - if( $this.jqmData('fullscreen') ){ $this.addClass('ui-page-fullscreen'); } - $this.find( ".ui-header:jqmData(position='fixed')" ).addClass('ui-header-fixed ui-fixed-inline fade'); //should be slidedown - $this.find( ".ui-footer:jqmData(position='fixed')" ).addClass('ui-footer-fixed ui-fixed-inline fade'); //should be slideup - }); -}; - -//single controller for all showing,hiding,toggling -$.fixedToolbars = (function(){ - if( !$.support.scrollTop ){ return; } - var currentstate = 'inline', - autoHideMode = false, - showDelay = 100, - delayTimer, - ignoreTargets = 'a,input,textarea,select,button,label,.ui-header-fixed,.ui-footer-fixed', - toolbarSelector = '.ui-header-fixed:first, .ui-footer-fixed:not(.ui-footer-duplicate):last', - stickyFooter, //for storing quick references to duplicate footers - supportTouch = $.support.touch, - touchStartEvent = supportTouch ? "touchstart" : "mousedown", - touchStopEvent = supportTouch ? "touchend" : "mouseup", - stateBefore = null, - scrollTriggered = false, - touchToggleEnabled = true; - - function showEventCallback(event) - { - // An event that affects the dimensions of the visual viewport has - // been triggered. If the header and/or footer for the current page are in overlay - // mode, we want to hide them, and then fire off a timer to show them at a later - // point. Events like a resize can be triggered continuously during a scroll, on - // some platforms, so the timer is used to delay the actual positioning until the - // flood of events have subsided. - // - // If we are in autoHideMode, we don't do anything because we know the scroll - // callbacks for the plugin will fire off a show when the scrolling has stopped. - if (!autoHideMode && currentstate == 'overlay') { - if (!delayTimer) - $.fixedToolbars.hide(true); - $.fixedToolbars.startShowTimer(); - } - } - - $(function() { - $(document) - .bind( "vmousedown",function(event){ - if( touchToggleEnabled ) { - stateBefore = currentstate; - } - }) - .bind( "vclick",function(event){ - if( touchToggleEnabled ) { - if( $(event.target).closest(ignoreTargets).length ){ return; } - if( !scrollTriggered ){ - $.fixedToolbars.toggle(stateBefore); - stateBefore = null; - } - } - }) - .bind('scrollstart',function(event){ - scrollTriggered = true; - if(stateBefore == null){ stateBefore = currentstate; } - - // We only enter autoHideMode if the headers/footers are in - // an overlay state or the show timer was started. If the - // show timer is set, clear it so the headers/footers don't - // show up until after we're done scrolling. - var isOverlayState = stateBefore == 'overlay'; - autoHideMode = isOverlayState || !!delayTimer; - if (autoHideMode){ - $.fixedToolbars.clearShowTimer(); - if (isOverlayState) { - $.fixedToolbars.hide(true); - } - } - }) - .bind('scrollstop',function(event){ - if( $(event.target).closest(ignoreTargets).length ){ return; } - scrollTriggered = false; - if (autoHideMode) { - autoHideMode = false; - $.fixedToolbars.startShowTimer(); - } - stateBefore = null; - }) - .bind('silentscroll', showEventCallback); - - $(window).bind('resize', showEventCallback); - }); - - //before page is shown, check for duplicate footer - $('.ui-page').live('pagebeforeshow', function(event, ui){ - var page = $(event.target), - footer = page.find( ":jqmData(role='footer')" ), - id = footer.data('id'), - prevPage = ui.prevPage; - - prevFooter = prevPage && prevPage.find( ":jqmData(role='footer')" ); - var prevFooterMatches = prevFooter.jqmData( "id" ) === id; - - if( id && prevFooterMatches ){ - stickyFooter = footer; - setTop( stickyFooter.removeClass( "fade in out" ).appendTo( $.mobile.pageContainer ) ); - } - }); - - //after page is shown, append footer to new page - $('.ui-page').live('pageshow', function(event, ui){ - var $this = $(this); - - if( stickyFooter && stickyFooter.length ){ - - setTimeout(function(){ - setTop( stickyFooter.appendTo( $this ).addClass("fade") ); - stickyFooter = null; - }, 500); - } - - $.fixedToolbars.show(true, this); - }); - - - // element.getBoundingClientRect() is broken in iOS 3.2.1 on the iPad. The - // coordinates inside of the rect it returns don't have the page scroll position - // factored out of it like the other platforms do. To get around this, - // we'll just calculate the top offset the old fashioned way until core has - // a chance to figure out how to handle this situation. - // - // TODO: We'll need to get rid of getOffsetTop() once a fix gets folded into core. - - function getOffsetTop(ele) - { - var top = 0; - if (ele) - { - var op = ele.offsetParent, body = document.body; - top = ele.offsetTop; - while (ele && ele != body) - { - top += ele.scrollTop || 0; - if (ele == op) - { - top += op.offsetTop; - op = ele.offsetParent; - } - ele = ele.parentNode; - } - } - return top; - } - - function setTop(el){ - var fromTop = $(window).scrollTop(), - thisTop = getOffsetTop(el[0]), // el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead. - thisCSStop = el.css('top') == 'auto' ? 0 : parseFloat(el.css('top')), - screenHeight = window.innerHeight, - thisHeight = el.outerHeight(), - useRelative = el.parents('.ui-page:not(.ui-page-fullscreen)').length, - relval; - if( el.is('.ui-header-fixed') ){ - relval = fromTop - thisTop + thisCSStop; - if( relval < thisTop){ relval = 0; } - return el.css('top', ( useRelative ) ? relval : fromTop); - } - else{ - //relval = -1 * (thisTop - (fromTop + screenHeight) + thisCSStop + thisHeight); - //if( relval > thisTop ){ relval = 0; } - relval = fromTop + screenHeight - thisHeight - (thisTop - thisCSStop); - return el.css('top', ( useRelative ) ? relval : fromTop + screenHeight - thisHeight ); - } - } - - //exposed methods - return { - show: function(immediately, page){ - $.fixedToolbars.clearShowTimer(); - currentstate = 'overlay'; - var $ap = page ? $(page) : ($.mobile.activePage ? $.mobile.activePage : $(".ui-page-active")); - return $ap.children( toolbarSelector ).each(function(){ - var el = $(this), - fromTop = $(window).scrollTop(), - thisTop = getOffsetTop(el[0]), // el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead. - screenHeight = window.innerHeight, - thisHeight = el.outerHeight(), - alreadyVisible = (el.is('.ui-header-fixed') && fromTop <= thisTop + thisHeight) || (el.is('.ui-footer-fixed') && thisTop <= fromTop + screenHeight); - - //add state class - el.addClass('ui-fixed-overlay').removeClass('ui-fixed-inline'); - - if( !alreadyVisible && !immediately ){ - el.animationComplete(function(){ - el.removeClass('in'); - }).addClass('in'); - } - setTop(el); - }); - }, - hide: function(immediately){ - currentstate = 'inline'; - var $ap = $.mobile.activePage ? $.mobile.activePage : $(".ui-page-active"); - return $ap.children( toolbarSelector ).each(function(){ - var el = $(this); - - var thisCSStop = el.css('top'); thisCSStop = thisCSStop == 'auto' ? 0 : parseFloat(thisCSStop); - - //add state class - el.addClass('ui-fixed-inline').removeClass('ui-fixed-overlay'); - - if (thisCSStop < 0 || (el.is('.ui-header-fixed') && thisCSStop != 0)) - { - if(immediately){ - el.css('top',0); - } - else{ - if( el.css('top') !== 'auto' && parseFloat(el.css('top')) !== 0 ){ - var classes = 'out reverse'; - el.animationComplete(function(){ - el.removeClass(classes); - el.css('top',0); - }).addClass(classes); - } - } - } - }); - }, - startShowTimer: function(){ - $.fixedToolbars.clearShowTimer(); - var args = $.makeArray(arguments); - delayTimer = setTimeout(function(){ - delayTimer = undefined; - $.fixedToolbars.show.apply(null, args); - }, showDelay); - }, - clearShowTimer: function() { - if (delayTimer) { - clearTimeout(delayTimer); - } - delayTimer = undefined; - }, - toggle: function(from){ - if(from){ currentstate = from; } - return (currentstate == 'overlay') ? $.fixedToolbars.hide() : $.fixedToolbars.show(); - }, - setTouchToggleEnabled: function(enabled) { - touchToggleEnabled = enabled; - } - }; -})(); - -})(jQuery); -/* -* jQuery Mobile Framework : "checkboxradio" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.checkboxradio", $.mobile.widget, { - options: { - theme: null - }, - _create: function(){ - var self = this, - input = this.element, - //NOTE: Windows Phone could not find the label through a selector - //filter works though. - label = input.closest("form,fieldset,:jqmData(role='page')").find("label").filter("[for=" + input[0].id + "]"), - inputtype = input.attr( "type" ), - checkedicon = "ui-icon-" + inputtype + "-on", - uncheckedicon = "ui-icon-" + inputtype + "-off"; - - if ( inputtype != "checkbox" && inputtype != "radio" ) { return; } - - //expose for other methods - $.extend( this,{ - label : label, - inputtype : inputtype, - checkedicon : checkedicon, - uncheckedicon : uncheckedicon - }); - - // If there's no selected theme... - if( !this.options.theme ) { - this.options.theme = this.element.jqmData( "theme" ); - } - - label - .buttonMarkup({ - theme: this.options.theme, - icon: this.element.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedicon, - shadow: false - }); - - // wrap the input + label in a div - input - .add( label ) - .wrapAll( "
" ); - - label.bind({ - vmouseover: function() { - if( $(this).parent().is('.ui-disabled') ){ return false; } - }, - - vclick: function( event ){ - if ( input.is( ":disabled" ) ){ - event.preventDefault(); - return; - } - - self._cacheVals(); - input.attr( "checked", inputtype === "radio" && true || !input.is( ":checked" ) ); - self._updateAll(); - return false; - } - - }); - - input - .bind({ - vmousedown: function(){ - this._cacheVals(); - }, - - vclick: function(){ - self._updateAll(); - }, - - focus: function() { - label.addClass( "ui-focus" ); - }, - - blur: function() { - label.removeClass( "ui-focus" ); - } - }); - - this.refresh(); - - }, - - _cacheVals: function(){ - this._getInputSet().each(function(){ - $(this).jqmData("cacheVal", $(this).is(":checked") ); - }); - }, - - //returns either a set of radios with the same name attribute, or a single checkbox - _getInputSet: function(){ - return this.element.closest( "form,fieldset,:jqmData(role='page')" ) - .find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.inputtype +"']" ); - }, - - _updateAll: function(){ - this._getInputSet().each(function(){ - if( $(this).is(":checked") || this.inputtype === "checkbox" ){ - $(this).trigger("change"); - } - }) - .checkboxradio( "refresh" ); - }, - - refresh: function( ){ - var input = this.element, - label = this.label, - icon = label.find( ".ui-icon" ); - - if ( input[0].checked ) { - label.addClass( $.mobile.activeBtnClass ); - icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon ); - - } else { - label.removeClass( $.mobile.activeBtnClass ); - icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon ); - } - - if( input.is( ":disabled" ) ){ - this.disable(); - } - else { - this.enable(); - } - }, - - disable: function(){ - this.element.attr("disabled",true).parent().addClass("ui-disabled"); - }, - - enable: function(){ - this.element.attr("disabled",false).parent().removeClass("ui-disabled"); - } -}); -})( jQuery ); -/* -* jQuery Mobile Framework : "textinput" plugin for text inputs, textareas -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.textinput", $.mobile.widget, { - options: { - theme: null - }, - _create: function(){ - var input = this.element, - o = this.options, - theme = o.theme, - themeclass; - - if ( !theme ) { - var themedParent = this.element.closest("[class*='ui-bar-'],[class*='ui-body-']"); - theme = themedParent.length ? - /ui-(bar|body)-([a-z])/.exec( themedParent.attr("class") )[2] : - "c"; - } - - themeclass = " ui-body-" + theme; - - $('label[for='+input.attr('id')+']').addClass('ui-input-text'); - - input.addClass('ui-input-text ui-body-'+ o.theme); - - var focusedEl = input; - - //"search" input widget - if( input.is( "[type='search'],:jqmData(type='search')" ) ){ - focusedEl = input.wrap('').parent(); - var clearbtn = $('clear text') - .tap(function( e ){ - input.val('').focus(); - input.trigger('change'); - clearbtn.addClass('ui-input-clear-hidden'); - e.preventDefault(); - }) - .appendTo(focusedEl) - .buttonMarkup({icon: 'delete', iconpos: 'notext', corners:true, shadow:true}); - - function toggleClear(){ - if(input.val() == ''){ - clearbtn.addClass('ui-input-clear-hidden'); - } - else{ - clearbtn.removeClass('ui-input-clear-hidden'); - } - } - - toggleClear(); - input.keyup(toggleClear); - } - else{ - input.addClass('ui-corner-all ui-shadow-inset' + themeclass); - } - - input - .focus(function(){ - focusedEl.addClass('ui-focus'); - }) - .blur(function(){ - focusedEl.removeClass('ui-focus'); - }); - - //autogrow - if ( input.is('textarea') ) { - var extraLineHeight = 15, - keyupTimeoutBuffer = 100, - keyup = function() { - var scrollHeight = input[0].scrollHeight, - clientHeight = input[0].clientHeight; - if ( clientHeight < scrollHeight ) { - input.css({ height: (scrollHeight + extraLineHeight) }); - } - }, - keyupTimeout; - input.keyup(function() { - clearTimeout( keyupTimeout ); - keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer ); - }); - } - }, - - disable: function(){ - ( this.element.attr("disabled",true).is( "[type='search'],:jqmData(type='search')" ) ? this.element.parent() : this.element ).addClass("ui-disabled"); - }, - - enable: function(){ - ( this.element.attr("disabled", false).is( "[type='search'],:jqmData(type='search')" ) ? this.element.parent() : this.element ).removeClass("ui-disabled"); - } -}); -})( jQuery ); -/* -* jQuery Mobile Framework : "selectmenu" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.selectmenu", $.mobile.widget, { - options: { - theme: null, - disabled: false, - icon: 'arrow-d', - iconpos: 'right', - inline: null, - corners: true, - shadow: true, - iconshadow: true, - menuPageTheme: 'b', - overlayTheme: 'a', - hidePlaceholderMenuItems: true, - closeText: 'Close', - nativeMenu: true - }, - _create: function(){ - - var self = this, - - o = this.options, - - select = this.element - .wrap( "
" ), - - selectID = select.attr( "id" ), - - label = $( "label[for="+ selectID +"]" ).addClass( "ui-select" ), - - //IE throws an exception at options.item() function when - //there is no selected item - //select first in this case - selectedIndex = select[0].selectedIndex == -1 ? 0 : select[0].selectedIndex, - - button = ( self.options.nativeMenu ? $( "
" ) : $( "", { - "href": "#", - "role": "button", - "id": buttonId, - "aria-haspopup": "true", - "aria-owns": menuId - }) ) - .text( $( select[0].options.item( selectedIndex ) ).text() ) - .insertBefore( select ) - .buttonMarkup({ - theme: o.theme, - icon: o.icon, - iconpos: o.iconpos, - inline: o.inline, - corners: o.corners, - shadow: o.shadow, - iconshadow: o.iconshadow - }), - - //multi select or not - isMultiple = self.isMultiple = select[0].multiple; - - //Opera does not properly support opacity on select elements - //In Mini, it hides the element, but not its text - //On the desktop,it seems to do the opposite - //for these reasons, using the nativeMenu option results in a full native select in Opera - if( o.nativeMenu && window.opera && window.opera.version ){ - select.addClass( "ui-select-nativeonly" ); - } - - //vars for non-native menus - if( !o.nativeMenu ){ - var options = select.find("option"), - - buttonId = selectID + "-button", - - menuId = selectID + "-menu", - - thisPage = select.closest( ".ui-page" ), - - //button theme - theme = /ui-btn-up-([a-z])/.exec( button.attr("class") )[1], - - menuPage = $( "
" + - "
" + - "
" + label.text() + "
"+ - "
"+ - "
"+ - "
" ) - .appendTo( $.mobile.pageContainer ) - .page(), - - menuPageContent = menuPage.find( ".ui-content" ), - - menuPageClose = menuPage.find( ".ui-header a" ), - - screen = $( "
", {"class": "ui-selectmenu-screen ui-screen-hidden"}) - .appendTo( thisPage ), - - listbox = $( "
", { "class": "ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all pop ui-body-" + o.overlayTheme } ) - .insertAfter(screen), - - list = $( "
    ", { - "class": "ui-selectmenu-list", - "id": menuId, - "role": "listbox", - "aria-labelledby": buttonId - }) - .attr( "data-" + $.mobile.ns + "theme", theme ) - .appendTo( listbox ), - - header = $( "
    ", { - "class": "ui-header ui-bar-" + theme - }) - .prependTo( listbox ), - - headerTitle = $( "

    ", { - "class": "ui-title" - }) - .appendTo( header ), - - headerClose = $( "", { - "text": o.closeText, - "href": "#", - "class": "ui-btn-left" - }) - .attr( "data-" + $.mobile.ns + "iconpos", "notext" ) - .attr( "data-" + $.mobile.ns + "icon", "delete" ) - .appendTo( header ) - .buttonMarkup(), - - menuType; - } //end non native vars - - // add counter for multi selects - if( isMultiple ){ - self.buttonCount = $('') - .addClass( 'ui-li-count ui-btn-up-c ui-btn-corner-all' ) - .hide() - .appendTo( button ); - } - - //disable if specified - if( o.disabled ){ this.disable(); } - - //events on native select - select - .change(function(){ - self.refresh(); - }); - - //expose to other methods - $.extend(self, { - select: select, - optionElems: options, - selectID: selectID, - label: label, - buttonId:buttonId, - menuId:menuId, - thisPage:thisPage, - button:button, - menuPage:menuPage, - menuPageContent:menuPageContent, - screen:screen, - listbox:listbox, - list:list, - menuType:menuType, - header:header, - headerClose:headerClose, - headerTitle:headerTitle, - placeholder: '' - }); - - //support for using the native select menu with a custom button - if( o.nativeMenu ){ - - select - .appendTo(button) - .bind( "vmousedown", function( e ){ - //add active class to button - button.addClass( $.mobile.activeBtnClass ); - }) - .bind( "focus vmouseover", function(){ - button.trigger( "vmouseover" ); - }) - .bind( "vmousemove", function(){ - //remove active class on scroll/touchmove - button.removeClass( $.mobile.activeBtnClass ); - }) - .bind( "change blur vmouseout", function(){ - button - .trigger( "vmouseout" ) - .removeClass( $.mobile.activeBtnClass ); - }); - - - } else { - - //create list from select, update state - self.refresh(); - - select - .attr( "tabindex", "-1" ) - .focus(function(){ - $(this).blur(); - button.focus(); - }); - - //button events - button - .bind( "vclick keydown" , function( event ){ - if( event.type == "vclick" || - event.keyCode && ( event.keyCode === $.mobile.keyCode.ENTER || event.keyCode === $.mobile.keyCode.SPACE ) ){ - self.open(); - event.preventDefault(); - } - }); - - //events for list items - list - .attr( "role", "listbox" ) - .delegate( ".ui-li>a", "focusin", function() { - $( this ).attr( "tabindex", "0" ); - }) - .delegate( ".ui-li>a", "focusout", function() { - $( this ).attr( "tabindex", "-1" ); - }) - .delegate("li:not(.ui-disabled, .ui-li-divider)", "vclick", function(event){ - - // index of option tag to be selected - var oldIndex = select[0].selectedIndex, - newIndex = list.find( "li:not(.ui-li-divider)" ).index( this ), - option = self.optionElems.eq( newIndex )[0]; - - // toggle selected status on the tag for multi selects - option.selected = isMultiple ? !option.selected : true; - - // toggle checkbox class for multiple selects - if( isMultiple ){ - $(this) - .find('.ui-icon') - .toggleClass('ui-icon-checkbox-on', option.selected) - .toggleClass('ui-icon-checkbox-off', !option.selected); - } - - // trigger change if value changed - if( oldIndex !== newIndex ){ - select.trigger( "change" ); - } - - //hide custom select for single selects only - if( !isMultiple ){ - self.close(); - } - - event.preventDefault(); - }) - //keyboard events for menu items - .keydown(function( e ) { - var target = $( e.target ), - li = target.closest( "li" ); - - // switch logic based on which key was pressed - switch ( e.keyCode ) { - // up or left arrow keys - case 38: - var prev = li.prev(); - - // if there's a previous option, focus it - if ( prev.length ) { - target - .blur() - .attr( "tabindex", "-1" ); - - prev.find( "a" ).first().focus(); - } - - return false; - break; - - // down or right arrow keys - case 40: - var next = li.next(); - - // if there's a next option, focus it - if ( next.length ) { - target - .blur() - .attr( "tabindex", "-1" ); - - next.find( "a" ).first().focus(); - } - - return false; - break; - - // if enter or space is pressed, trigger click - case 13: - case 32: - target.trigger( "vclick" ); - - return false; - break; - } - }); - - //events on "screen" overlay - screen.bind("vclick", function( event ){ - self.close(); - }); - - //close button on small overlays - self.headerClose.click(function(){ - if( self.menuType == "overlay" ){ - self.close(); - return false; - } - }) - } - }, - - _buildList: function(){ - var self = this, - o = this.options, - placeholder = this.placeholder, - optgroups = [], - lis = [], - dataIcon = self.isMultiple ? "checkbox-off" : "false"; - - self.list.empty().filter('.ui-listview').listview('destroy'); - - //populate menu with options from select element - self.select.find( "option" ).each(function( i ){ - var $this = $(this), - $parent = $this.parent(), - text = $this.text(), - anchor = ""+ text +"", - classes = [], - extraAttrs = []; - - // are we inside an optgroup? - if( $parent.is("optgroup") ){ - var optLabel = $parent.attr("label"); - - // has this optgroup already been built yet? - if( $.inArray(optLabel, optgroups) === -1 ){ - lis.push( "
  • "+ optLabel +"
  • " ); - optgroups.push( optLabel ); - } - } - - //find placeholder text - if( !this.getAttribute('value') || text.length == 0 || $this.jqmData('placeholder') ){ - if( o.hidePlaceholderMenuItems ){ - classes.push( "ui-selectmenu-placeholder" ); - } - placeholder = self.placeholder = text; - } - - // support disabled option tags - if( this.disabled ){ - classes.push( "ui-disabled" ); - extraAttrs.push( "aria-disabled='true'" ); - } - - lis.push( "
  • "+ anchor +"
  • " ) - }); - - self.list.html( lis.join(" ") ); - - self.list.find( "li" ) - .attr({ "role": "option", "tabindex": "-1" }) - .first().attr( "tabindex", "0" ); - - // hide header close link for single selects - if( !this.isMultiple ){ - this.headerClose.hide(); - } - - // hide header if it's not a multiselect and there's no placeholder - if( !this.isMultiple && !placeholder.length ){ - this.header.hide(); - } else { - this.headerTitle.text( this.placeholder ); - } - - //now populated, create listview - self.list.listview(); - }, - - refresh: function( forceRebuild ){ - var self = this, - select = this.element, - isMultiple = this.isMultiple, - options = this.optionElems = select.find("option"), - selected = options.filter(":selected"), - - // return an array of all selected index's - indicies = selected.map(function(){ - return options.index( this ); - }).get(); - - if( !self.options.nativeMenu && ( forceRebuild || select[0].options.length != self.list.find('li').length )){ - self._buildList(); - } - - self.button - .find( ".ui-btn-text" ) - .text(function(){ - if( !isMultiple ){ - return selected.text(); - } - - return selected.length ? - selected.map(function(){ return $(this).text(); }).get().join(', ') : - self.placeholder; - }); - - // multiple count inside button - if( isMultiple ){ - self.buttonCount[ selected.length > 1 ? 'show' : 'hide' ]().text( selected.length ); - } - - if( !self.options.nativeMenu ){ - self.list - .find( 'li:not(.ui-li-divider)' ) - .removeClass( $.mobile.activeBtnClass ) - .attr( 'aria-selected', false ) - .each(function( i ){ - if( $.inArray(i, indicies) > -1 ){ - var item = $(this).addClass( $.mobile.activeBtnClass ); - - // aria selected attr - item.find( 'a' ).attr( 'aria-selected', true ); - - // multiple selects: add the "on" checkbox state to the icon - if( isMultiple ){ - item.find('.ui-icon').removeClass('ui-icon-checkbox-off').addClass('ui-icon-checkbox-on'); - } - } - }); - } - }, - - open: function(){ - if( this.options.disabled || this.options.nativeMenu ){ return; } - - var self = this, - menuHeight = self.list.parent().outerHeight(), - menuWidth = self.list.parent().outerWidth(), - scrollTop = $(window).scrollTop(), - btnOffset = self.button.offset().top, - screenHeight = window.innerHeight, - screenWidth = window.innerWidth; - - //add active class to button - self.button.addClass( $.mobile.activeBtnClass ); - - //remove after delay - setTimeout(function(){ - self.button.removeClass( $.mobile.activeBtnClass ); - }, 300); - - function focusMenuItem(){ - self.list.find( ".ui-btn-active" ).focus(); - } - - if( menuHeight > screenHeight - 80 || !$.support.scrollTop ){ - - //for webos (set lastscroll using button offset) - if( scrollTop == 0 && btnOffset > screenHeight ){ - self.thisPage.one('pagehide',function(){ - $(this).jqmData('lastScroll', btnOffset); - }); - } - - self.menuPage.one('pageshow', function() { - // silentScroll() is called whenever a page is shown to restore - // any previous scroll position the page may have had. We need to - // wait for the "silentscroll" event before setting focus to avoid - // the browser's "feature" which offsets rendering to make sure - // whatever has focus is in view. - $(window).one("silentscroll", function(){ focusMenuItem(); }); - }); - - self.menuType = "page"; - self.menuPageContent.append( self.list ); - $.mobile.changePage(self.menuPage, 'pop', false, true); - } - else { - self.menuType = "overlay"; - - self.screen - .height( $(document).height() ) - .removeClass('ui-screen-hidden'); - - //try and center the overlay over the button - var roomtop = btnOffset - scrollTop, - roombot = scrollTop + screenHeight - btnOffset, - halfheight = menuHeight / 2, - maxwidth = parseFloat(self.list.parent().css('max-width')), - newtop, newleft; - - if( roomtop > menuHeight / 2 && roombot > menuHeight / 2 ){ - newtop = btnOffset + ( self.button.outerHeight() / 2 ) - halfheight; - } - else{ - //30px tolerance off the edges - newtop = roomtop > roombot ? scrollTop + screenHeight - menuHeight - 30 : scrollTop + 30; - } - - // if the menuwidth is smaller than the screen center is - if (menuWidth < maxwidth) { - newleft = (screenWidth - menuWidth) / 2; - } else { //otherwise insure a >= 30px offset from the left - newleft = self.button.offset().left + self.button.outerWidth() / 2 - menuWidth / 2; - // 30px tolerance off the edges - if (newleft < 30) { - newleft = 30; - } else if ((newleft + menuWidth) > screenWidth) { - newleft = screenWidth - menuWidth - 30; - } - } - - self.listbox - .append( self.list ) - .removeClass( "ui-selectmenu-hidden" ) - .css({ - top: newtop, - left: newleft - }) - .addClass("in"); - - focusMenuItem(); - } - - // wait before the dialog can be closed - setTimeout(function(){ - self.isOpen = true; - }, 400); - }, - - close: function(){ - if( this.options.disabled || !this.isOpen || this.options.nativeMenu ){ return; } - var self = this; - - function focusButton(){ - setTimeout(function(){ - self.button.focus(); - }, 40); - - self.listbox.removeAttr('style').append( self.list ); - } - - if(self.menuType == "page"){ - $.mobile.changePage([self.menuPage,self.thisPage], 'pop', true, false); - self.menuPage.one("pagehide", focusButton); - } - else{ - self.screen.addClass( "ui-screen-hidden" ); - self.listbox.addClass( "ui-selectmenu-hidden" ).removeAttr( "style" ).removeClass("in"); - focusButton(); - } - - // allow the dialog to be closed again - this.isOpen = false; - }, - - disable: function(){ - this.element.attr("disabled",true); - this.button.addClass('ui-disabled').attr("aria-disabled", true); - return this._setOption( "disabled", true ); - }, - - enable: function(){ - this.element.attr("disabled",false); - this.button.removeClass('ui-disabled').attr("aria-disabled", false); - return this._setOption( "disabled", false ); - } -}); -})( jQuery ); - -/* -* jQuery Mobile Framework : plugin for making button-like links -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { - -$.fn.buttonMarkup = function( options ){ - return this.each( function() { - var el = $( this ), - o = $.extend( {}, $.fn.buttonMarkup.defaults, el.jqmData(), options), - - // Classes Defined - buttonClass, - innerClass = "ui-btn-inner", - iconClass; - - if ( attachEvents ) { - attachEvents(); - } - - // if not, try to find closest theme container - if ( !o.theme ) { - var themedParent = el.closest("[class*='ui-bar-'],[class*='ui-body-']"); - o.theme = themedParent.length ? - /ui-(bar|body)-([a-z])/.exec( themedParent.attr("class") )[2] : - "c"; - } - - buttonClass = "ui-btn ui-btn-up-" + o.theme; - - if ( o.inline ) { - buttonClass += " ui-btn-inline"; - } - - if ( o.icon ) { - o.icon = "ui-icon-" + o.icon; - o.iconpos = o.iconpos || "left"; - - iconClass = "ui-icon " + o.icon; - - if ( o.shadow ) { - iconClass += " ui-icon-shadow"; - } - } - - if ( o.iconpos ) { - buttonClass += " ui-btn-icon-" + o.iconpos; - - if ( o.iconpos == "notext" && !el.attr("title") ) { - el.attr( "title", el.text() ); - } - } - - if ( o.corners ) { - buttonClass += " ui-btn-corner-all"; - innerClass += " ui-btn-corner-all"; - } - - if ( o.shadow ) { - buttonClass += " ui-shadow"; - } - - el - .attr( "data-" + $.mobile.ns + "theme", o.theme ) - .addClass( buttonClass ); - - var wrap = ("" + - ( o.icon ? "" : "" ) + - "").replace(/D/g, o.wrapperEls); - - el.wrapInner( wrap ); - }); -}; - -$.fn.buttonMarkup.defaults = { - corners: true, - shadow: true, - iconshadow: true, - wrapperEls: "span" -}; - -var attachEvents = function() { - $(".ui-btn:not(.ui-disabled)").live({ - "vmousedown": function() { - var theme = $(this).attr( "data-" + $.mobile.ns + "theme" ); - $(this).removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme ); - }, - "vmousecancel vmouseup": function() { - var theme = $(this).attr( "data-" + $.mobile.ns + "theme" ); - $(this).removeClass( "ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme ); - }, - "vmouseover focus": function() { - var theme = $(this).attr( "data-" + $.mobile.ns + "theme" ); - $(this).removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme ); - }, - "vmouseout blur": function() { - var theme = $(this).attr( "data-" + $.mobile.ns + "theme" ); - $(this).removeClass( "ui-btn-hover-" + theme ).addClass( "ui-btn-up-" + theme ); - } - }); - - attachEvents = null; -}; - -})(jQuery); -/* -* jQuery Mobile Framework : "button" plugin - links that proxy to native input/buttons -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.button", $.mobile.widget, { - options: { - theme: null, - icon: null, - iconpos: null, - inline: null, - corners: true, - shadow: true, - iconshadow: true - }, - _create: function(){ - var $el = this.element, - o = this.options; - - //add ARIA role - this.button = $( "
    " ) - .text( $el.text() || $el.val() ) - .buttonMarkup({ - theme: o.theme, - icon: o.icon, - iconpos: o.iconpos, - inline: o.inline, - corners: o.corners, - shadow: o.shadow, - iconshadow: o.iconshadow - }) - .insertBefore( $el ) - .append( $el.addClass('ui-btn-hidden') ); - - //add hidden input during submit - var type = $el.attr('type'); - if( type !== 'button' && type !== 'reset' ){ - $el.bind("vclick", function(){ - var $buttonPlaceholder = $("", - {type: "hidden", name: $el.attr("name"), value: $el.attr("value")}) - .insertBefore($el); - - //bind to doc to remove after submit handling - $(document).submit(function(){ - $buttonPlaceholder.remove(); - }); - }); - } - this.refresh(); - - }, - - enable: function(){ - this.element.attr("disabled", false); - this.button.removeClass("ui-disabled").attr("aria-disabled", false); - return this._setOption("disabled", false); - }, - - disable: function(){ - this.element.attr("disabled", true); - this.button.addClass("ui-disabled").attr("aria-disabled", true); - return this._setOption("disabled", true); - }, - - refresh: function(){ - if( this.element.attr('disabled') ){ - this.disable(); - } - else{ - this.enable(); - } - } -}); -})( jQuery );/* -* jQuery Mobile Framework : "slider" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.slider", $.mobile.widget, { - options: { - theme: null, - trackTheme: null, - disabled: false - }, - _create: function(){ - var self = this, - - control = this.element, - - parentTheme = control.parents('[class*=ui-bar-],[class*=ui-body-]').eq(0), - - parentTheme = parentTheme.length ? parentTheme.attr('class').match(/ui-(bar|body)-([a-z])/)[2] : 'c', - - theme = this.options.theme ? this.options.theme : parentTheme, - - trackTheme = this.options.trackTheme ? this.options.trackTheme : parentTheme, - - cType = control[0].nodeName.toLowerCase(), - selectClass = (cType == 'select') ? 'ui-slider-switch' : '', - controlID = control.attr('id'), - labelID = controlID + '-label', - label = $('[for='+ controlID +']').attr('id',labelID), - val = function(){ - return (cType == 'input') ? parseFloat(control.val()) : control[0].selectedIndex; - }, - min = (cType == 'input') ? parseFloat(control.attr('min')) : 0, - max = (cType == 'input') ? parseFloat(control.attr('max')) : control.find('option').length-1, - step = window.parseFloat(control.attr('step') || 1), - slider = $('
    '), - handle = $('') - .appendTo(slider) - .buttonMarkup({corners: true, theme: theme, shadow: true}) - .attr({ - 'role': 'slider', - 'aria-valuemin': min, - 'aria-valuemax': max, - 'aria-valuenow': val(), - 'aria-valuetext': val(), - 'title': val(), - 'aria-labelledby': labelID - }); - - $.extend(this, { - slider: slider, - handle: handle, - dragging: false, - beforeStart: null - }); - - if(cType == 'select'){ - slider.wrapInner('
    '); - var options = control.find('option'); - - control.find('option').each(function(i){ - var side = (i==0) ?'b':'a', - corners = (i==0) ? 'right' :'left', - theme = (i==0) ? ' ui-btn-down-' + trackTheme :' ui-btn-active'; - $('
    ').prependTo(slider); - $(''+$(this).text()+'').prependTo(handle); - }); - - } - - label.addClass('ui-slider'); - - // monitor the input for updated values - control - .addClass((cType == 'input') ? 'ui-slider-input' : 'ui-slider-switch') - .change(function(){ - self.refresh( val(), true ); - }) - .keyup(function(){ // necessary? - self.refresh( val(), true, true ); - }) - .blur(function(){ - self.refresh( val(), true ); - }); - - // prevent screen drag when slider activated - $(document).bind( "vmousemove", function(event){ - if ( self.dragging ) { - self.refresh( event ); - return false; - } - }); - - slider - .bind( "vmousedown", function(event){ - self.dragging = true; - if ( cType === "select" ) { - self.beforeStart = control[0].selectedIndex; - } - self.refresh( event ); - return false; - }); - - slider - .add(document) - .bind( "vmouseup", function(){ - if ( self.dragging ) { - self.dragging = false; - if ( cType === "select" ) { - if ( self.beforeStart === control[0].selectedIndex ) { - //tap occurred, but value didn't change. flip it! - self.refresh( self.beforeStart === 0 ? 1 : 0 ); - } - var curval = val(); - var snapped = Math.round( curval / (max - min) * 100 ); - handle - .addClass("ui-slider-handle-snapping") - .css("left", snapped + "%") - .animationComplete(function(){ - handle.removeClass("ui-slider-handle-snapping"); - }); - } - return false; - } - }); - - slider.insertAfter(control); - - // NOTE force focus on handle - this.handle - .bind( "vmousedown", function(){ - $(this).focus(); - }); - - this.handle - .bind( "keydown", function( event ) { - var index = val(); - - if ( self.options.disabled ) { - return; - } - - // In all cases prevent the default and mark the handle as active - switch ( event.keyCode ) { - case $.mobile.keyCode.HOME: - case $.mobile.keyCode.END: - case $.mobile.keyCode.PAGE_UP: - case $.mobile.keyCode.PAGE_DOWN: - case $.mobile.keyCode.UP: - case $.mobile.keyCode.RIGHT: - case $.mobile.keyCode.DOWN: - case $.mobile.keyCode.LEFT: - event.preventDefault(); - - if ( !self._keySliding ) { - self._keySliding = true; - $( this ).addClass( "ui-state-active" ); - } - break; - } - - // move the slider according to the keypress - switch ( event.keyCode ) { - case $.mobile.keyCode.HOME: - self.refresh(min); - break; - case $.mobile.keyCode.END: - self.refresh(max); - break; - case $.mobile.keyCode.PAGE_UP: - case $.mobile.keyCode.UP: - case $.mobile.keyCode.RIGHT: - self.refresh(index + step); - break; - case $.mobile.keyCode.PAGE_DOWN: - case $.mobile.keyCode.DOWN: - case $.mobile.keyCode.LEFT: - self.refresh(index - step); - break; - } - }) // remove active mark - .keyup(function( event ) { - if ( self._keySliding ) { - self._keySliding = false; - $( this ).removeClass( "ui-state-active" ); - } - }); - - this.refresh(); - }, - - refresh: function(val, isfromControl, preventInputUpdate){ - if ( this.options.disabled ) { return; } - - var control = this.element, percent, - cType = control[0].nodeName.toLowerCase(), - min = (cType === "input") ? parseFloat(control.attr("min")) : 0, - max = (cType === "input") ? parseFloat(control.attr("max")) : control.find("option").length - 1; - - if ( typeof val === "object" ) { - var data = val, - // a slight tolerance helped get to the ends of the slider - tol = 8; - if ( !this.dragging - || data.pageX < this.slider.offset().left - tol - || data.pageX > this.slider.offset().left + this.slider.width() + tol ) { - return; - } - percent = Math.round( ((data.pageX - this.slider.offset().left) / this.slider.width() ) * 100 ); - } else { - if ( val == null ) { - val = (cType === "input") ? parseFloat(control.val()) : control[0].selectedIndex; - } - percent = (parseFloat(val) - min) / (max - min) * 100; - } - - if ( isNaN(percent) ) { return; } - if ( percent < 0 ) { percent = 0; } - if ( percent > 100 ) { percent = 100; } - - var newval = Math.round( (percent / 100) * (max - min) ) + min; - if ( newval < min ) { newval = min; } - if ( newval > max ) { newval = max; } - - //flip the stack of the bg colors - if ( percent > 60 && cType === "select" ) { - - } - this.handle.css("left", percent + "%"); - this.handle.attr({ - "aria-valuenow": (cType === "input") ? newval : control.find("option").eq(newval).attr("value"), - "aria-valuetext": (cType === "input") ? newval : control.find("option").eq(newval).text(), - title: newval - }); - - // add/remove classes for flip toggle switch - if ( cType === "select" ) { - if ( newval === 0 ) { - this.slider.addClass("ui-slider-switch-a") - .removeClass("ui-slider-switch-b"); - } else { - this.slider.addClass("ui-slider-switch-b") - .removeClass("ui-slider-switch-a"); - } - } - - if(!preventInputUpdate){ - // update control's value - if ( cType === "input" ) { - control.val(newval); - } else { - control[ 0 ].selectedIndex = newval; - } - if (!isfromControl) { control.trigger("change"); } - } - }, - - enable: function(){ - this.element.attr("disabled", false); - this.slider.removeClass("ui-disabled").attr("aria-disabled", false); - return this._setOption("disabled", false); - }, - - disable: function(){ - this.element.attr("disabled", true); - this.slider.addClass("ui-disabled").attr("aria-disabled", true); - return this._setOption("disabled", true); - } - -}); -})( jQuery ); - -/* -* jQuery Mobile Framework : "collapsible" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.collapsible", $.mobile.widget, { - options: { - expandCueText: ' click to expand contents', - collapseCueText: ' click to collapse contents', - collapsed: false, - heading: '>:header,>legend', - theme: null, - iconTheme: 'd' - }, - _create: function(){ - - var $el = this.element, - o = this.options, - collapsibleContain = $el.addClass('ui-collapsible-contain'), - collapsibleHeading = $el.find(o.heading).eq(0), - collapsibleContent = collapsibleContain.wrapInner('
    ').find('.ui-collapsible-content'), - collapsibleParent = $el.closest( ":jqmData(role='collapsible-set')" ).addClass('ui-collapsible-set'); - - //replace collapsibleHeading if it's a legend - if(collapsibleHeading.is('legend')){ - collapsibleHeading = $('
    '+ collapsibleHeading.html() +'
    ').insertBefore(collapsibleHeading); - collapsibleHeading.next().remove(); - } - - //drop heading in before content - collapsibleHeading.insertBefore(collapsibleContent); - - //modify markup & attributes - collapsibleHeading.addClass('ui-collapsible-heading') - .append('') - .wrapInner('') - .find('a:eq(0)') - .buttonMarkup({ - shadow: !!!collapsibleParent.length, - corners:false, - iconPos: 'left', - icon: 'plus', - theme: o.theme - }) - .find('.ui-icon') - .removeAttr('class') - .buttonMarkup({ - shadow: true, - corners:true, - iconPos: 'notext', - icon: 'plus', - theme: o.iconTheme - }); - - if( !collapsibleParent.length ){ - collapsibleHeading - .find('a:eq(0)') - .addClass('ui-corner-all') - .find('.ui-btn-inner') - .addClass('ui-corner-all'); - } - else { - if( collapsibleContain.jqmData('collapsible-last') ){ - collapsibleHeading - .find('a:eq(0), .ui-btn-inner') - .addClass('ui-corner-bottom'); - } - } - - - //events - collapsibleContain - .bind('collapse', function(event){ - if( !event.isDefaultPrevented() ){ - event.preventDefault(); - collapsibleHeading - .addClass('ui-collapsible-heading-collapsed') - .find('.ui-collapsible-heading-status').text(o.expandCueText); - - collapsibleHeading.find('.ui-icon').removeClass('ui-icon-minus').addClass('ui-icon-plus'); - collapsibleContent.addClass('ui-collapsible-content-collapsed').attr('aria-hidden',true); - - if( collapsibleContain.jqmData('collapsible-last') ){ - collapsibleHeading - .find('a:eq(0), .ui-btn-inner') - .addClass('ui-corner-bottom'); - } - } - - }) - .bind('expand', function(event){ - if( !event.isDefaultPrevented() ){ - event.preventDefault(); - collapsibleHeading - .removeClass('ui-collapsible-heading-collapsed') - .find('.ui-collapsible-heading-status').text(o.collapseCueText); - - collapsibleHeading.find('.ui-icon').removeClass('ui-icon-plus').addClass('ui-icon-minus'); - collapsibleContent.removeClass('ui-collapsible-content-collapsed').attr('aria-hidden',false); - - if( collapsibleContain.jqmData('collapsible-last') ){ - collapsibleHeading - .find('a:eq(0), .ui-btn-inner') - .removeClass('ui-corner-bottom'); - } - - } - }) - .trigger(o.collapsed ? 'collapse' : 'expand'); - - - //close others in a set - if( collapsibleParent.length && !collapsibleParent.jqmData("collapsiblebound") ){ - collapsibleParent - .jqmData("collapsiblebound", true) - .bind("expand", function( event ){ - $(this).find( ".ui-collapsible-contain" ) - .not( $(event.target).closest( ".ui-collapsible-contain" ) ) - .not( "> .ui-collapsible-contain .ui-collapsible-contain" ) - .trigger( "collapse" ); - }); - var set = collapsibleParent.find( ":jqmData(role=collapsible)" ) - - set.first() - .find('a:eq(0)') - .addClass('ui-corner-top') - .find('.ui-btn-inner') - .addClass('ui-corner-top'); - - set.last().jqmData('collapsible-last', true) - } - - collapsibleHeading - .bind("vclick", function(e){ - if( collapsibleHeading.is('.ui-collapsible-heading-collapsed') ){ - collapsibleContain.trigger('expand'); - } - else { - collapsibleContain.trigger('collapse'); - } - e.preventDefault(); - }); - } -}); -})( jQuery );/* -* jQuery Mobile Framework: "controlgroup" plugin - corner-rounding for groups of buttons, checks, radios, etc -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.fn.controlgroup = function(options){ - - return this.each(function(){ - var o = $.extend({ - direction: $( this ).jqmData( "type" ) || "vertical", - shadow: false - },options); - var groupheading = $(this).find('>legend'), - flCorners = o.direction == 'horizontal' ? ['ui-corner-left', 'ui-corner-right'] : ['ui-corner-top', 'ui-corner-bottom'], - type = $(this).find('input:eq(0)').attr('type'); - - //replace legend with more stylable replacement div - if( groupheading.length ){ - $(this).wrapInner('
    '); - $('
    '+ groupheading.html() +'
    ').insertBefore( $(this).children(0) ); - groupheading.remove(); - } - - $(this).addClass('ui-corner-all ui-controlgroup ui-controlgroup-'+o.direction); - - function flipClasses(els){ - els - .removeClass('ui-btn-corner-all ui-shadow') - .eq(0).addClass(flCorners[0]) - .end() - .filter(':last').addClass(flCorners[1]).addClass('ui-controlgroup-last'); - } - flipClasses($(this).find('.ui-btn')); - flipClasses($(this).find('.ui-btn-inner')); - if(o.shadow){ - $(this).addClass('ui-shadow'); - } - }); -}; -})(jQuery);/* -* jQuery Mobile Framework : "fieldcontain" plugin - simple class additions to make form row separators -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.fn.fieldcontain = function(options){ - return this.addClass('ui-field-contain ui-body ui-br'); -}; -})(jQuery);/* -* jQuery Mobile Framework : "listview" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { - -$.widget( "mobile.listview", $.mobile.widget, { - options: { - theme: "c", - countTheme: "c", - headerTheme: "b", - dividerTheme: "b", - splitIcon: "arrow-r", - splitTheme: "b", - inset: false - }, - - _create: function() { - var $list = this.element, - o = this.options; - - // create listview markup - $list - .addClass( "ui-listview" ); - - if ( o.inset ) { - $list.addClass( "ui-listview-inset ui-corner-all ui-shadow" ); - } - - this._itemApply( $list, $list ); - - this.refresh( true ); - - }, - - _itemApply: function( $list, item ) { - // TODO class has to be defined in markup - item.find( ".ui-li-count" ) - .addClass( "ui-btn-up-" + ($list.jqmData( "counttheme" ) || this.options.countTheme) + " ui-btn-corner-all" ); - - item.find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" ); - - item.find( "p, dl" ).addClass( "ui-li-desc" ); - - $list.find( "li" ).find( ">img:eq(0), >:first>img:eq(0)" ).addClass( "ui-li-thumb" ).each(function() { - $( this ).closest( "li" ).addClass( $(this).is( ".ui-li-icon" ) ? "ui-li-has-icon" : "ui-li-has-thumb" ); - }); - - var aside = item.find( ".ui-li-aside" ); - - if ( aside.length ) { - aside.each(function(i, el) { - $(el).prependTo( $(el).parent() ); //shift aside to front for css float - }); - } - - if ( $.support.cssPseudoElement || !$.nodeName( item[0], "ol" ) ) { - return; - } - }, - - _removeCorners: function(li){ - li - .add( li.find(".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb") ) - .removeClass( "ui-corner-top ui-corner-bottom ui-corner-br ui-corner-bl ui-corner-tr ui-corner-tl" ); - }, - - refresh: function( create ) { - this._createSubPages(); - - var o = this.options, - $list = this.element, - self = this, - dividertheme = $list.jqmData( "dividertheme" ) || o.dividerTheme, - li = $list.children( "li" ), - counter = $.support.cssPseudoElement || !$.nodeName( $list[0], "ol" ) ? 0 : 1; - - if ( counter ) { - $list.find( ".ui-li-dec" ).remove(); - } - - li.each(function( pos ) { - var item = $( this ), - itemClass = "ui-li"; - - // If we're creating the element, we update it regardless - if ( !create && item.hasClass( "ui-li" ) ) { - return; - } - - var itemTheme = item.jqmData("theme") || o.theme; - - var a = item.find( ">a" ); - - if ( a.length ) { - var icon = item.jqmData("icon"); - - item - .buttonMarkup({ - wrapperEls: "div", - shadow: false, - corners: false, - iconpos: "right", - icon: a.length > 1 || icon === false ? false : icon || "arrow-r", - theme: itemTheme - }); - - a.first().addClass( "ui-link-inherit" ); - - if ( a.length > 1 ) { - itemClass += " ui-li-has-alt"; - - var last = a.last(), - splittheme = $list.jqmData( "splittheme" ) || last.jqmData( "theme" ) || o.splitTheme; - - last - .appendTo(item) - .attr( "title", last.text() ) - .addClass( "ui-li-link-alt" ) - .empty() - .buttonMarkup({ - shadow: false, - corners: false, - theme: itemTheme, - icon: false, - iconpos: false - }) - .find( ".ui-btn-inner" ) - .append( $( "" ).buttonMarkup({ - shadow: true, - corners: true, - theme: splittheme, - iconpos: "notext", - icon: $list.jqmData( "spliticon" ) || last.jqmData( "icon" ) || o.splitIcon - } ) ); - } - - } else if ( item.jqmData( "role" ) === "list-divider" ) { - itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme; - item.attr( "role", "heading" ); - - //reset counter when a divider heading is encountered - if ( counter ) { - counter = 1; - } - - } else { - itemClass += " ui-li-static ui-body-" + itemTheme; - } - - - if( o.inset ){ - if ( pos === 0 ) { - itemClass += " ui-corner-top"; - - item - .add( item.find( ".ui-btn-inner" ) ) - .find( ".ui-li-link-alt" ) - .addClass( "ui-corner-tr" ) - .end() - .find( ".ui-li-thumb" ) - .addClass( "ui-corner-tl" ); - if(item.next().next().length){ - self._removeCorners( item.next() ); - } - - } - if ( pos === li.length - 1 ) { - itemClass += " ui-corner-bottom"; - - item - .add( item.find( ".ui-btn-inner" ) ) - .find( ".ui-li-link-alt" ) - .addClass( "ui-corner-br" ) - .end() - .find( ".ui-li-thumb" ) - .addClass( "ui-corner-bl" ); - - if(item.prev().prev().length){ - self._removeCorners( item.prev() ); - } - } - } - - - if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) { - - var countParent = item.is(".ui-li-static:first") ? item : item.find( ".ui-link-inherit" ); - - countParent - .addClass( "ui-li-jsnumbering" ) - .prepend( "" + (counter++) + ". " ); - } - - item.add( item.find( ".ui-btn-inner" ) ).addClass( itemClass ); - - if ( !create ) { - self._itemApply( $list, item ); - } - }); - }, - - //create a string for ID/subpage url creation - _idStringEscape: function( str ){ - return str.replace(/[^a-zA-Z0-9]/g, '-'); - }, - - _createSubPages: function() { - var parentList = this.element, - parentPage = parentList.closest( ".ui-page" ), - parentId = parentPage.jqmData( "url" ), - o = this.options, - self = this, - persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" ); - - $( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function( i ) { - var list = $( this ), - parent = list.parent(), - nodeEls = $( list.prevAll().toArray().reverse() ), - nodeEls = nodeEls.length ? nodeEls : $( "" + $.trim(parent.contents()[ 0 ].nodeValue) + "" ), - title = nodeEls.first().text(),//url limits to first 30 chars of text - id = parentId + "&" + $.mobile.subPageUrlKey + "=" + self._idStringEscape(title + " " + i), - theme = list.jqmData( "theme" ) || o.theme, - countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme, - newPage = list.wrap( "
    " ) - .parent() - .before( "
    " + title + "
    " ) - .after( persistentFooterID ? $( "
    ") : "" ) - .parent() - .attr( "data-" + $.mobile.ns + "url", id ) - .attr( "data-" + $.mobile.ns + "theme", theme ) - .attr( "data-" + $.mobile.ns + "count-theme", countTheme ) - .appendTo( $.mobile.pageContainer ); - - newPage.page(); - var anchor = parent.find('a:first'); - if (!anchor.length) { - anchor = $("").html( nodeEls || title ).prependTo(parent.empty()); - } - anchor.attr('href','#' + id); - }).listview(); - } -}); - -})( jQuery ); -/* -* jQuery Mobile Framework : "listview" filter extension -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { - -$.mobile.listview.prototype.options.filter = false; -$.mobile.listview.prototype.options.filterPlaceholder = "Filter items..."; - -$( ":jqmData(role='listview')" ).live( "listviewcreate", function() { - var list = $( this ), - listview = list.data( "listview" ); - - if ( !listview.options.filter ) { - return; - } - - var wrapper = $( "
    ", { "class": "ui-listview-filter ui-bar-c", "role": "search" } ), - - search = $( "", { - placeholder: listview.options.filterPlaceholder - }) - .attr( "data-" + $.mobile.ns + "type", "search" ) - .bind( "keyup change", function() { - var val = this.value.toLowerCase(), - listItems = list.children(); - listItems.show(); - if ( val ) { - // This handles hiding regular rows without the text we search for - // and any list dividers without regular rows shown under it - var childItems = false, - item; - - for (var i = listItems.length; i >= 0; i--) { - item = $(listItems[i]); - if (item.is("li:jqmData(role=list-divider)")) { - if (!childItems) { - item.hide(); - } - // New bucket! - childItems = false; - } else if (item.text().toLowerCase().indexOf( val ) === -1) { - item.hide(); - } else { - // There's a shown item in the bucket - childItems = true; - } - } - } - }) - .appendTo( wrapper ) - .textinput(); - - if ($( this ).jqmData( "inset" ) ) { - wrapper.addClass( "ui-listview-filter-inset" ); - } - - wrapper.insertBefore( list ); -}); - -})( jQuery ); -/* -* jQuery Mobile Framework : "dialog" plugin. -* Copyright (c) jQuery Project -* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -* Note: Code is in draft form and is subject to change -*/ -(function($, undefined ) { -$.widget( "mobile.dialog", $.mobile.widget, { - options: { - closeBtnText: "Close" - }, - _create: function(){ - var self = this, - $el = self.element; - - /* class the markup for dialog styling */ - this.element - //add ARIA role - .attr("role","dialog") - .addClass('ui-page ui-dialog ui-body-a') - .find( ":jqmData(role=header)" ) - .addClass('ui-corner-top ui-overlay-shadow') - .prepend( ""+ this.options.closeBtnText +"" ) - .end() - .find('.ui-content:not([class*="ui-body-"])') - .addClass('ui-body-c') - .end() - .find( ".ui-content,:jqmData(role='footer')" ) - .last() - .addClass('ui-corner-bottom ui-overlay-shadow'); - - /* bind events - - clicks and submits should use the closing transition that the dialog opened with - unless a data-transition is specified on the link/form - - if the click was on the close button, or the link has a data-rel="back" it'll go back in history naturally - */ - this.element - .bind( "vclick submit", function(e){ - var $targetel; - if( e.type == "vclick" ){ - $targetel = $(e.target).closest("a"); - } - else{ - $targetel = $(e.target).closest("form"); - } - - if( $targetel.length && !$targetel.jqmData("transition") ){ - $targetel - .attr("data-" + $.mobile.ns + "transition", $.mobile.urlHistory.getActive().transition ) - .attr("data-" + $.mobile.ns + "direction", "reverse"); - } - }); - - }, - - //close method goes back in history - close: function(){ - window.history.back(); - } -}); -})( jQuery );/* -* jQuery Mobile Framework : "navbar" plugin -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.widget( "mobile.navbar", $.mobile.widget, { - options: { - iconpos: 'top', - grid: null - }, - _create: function(){ - var $navbar = this.element, - $navbtns = $navbar.find("a"), - iconpos = $navbtns.filter( ":jqmData(icon)").length ? this.options.iconpos : undefined; - - $navbar - .addClass('ui-navbar') - .attr("role","navigation") - .find("ul") - .grid({grid: this.options.grid }); - - if( !iconpos ){ - $navbar.addClass("ui-navbar-noicons"); - } - - $navbtns - .buttonMarkup({ - corners: false, - shadow: false, - iconpos: iconpos - }); - - $navbar.delegate("a", "vclick",function(event){ - $navbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass ); - $( this ).addClass( $.mobile.activeBtnClass ); - }); - } -}); -})( jQuery ); -/* -* jQuery Mobile Framework : plugin for creating CSS grids -* Copyright (c) jQuery Project -* Dual licensed under the MIT or GPL Version 2 licenses. -* http://jquery.org/license -*/ -(function($, undefined ) { -$.fn.grid = function(options){ - return this.each(function(){ - var o = $.extend({ - grid: null - },options); - - - var $kids = $(this).children(), - gridCols = {solo:1, a:2, b:3, c:4, d:5}, - grid = o.grid, - iterator; - - if( !grid ){ - if( $kids.length <= 5 ){ - for(var letter in gridCols){ - if(gridCols[letter] == $kids.length){ grid = letter; } - } - } - else{ - grid = 'a'; - } - } - iterator = gridCols[grid]; - - $(this).addClass('ui-grid-' + grid); - - $kids.filter(':nth-child(' + iterator + 'n+1)').addClass('ui-block-a'); - if(iterator > 1){ - $kids.filter(':nth-child(' + iterator + 'n+2)').addClass('ui-block-b'); - } - if(iterator > 2){ - $kids.filter(':nth-child(3n+3)').addClass('ui-block-c'); - } - if(iterator > 3){ - $kids.filter(':nth-child(4n+4)').addClass('ui-block-d'); - } - if(iterator > 4){ - $kids.filter(':nth-child(5n+5)').addClass('ui-block-e'); - } - - }); -}; -})(jQuery);/*! - * jQuery Mobile v@VERSION - * http://jquerymobile.com/ - * - * Copyright 2010, jQuery Project - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - */ - -(function( $, window, undefined ) { - var $html = $( "html" ), - $head = $( "head" ), - $window = $( window ); - - //trigger mobileinit event - useful hook for configuring $.mobile settings before they're used - $( window.document ).trigger( "mobileinit" ); - - //support conditions - //if device support condition(s) aren't met, leave things as they are -> a basic, usable experience, - //otherwise, proceed with the enhancements - if ( !$.mobile.gradeA() ) { - return; - } - - //add mobile, initial load "rendering" classes to docEl - $html.addClass( "ui-mobile ui-mobile-rendering" ); - - //define & prepend meta viewport tag, if content is defined - //NOTE: this is now deprecated. We recommend placing the meta viewport element in - //the markup from the start. - $.mobile.metaViewportContent && !$head.find( "meta[name='viewport']" ).length ? $( "", { name: "viewport", content: $.mobile.metaViewportContent}).prependTo( $head ) : undefined; - - //loading div which appears during Ajax requests - //will not appear if $.mobile.loadingMessage is false - var $loader = $.mobile.loadingMessage ? $( "
    " + "" + "

    " + $.mobile.loadingMessage + "

    " + "
    " ) : undefined; - - if(typeof $loader === "undefined"){ - alert($.mobile.loadingMessage); - } - - $.extend($.mobile, { - // turn on/off page loading message. - pageLoading: function ( done ) { - if ( done ) { - $html.removeClass( "ui-loading" ); - } else { - if( $.mobile.loadingMessage ){ - var activeBtn = $( "." + $.mobile.activeBtnClass ).first(); - - - if(typeof $loader === "undefined"){ - alert($.mobile.loadingMessage); - } - - $loader - .appendTo( $.mobile.pageContainer ) - //position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top - .css( { - top: $.support.scrollTop && $(window).scrollTop() + $(window).height() / 2 || - activeBtn.length && activeBtn.offset().top || 100 - } ); - } - - $html.addClass( "ui-loading" ); - } - }, - - // find and enhance the pages in the dom and transition to the first page. - initializePage: function(){ - //find present pages - var $pages = $( ":jqmData(role='page')" ); - - //add dialogs, set data-url attrs - $pages.add( ":jqmData(role='dialog')" ).each(function(){ - var $this = $(this); - - // unless the data url is already set set it to the id - if( !$this.jqmData('url') ){ - $this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) ); - } - }); - - //define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback) - $.mobile.firstPage = $pages.first(); - - //define page container - $.mobile.pageContainer = $pages.first().parent().addClass( "ui-mobile-viewport" ); - - //cue page loading message - $.mobile.pageLoading(); - - // if hashchange listening is disabled or there's no hash deeplink, change to the first page in the DOM - if( !$.mobile.hashListeningEnabled || !$.mobile.path.stripHash( location.hash ) ){ - $.mobile.changePage( $.mobile.firstPage, false, true, false, true ); - } - // otherwise, trigger a hashchange to load a deeplink - else { - $window.trigger( "hashchange", [ true ] ); - } - } - }); - - //dom-ready inits - $( $.mobile.initializePage ); - - //window load event - //hide iOS browser chrome on load - $window.load( $.mobile.silentScroll ); -})( jQuery, this ); - --- /dev/null +++ b/js/jquery.mobile-1.1.0.min.js @@ -1,1 +1,178 @@ +/*! jQuery Mobile v1.1.0 db342b1f315c282692791aa870455901fdb46a55 jquerymobile.com | jquery.org/license */ +(function(D,s,k){typeof define==="function"&&define.amd?define(["jquery"],function(a){k(a,D,s);return a.mobile}):k(D.jQuery,D,s)})(this,document,function(D,s,k){(function(a,c,b,e){function f(a){for(;a&&typeof a.originalEvent!=="undefined";)a=a.originalEvent;return a}function d(b){for(var d={},f,g;b;){f=a.data(b,t);for(g in f)if(f[g])d[g]=d.hasVirtualBinding=true;b=b.parentNode}return d}function g(){y&&(clearTimeout(y),y=0);y=setTimeout(function(){F=y=0;C.length=0;z=false;G=true},a.vmouse.resetTimerDuration)} +function h(b,d,g){var c,h;if(!(h=g&&g[b])){if(g=!g)a:{for(g=d.target;g;){if((h=a.data(g,t))&&(!b||h[b]))break a;g=g.parentNode}g=null}h=g}if(h){c=d;var g=c.type,z,j;c=a.Event(c);c.type=b;h=c.originalEvent;z=a.event.props;g.search(/^(mouse|click)/)>-1&&(z=w);if(h)for(j=z.length;j;)b=z[--j],c[b]=h[b];if(g.search(/mouse(down|up)|click/)>-1&&!c.which)c.which=1;if(g.search(/^touch/)!==-1&&(b=f(h),g=b.touches,b=b.changedTouches,g=g&&g.length?g[0]:b&&b.length?b[0]:e))for(h=0,len=u.length;hz||Math.abs(c.pageY-E)>z;flags=d(b.target);A&&!e&&h("vmousecancel",b,flags);h("vmousemove",b,flags);g()}}function l(a){if(!G){G=true;var b=d(a.target),c;h("vmouseup",a,b);if(!A&&(c=h("vclick",a,b))&&c.isDefaultPrevented())c=f(a).changedTouches[0],C.push({touchID:F,x:c.clientX,y:c.clientY}),z=true;h("vmouseout",a,b);A=false;g()}}function r(b){var b= +a.data(b,t),d;if(b)for(d in b)if(b[d])return true;return false}function n(){}function k(b){var d=b.substr(1);return{setup:function(){r(this)||a.data(this,t,{});a.data(this,t)[b]=true;v[b]=(v[b]||0)+1;v[b]===1&&H.bind(d,j);a(this).bind(d,n);if(K)v.touchstart=(v.touchstart||0)+1,v.touchstart===1&&H.bind("touchstart",o).bind("touchend",l).bind("touchmove",p).bind("scroll",m)},teardown:function(){--v[b];v[b]||H.unbind(d,j);K&&(--v.touchstart,v.touchstart||H.unbind("touchstart",o).unbind("touchmove",p).unbind("touchend", +l).unbind("scroll",m));var f=a(this),g=a.data(this,t);g&&(g[b]=false);f.unbind(d,n);r(this)||f.removeData(t)}}}var t="virtualMouseBindings",x="virtualTouchID",c="vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split(" "),u="clientX clientY pageX pageY screenX screenY".split(" "),w=a.event.props.concat(a.event.mouseHooks?a.event.mouseHooks.props:[]),v={},y=0,s=0,E=0,A=false,C=[],z=false,G=false,K="addEventListener"in b,H=a(b),L=1,F=0;a.vmouse={moveDistanceThreshold:10,clickDistanceThreshold:10, +resetTimerDuration:1500};for(var I=0;I7);a.fn[f]=function(a){return a?this.bind(f,a):this.trigger(f)};a.fn[f].delay=50;h[f]=a.extend(h[f],{setup:function(){if(o)return false;a(g.start)},teardown:function(){if(o)return false;a(g.stop)}});g=function(){function g(){var b=e(),d=t(r);if(b!==r)k(r=b,d),a(c).trigger(f);else if(d!==r)location.href=location.href.replace(/#.*/,"")+d;j=setTimeout(g,a.fn[f].delay)}var h={},j,r=e(),n=function(a){return a},k= +n,t=n;h.start=function(){j||g()};h.stop=function(){j&&clearTimeout(j);j=b};a.browser.msie&&!o&&function(){var b,c;h.start=function(){if(!b)c=(c=a.fn[f].src)&&c+e(),b=a('