Merge lp:~hrvojem/tcprstat/sphinx_doc into lp:tcprstat

Proposed by Hrvoje Matijakovic on 2012-03-08
Status: Needs review
Proposed branch: lp:~hrvojem/tcprstat/sphinx_doc
Merge into: lp:tcprstat
Diff against target: 17878 lines
To merge this branch: bzr merge lp:~hrvojem/tcprstat/sphinx_doc
Reviewer Review Type Date Requested Status
Ignacio Nin 2012-03-08 Pending
Review via email: mp+96529@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

74. By Hrvoje Matijakovic on 2012-03-08

ported documentation from wiki to sphinx doc

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'doc'
2=== added file 'doc/Makefile'
3--- doc/Makefile 1970-01-01 00:00:00 +0000
4+++ doc/Makefile 2012-03-08 09:19:21 +0000
5@@ -0,0 +1,130 @@
6+# Makefile for Sphinx documentation
7+#
8+
9+# You can set these variables from the command line.
10+SPHINXOPTS =
11+SPHINXBUILD = sphinx-build
12+PAPER =
13+BUILDDIR = build
14+
15+# Internal variables.
16+PAPEROPT_a4 = -D latex_paper_size=a4
17+PAPEROPT_letter = -D latex_paper_size=letter
18+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
19+
20+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
21+
22+help:
23+ @echo "Please use \`make <target>' where <target> is one of"
24+ @echo " html to make standalone HTML files"
25+ @echo " dirhtml to make HTML files named index.html in directories"
26+ @echo " singlehtml to make a single large HTML file"
27+ @echo " pickle to make pickle files"
28+ @echo " json to make JSON files"
29+ @echo " htmlhelp to make HTML files and a HTML help project"
30+ @echo " qthelp to make HTML files and a qthelp project"
31+ @echo " devhelp to make HTML files and a Devhelp project"
32+ @echo " epub to make an epub"
33+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
34+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
35+ @echo " text to make text files"
36+ @echo " man to make manual pages"
37+ @echo " changes to make an overview of all changed/added/deprecated items"
38+ @echo " linkcheck to check all external links for integrity"
39+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
40+
41+clean:
42+ -rm -rf $(BUILDDIR)/*
43+
44+html:
45+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
46+ @echo
47+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
48+
49+dirhtml:
50+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
51+ @echo
52+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
53+
54+singlehtml:
55+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
56+ @echo
57+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
58+
59+pickle:
60+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
61+ @echo
62+ @echo "Build finished; now you can process the pickle files."
63+
64+json:
65+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
66+ @echo
67+ @echo "Build finished; now you can process the JSON files."
68+
69+htmlhelp:
70+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
71+ @echo
72+ @echo "Build finished; now you can run HTML Help Workshop with the" \
73+ ".hhp project file in $(BUILDDIR)/htmlhelp."
74+
75+qthelp:
76+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
77+ @echo
78+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
79+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
80+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PerconaXtraBackup.qhcp"
81+ @echo "To view the help file:"
82+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PerconaXtraBackup.qhc"
83+
84+devhelp:
85+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
86+ @echo
87+ @echo "Build finished."
88+ @echo "To view the help file:"
89+ @echo "# mkdir -p $$HOME/.local/share/devhelp/PerconaXtraBackup"
90+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PerconaXtraBackup"
91+ @echo "# devhelp"
92+
93+epub:
94+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
95+ @echo
96+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
97+
98+latex:
99+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
100+ @echo
101+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
102+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
103+ "(use \`make latexpdf' here to do that automatically)."
104+
105+latexpdf:
106+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
107+ @echo "Running LaTeX files through pdflatex..."
108+ make -C $(BUILDDIR)/latex all-pdf
109+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
110+
111+text:
112+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
113+ @echo
114+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
115+
116+man:
117+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
118+ @echo
119+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
120+
121+changes:
122+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
123+ @echo
124+ @echo "The overview file is in $(BUILDDIR)/changes."
125+
126+linkcheck:
127+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
128+ @echo
129+ @echo "Link check complete; look for any errors in the above output " \
130+ "or in $(BUILDDIR)/linkcheck/output.txt."
131+
132+doctest:
133+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
134+ @echo "Testing of doctests in the sources finished, look at the " \
135+ "results in $(BUILDDIR)/doctest/output.txt."
136
137=== added directory 'doc/build'
138=== added directory 'doc/build/doctrees'
139=== added file 'doc/build/doctrees/environment.pickle'
140Binary files doc/build/doctrees/environment.pickle 1970-01-01 00:00:00 +0000 and doc/build/doctrees/environment.pickle 2012-03-08 09:19:21 +0000 differ
141=== added file 'doc/build/doctrees/index.doctree'
142Binary files doc/build/doctrees/index.doctree 1970-01-01 00:00:00 +0000 and doc/build/doctrees/index.doctree 2012-03-08 09:19:21 +0000 differ
143=== added file 'doc/build/doctrees/installation.doctree'
144Binary files doc/build/doctrees/installation.doctree 1970-01-01 00:00:00 +0000 and doc/build/doctrees/installation.doctree 2012-03-08 09:19:21 +0000 differ
145=== added file 'doc/build/doctrees/intro.doctree'
146Binary files doc/build/doctrees/intro.doctree 1970-01-01 00:00:00 +0000 and doc/build/doctrees/intro.doctree 2012-03-08 09:19:21 +0000 differ
147=== added file 'doc/build/doctrees/manual.doctree'
148Binary files doc/build/doctrees/manual.doctree 1970-01-01 00:00:00 +0000 and doc/build/doctrees/manual.doctree 2012-03-08 09:19:21 +0000 differ
149=== added file 'doc/build/doctrees/support.doctree'
150Binary files doc/build/doctrees/support.doctree 1970-01-01 00:00:00 +0000 and doc/build/doctrees/support.doctree 2012-03-08 09:19:21 +0000 differ
151=== added directory 'doc/build/html'
152=== added file 'doc/build/html/.buildinfo'
153--- doc/build/html/.buildinfo 1970-01-01 00:00:00 +0000
154+++ doc/build/html/.buildinfo 2012-03-08 09:19:21 +0000
155@@ -0,0 +1,4 @@
156+# Sphinx build info version 1
157+# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
158+config: 157b3cb084d64187df07ef5c09529c53
159+tags: fbb0d17656682115ca4d033fb2f83ba1
160
161=== added directory 'doc/build/html/_sources'
162=== added file 'doc/build/html/_sources/index.txt'
163--- doc/build/html/_sources/index.txt 1970-01-01 00:00:00 +0000
164+++ doc/build/html/_sources/index.txt 2012-03-08 09:19:21 +0000
165@@ -0,0 +1,47 @@
166+============================================================
167+ Tcprstat - Documentation
168+============================================================
169+
170+Introduction
171+============
172+
173+.. toctree::
174+ :maxdepth: 1
175+ :glob:
176+
177+ intro
178+
179+Installation
180+============
181+
182+.. toctree::
183+ :maxdepth: 2
184+ :glob:
185+
186+ installation
187+
188+User's Manual
189+=============
190+
191+.. toctree::
192+ :maxdepth: 2
193+ :glob:
194+
195+ manual
196+
197+Miscellaneous
198+=============
199+
200+.. toctree::
201+ :maxdepth: 1
202+ :glob:
203+
204+ support
205+
206+Indices and tables
207+==================
208+
209+* :ref:`genindex`
210+
211+* :ref:`search`
212+
213
214=== added file 'doc/build/html/_sources/installation.txt'
215--- doc/build/html/_sources/installation.txt 1970-01-01 00:00:00 +0000
216+++ doc/build/html/_sources/installation.txt 2012-03-08 09:19:21 +0000
217@@ -0,0 +1,12 @@
218+=====================
219+ Installing tcprstat
220+=====================
221+
222+For portability and ease of use, we build a single statically linked binary, which can be downloaded and used as-is on 64-bit platforms. At present there is no installation mechanism, so to use tcprstat, you simply need to:
223+
224+ * Download the `statically linked 64-bit binary (version 0.3.1) <http://github.com/downloads/Lowercases/tcprstat/tcprstat-static.v0.3.1.x86_64>`_
225+ * Move it into a directory in your PATH, such as /usr/bin
226+ * Rename it to tcprstat
227+ * Make it executable with chmod +x
228+
229+There are currently no operating-system-specific packages for tcprstat, although in the future we plan to include it in our APT and YUM repositories. If you need to run tcprstat on 32-bit systems, you will need to build it from source.
230
231=== added file 'doc/build/html/_sources/intro.txt'
232--- doc/build/html/_sources/intro.txt 1970-01-01 00:00:00 +0000
233+++ doc/build/html/_sources/intro.txt 2012-03-08 09:19:21 +0000
234@@ -0,0 +1,27 @@
235+==============
236+About tcprstat
237+==============
238+
239+.. toctree::
240+ :hidden:
241+
242+tcprstat is a free, open-source TCP analysis tool that watches network traffic and computes the delay between requests and responses. From this it derives response-time statistics and prints them out. The output is similar to other Unix -stat tools such as vmstat, iostat, and mpstat. The tool can optionally watch traffic to only a specified port, which makes it practical for timing requests and responses to a single daemon process such as mysqld, httpd, memcached, or any of a variety of other server processes.
243+
244+The advantages of tcprstat are as follows:
245+
246+ * It is lightweight and unobtrusive. No bulky log files need be written and analyzed.
247+ * Requests and responses are timed with microsecond resolution.
248+ * The output is easy to import into spreadsheets, manipulate with command-line scripts, graph with gnuplot, and so on.
249+ * It is protocol-agnostic, and works well for a large variety of client-server protocols that have a simple request-response model.
250+
251+tcprstat is related to the `tcpstat <http://www.frenchfries.net/paul/tcpstat/>`_ tool, but it focuses on response time measurements, not on the amount and size of the network traffic. This makes it useful for response time analysis, which is needed for techniques such as `Goal-Driven Performance Optimization <http://www.percona.com/about-us/white-papers>`_.
252+
253+tcprstat development is hosted on `Launchpad <https://launchpad.net/tcprstat>`_. We are currently moving downloads and bug tracking from GitHub to Launchpad, so some links in this document may refer to GitHub until that process is complete.
254+
255+Development Status
256+==================
257+tcprstat is currently in Beta, although we consider it ready for production testing. Several C++ experts have reviewed the code, and it has been observed in high-stress production environments for many weeks with no apparent problems. Please test and review the code, and report any issues or suggestions you have. Please also review our `roadmap <https://launchpad.net/tcprstat/+milestones>`_ and contribute your suggestions.
258+
259+Authors
260+=======
261+tcprstat was written by `Ignacio Nin <http://www.percona.com/about-us/our-team/ignacio-nin/>`_, based on ideas from `Baron Schwartz <http://www.percona.com/about-us/our-team/baron-schwartz/>`_ and other Percona consultants. The code was reviewed by Oleg Tsarev, Sasha Pachev, and other members of the Percona development team.
262
263=== added file 'doc/build/html/_sources/manual.txt'
264--- doc/build/html/_sources/manual.txt 1970-01-01 00:00:00 +0000
265+++ doc/build/html/_sources/manual.txt 2012-03-08 09:19:21 +0000
266@@ -0,0 +1,126 @@
267+.. _user-manual:
268+
269+======================
270+tcprstat User's Manual
271+======================
272+
273+.. toctree::
274+ :maxdepth: 1
275+ :hidden:
276+
277+Running tcprstat
278+================
279+
280+tcprstat requires root permissions to execute. If you are not root, you should either become root with su, or execute tcprstat with sudo. The following examples assume you are root, and do not show the use of sudo.
281+
282+Default Usage
283+-------------
284+The simplest functionality is to accept all defaults and simply execute the tool. By default, it will measure the TCP traffic for 10 seconds and print out a header, followed by a single line of statistics. ::
285+
286+ # timestamp count max min avg med stddev 95_max 95_avg 95_std 99_max 99_avg 99_std
287+ 1283265068 23892 425546 30 505 161 6240 835 186 102 4179 261 429
288+
289+
290+Basic, Useful Functionality
291+---------------------------
292+
293+In practice, you will usually select a specific port to measure, set the tool to iterate infinitely, and possibly change the default 10-second interval. To accomplish this, use the following options:
294+
295+ * -p <port> selects a port
296+ * -i <secs> sets the measurement interval, in seconds
297+ * -n <iter> specifies the number of iterations to run; 0 means to run forever
298+
299+For example, to watch Sphinx traffic in one-second intervals forever, execute: ::
300+
301+ # tcprstat -p 3312 -i 1 -n 0.
302+
303+Customizing The Output
304+----------------------
305+
306+tcprstat's output can be changed to include or omit various types of statistics on the traffic it measures. The default output includes columns that are useful for many purposes. The output is specified with %C format codes, where C is a single character. The following table documents the available format codes and their meaning.
307+
308+=========== ============= ======== ==========================================================
309+Format Code Header Default? Meaning
310+=========== ============= ======== ==========================================================
311+%n count y Count of requests that completed during this iteration
312+%a avg y Average response time
313+%s sum y Sum of response times
314+%x sqs n Sum of squares of response times
315+%m min y Minimum response time
316+%M max y Maximum response time
317+%h med y Median response time
318+%S stddev y Standard deviation of response times
319+%v var n Variance of response times
320+%I iter# n Iteration number
321+%t elapsed n Seconds elapsed since the first iteration
322+%T timestamp y Unix timestamp
323+%% A literal %
324+\t A tab character
325+\n A newline character
326+95,99 Adds a prefix y A percentile indicator; see later in this section for more
327+=========== ============= ======== ==========================================================
328+
329+You can change the tcprstat output format by customizing the -f option. For example, to print out the number of requests per second to a MySQL server on port 3306, execute the following: ::
330+
331+ # tcprstat -f '%n\n' -p 3306 -t 1 -n 0
332+ count
333+ 2212
334+ 2070
335+ ...
336+
337+You can also include a percentile indicator, to compute the statistics over the Nth percentile of the response times. The tool currently supports only the 95th and 99th percentiles. To print out statistics for a given percentile, include the percentile number between the % character and the format code. The default column header will then include the percentile value. The following example prints the maximum, 95th percentile maximum, and 99th percentile maximum response times in microseconds: ::
338+
339+ # tcprstat -f '%M\t%95M\t%99M\n' -p 3306 -t 1 -n 0
340+ max 95_max 99_max
341+ 31221 411 3001
342+ 52721 495 2828
343+ 12173 507 1513
344+ ...
345+
346+Analyzing a pcap File
347+---------------------
348+
349+tcprstat has the ability not only to analyze traffic live as it is captured, but also to analyze traffic from a file created by tcpdump. This makes it possible to gather traffic on one machine and analyze it elsewhere at a different time. To save traffic for later analysis, execute tcpdump with the -w option and specify the file in which to store the resulting traffic. Use the -r option to tcprstat to read traffic from that file and analyze it.
350+
351+tcprstat normally decides what traffic is incoming (a request) and what traffic is outbound (a response) by finding a list of IP addresses bound to the local network interfaces. However, this will not work correctly when traffic is analyzed from a file that was gathered on a different host. You can use the -l option to specify a list of local IP addresses in this case.
352+
353+Command-Line Options
354+====================
355+
356+The following is a complete list of tcprstat's command-line options. You can always find a full list of the available command-line options and brief usage information by giving the --help option.
357+
358+.. option:: --format -f
359+
360+ A format string. Detailed description of supported values can bee seen in the table above.
361+
362+.. option:: --[no]header
363+
364+ If no argument is given, tcprstat auto-generates the header based on --format. If an argument is given, tcprstat uses that as the header instead. If --no-header is used, tcprstat will not print a header.
365+
366+.. option:: --help
367+
368+ Shows program information and usage.
369+
370+.. option:: --interval -t
371+
372+ The number of seconds tcprstat waits between each successive line of output. Default value is 10.
373+
374+.. option:: --iterations -n
375+
376+ How many iterations tcprstat should execute before exiting; 0 means infinity. Default value is 1.
377+
378+.. option:: --local -l
379+
380+ Accepts a comma-separated list of IP addresses to consider as local IP addresses, instead of getting a list from the operating system.
381+
382+.. option:: --port -p
383+
384+ Capture traffic only for the specified TCP port; if none, capture all traffic.
385+
386+.. option:: --read -r
387+
388+ Read the specified pcap file instead of capturing traffic from the network.
389+
390+.. option:: --version
391+
392+ Shows tcprstat version.
393
394=== added file 'doc/build/html/_sources/support.txt'
395--- doc/build/html/_sources/support.txt 1970-01-01 00:00:00 +0000
396+++ doc/build/html/_sources/support.txt 2012-03-08 09:19:21 +0000
397@@ -0,0 +1,7 @@
398+================
399+Help and Support
400+================
401+
402+Please use `Launchpad's issue tracking system <https://bugs.launchpad.net/tcprstat>`_ to report issues and request features. For general discussion, please use the `Percona-Discussion Google Group <http://groups.google.com/group/percona-discussion>`_. You can use the #percona IRC channel on FreeNode to chat with community members.
403+
404+For commercial support, maintenance packages, or to sponsor features, please contact `Percona Sales <http://www.percona.com/contact/sales>`_.
405
406=== added directory 'doc/build/html/_static'
407=== added file 'doc/build/html/_static/basic.css'
408--- doc/build/html/_static/basic.css 1970-01-01 00:00:00 +0000
409+++ doc/build/html/_static/basic.css 2012-03-08 09:19:21 +0000
410@@ -0,0 +1,528 @@
411+/*
412+ * basic.css
413+ * ~~~~~~~~~
414+ *
415+ * Sphinx stylesheet -- basic theme.
416+ *
417+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
418+ * :license: BSD, see LICENSE for details.
419+ *
420+ */
421+
422+/* -- main layout ----------------------------------------------------------- */
423+
424+div.clearer {
425+ clear: both;
426+}
427+
428+/* -- relbar ---------------------------------------------------------------- */
429+
430+div.related {
431+ width: 100%;
432+ font-size: 90%;
433+}
434+
435+div.related h3 {
436+ display: none;
437+}
438+
439+div.related ul {
440+ margin: 0;
441+ padding: 0 0 0 10px;
442+ list-style: none;
443+}
444+
445+div.related li {
446+ display: inline;
447+}
448+
449+div.related li.right {
450+ float: right;
451+ margin-right: 5px;
452+}
453+
454+/* -- sidebar --------------------------------------------------------------- */
455+
456+div.sphinxsidebarwrapper {
457+ padding: 10px 5px 0 10px;
458+}
459+
460+div.sphinxsidebar {
461+ float: left;
462+ width: 230px;
463+ margin-left: -100%;
464+ font-size: 90%;
465+}
466+
467+div.sphinxsidebar ul {
468+ list-style: none;
469+}
470+
471+div.sphinxsidebar ul ul,
472+div.sphinxsidebar ul.want-points {
473+ margin-left: 20px;
474+ list-style: square;
475+}
476+
477+div.sphinxsidebar ul ul {
478+ margin-top: 0;
479+ margin-bottom: 0;
480+}
481+
482+div.sphinxsidebar form {
483+ margin-top: 10px;
484+}
485+
486+div.sphinxsidebar input {
487+ border: 1px solid #98dbcc;
488+ font-family: sans-serif;
489+ font-size: 1em;
490+}
491+
492+img {
493+ border: 0;
494+}
495+
496+/* -- search page ----------------------------------------------------------- */
497+
498+ul.search {
499+ margin: 10px 0 0 20px;
500+ padding: 0;
501+}
502+
503+ul.search li {
504+ padding: 5px 0 5px 20px;
505+ background-image: url(file.png);
506+ background-repeat: no-repeat;
507+ background-position: 0 7px;
508+}
509+
510+ul.search li a {
511+ font-weight: bold;
512+}
513+
514+ul.search li div.context {
515+ color: #888;
516+ margin: 2px 0 0 30px;
517+ text-align: left;
518+}
519+
520+ul.keywordmatches li.goodmatch a {
521+ font-weight: bold;
522+}
523+
524+/* -- index page ------------------------------------------------------------ */
525+
526+table.contentstable {
527+ width: 90%;
528+}
529+
530+table.contentstable p.biglink {
531+ line-height: 150%;
532+}
533+
534+a.biglink {
535+ font-size: 1.3em;
536+}
537+
538+span.linkdescr {
539+ font-style: italic;
540+ padding-top: 5px;
541+ font-size: 90%;
542+}
543+
544+/* -- general index --------------------------------------------------------- */
545+
546+table.indextable {
547+ width: 100%;
548+}
549+
550+table.indextable td {
551+ text-align: left;
552+ vertical-align: top;
553+}
554+
555+table.indextable dl, table.indextable dd {
556+ margin-top: 0;
557+ margin-bottom: 0;
558+}
559+
560+table.indextable tr.pcap {
561+ height: 10px;
562+}
563+
564+table.indextable tr.cap {
565+ margin-top: 10px;
566+ background-color: #f2f2f2;
567+}
568+
569+img.toggler {
570+ margin-right: 3px;
571+ margin-top: 3px;
572+ cursor: pointer;
573+}
574+
575+div.modindex-jumpbox {
576+ border-top: 1px solid #ddd;
577+ border-bottom: 1px solid #ddd;
578+ margin: 1em 0 1em 0;
579+ padding: 0.4em;
580+}
581+
582+div.genindex-jumpbox {
583+ border-top: 1px solid #ddd;
584+ border-bottom: 1px solid #ddd;
585+ margin: 1em 0 1em 0;
586+ padding: 0.4em;
587+}
588+
589+/* -- general body styles --------------------------------------------------- */
590+
591+a.headerlink {
592+ visibility: hidden;
593+}
594+
595+h1:hover > a.headerlink,
596+h2:hover > a.headerlink,
597+h3:hover > a.headerlink,
598+h4:hover > a.headerlink,
599+h5:hover > a.headerlink,
600+h6:hover > a.headerlink,
601+dt:hover > a.headerlink {
602+ visibility: visible;
603+}
604+
605+div.body p.caption {
606+ text-align: inherit;
607+}
608+
609+div.body td {
610+ text-align: left;
611+}
612+
613+.field-list ul {
614+ padding-left: 1em;
615+}
616+
617+.first {
618+ margin-top: 0 !important;
619+}
620+
621+p.rubric {
622+ margin-top: 30px;
623+ font-weight: bold;
624+}
625+
626+img.align-left, .figure.align-left, object.align-left {
627+ clear: left;
628+ float: left;
629+ margin-right: 1em;
630+}
631+
632+img.align-right, .figure.align-right, object.align-right {
633+ clear: right;
634+ float: right;
635+ margin-left: 1em;
636+}
637+
638+img.align-center, .figure.align-center, object.align-center {
639+ display: block;
640+ margin-left: auto;
641+ margin-right: auto;
642+}
643+
644+.align-left {
645+ text-align: left;
646+}
647+
648+.align-center {
649+ clear: both;
650+ text-align: center;
651+}
652+
653+.align-right {
654+ text-align: right;
655+}
656+
657+/* -- sidebars -------------------------------------------------------------- */
658+
659+div.sidebar {
660+ margin: 0 0 0.5em 1em;
661+ border: 1px solid #ddb;
662+ padding: 7px 7px 0 7px;
663+ background-color: #ffe;
664+ width: 40%;
665+ float: right;
666+}
667+
668+p.sidebar-title {
669+ font-weight: bold;
670+}
671+
672+/* -- topics ---------------------------------------------------------------- */
673+
674+div.topic {
675+ border: 1px solid #ccc;
676+ padding: 7px 7px 0 7px;
677+ margin: 10px 0 10px 0;
678+}
679+
680+p.topic-title {
681+ font-size: 1.1em;
682+ font-weight: bold;
683+ margin-top: 10px;
684+}
685+
686+/* -- admonitions ----------------------------------------------------------- */
687+
688+div.admonition {
689+ margin-top: 10px;
690+ margin-bottom: 10px;
691+ padding: 7px;
692+}
693+
694+div.admonition dt {
695+ font-weight: bold;
696+}
697+
698+div.admonition dl {
699+ margin-bottom: 0;
700+}
701+
702+p.admonition-title {
703+ margin: 0px 10px 5px 0px;
704+ font-weight: bold;
705+}
706+
707+div.body p.centered {
708+ text-align: center;
709+ margin-top: 25px;
710+}
711+
712+/* -- tables ---------------------------------------------------------------- */
713+
714+table.docutils {
715+ border: 0;
716+ border-collapse: collapse;
717+}
718+
719+table.docutils td, table.docutils th {
720+ padding: 1px 8px 1px 5px;
721+ border-top: 0;
722+ border-left: 0;
723+ border-right: 0;
724+ border-bottom: 1px solid #aaa;
725+}
726+
727+table.field-list td, table.field-list th {
728+ border: 0 !important;
729+}
730+
731+table.footnote td, table.footnote th {
732+ border: 0 !important;
733+}
734+
735+th {
736+ text-align: left;
737+ padding-right: 5px;
738+}
739+
740+table.citation {
741+ border-left: solid 1px gray;
742+ margin-left: 1px;
743+}
744+
745+table.citation td {
746+ border-bottom: none;
747+}
748+
749+/* -- other body styles ----------------------------------------------------- */
750+
751+ol.arabic {
752+ list-style: decimal;
753+}
754+
755+ol.loweralpha {
756+ list-style: lower-alpha;
757+}
758+
759+ol.upperalpha {
760+ list-style: upper-alpha;
761+}
762+
763+ol.lowerroman {
764+ list-style: lower-roman;
765+}
766+
767+ol.upperroman {
768+ list-style: upper-roman;
769+}
770+
771+dl {
772+ margin-bottom: 15px;
773+}
774+
775+dd p {
776+ margin-top: 0px;
777+}
778+
779+dd ul, dd table {
780+ margin-bottom: 10px;
781+}
782+
783+dd {
784+ margin-top: 3px;
785+ margin-bottom: 10px;
786+ margin-left: 30px;
787+}
788+
789+dt:target, .highlighted {
790+ background-color: #fbe54e;
791+}
792+
793+dl.glossary dt {
794+ font-weight: bold;
795+ font-size: 1.1em;
796+}
797+
798+.field-list ul {
799+ margin: 0;
800+ padding-left: 1em;
801+}
802+
803+.field-list p {
804+ margin: 0;
805+}
806+
807+.refcount {
808+ color: #060;
809+}
810+
811+.optional {
812+ font-size: 1.3em;
813+}
814+
815+.versionmodified {
816+ font-style: italic;
817+}
818+
819+.system-message {
820+ background-color: #fda;
821+ padding: 5px;
822+ border: 3px solid red;
823+}
824+
825+.footnote:target {
826+ background-color: #ffa;
827+}
828+
829+.line-block {
830+ display: block;
831+ margin-top: 1em;
832+ margin-bottom: 1em;
833+}
834+
835+.line-block .line-block {
836+ margin-top: 0;
837+ margin-bottom: 0;
838+ margin-left: 1.5em;
839+}
840+
841+.guilabel, .menuselection {
842+ font-family: sans-serif;
843+}
844+
845+.accelerator {
846+ text-decoration: underline;
847+}
848+
849+.classifier {
850+ font-style: oblique;
851+}
852+
853+/* -- code displays --------------------------------------------------------- */
854+
855+pre {
856+ overflow: auto;
857+ overflow-y: hidden; /* fixes display issues on Chrome browsers */
858+}
859+
860+td.linenos pre {
861+ padding: 5px 0px;
862+ border: 0;
863+ background-color: transparent;
864+ color: #aaa;
865+}
866+
867+table.highlighttable {
868+ margin-left: 0.5em;
869+}
870+
871+table.highlighttable td {
872+ padding: 0 0.5em 0 0.5em;
873+}
874+
875+tt.descname {
876+ background-color: transparent;
877+ font-weight: bold;
878+ font-size: 1.2em;
879+}
880+
881+tt.descclassname {
882+ background-color: transparent;
883+}
884+
885+tt.xref, a tt {
886+ background-color: transparent;
887+ font-weight: bold;
888+}
889+
890+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
891+ background-color: transparent;
892+}
893+
894+.viewcode-link {
895+ float: right;
896+}
897+
898+.viewcode-back {
899+ float: right;
900+ font-family: sans-serif;
901+}
902+
903+div.viewcode-block:target {
904+ margin: -1px -10px;
905+ padding: 0 10px;
906+}
907+
908+/* -- math display ---------------------------------------------------------- */
909+
910+img.math {
911+ vertical-align: middle;
912+}
913+
914+div.body div.math p {
915+ text-align: center;
916+}
917+
918+span.eqno {
919+ float: right;
920+}
921+
922+/* -- printout stylesheet --------------------------------------------------- */
923+
924+@media print {
925+ div.document,
926+ div.documentwrapper,
927+ div.bodywrapper {
928+ margin: 0 !important;
929+ width: 100%;
930+ }
931+
932+ div.sphinxsidebar,
933+ div.related,
934+ div.footer,
935+ #top-link {
936+ display: none;
937+ }
938+}
939
940=== added file 'doc/build/html/_static/default.css'
941--- doc/build/html/_static/default.css 1970-01-01 00:00:00 +0000
942+++ doc/build/html/_static/default.css 2012-03-08 09:19:21 +0000
943@@ -0,0 +1,414 @@
944+/*
945+ * default.css_t
946+ * ~~~~~~~~~~~~~
947+ *
948+ * Sphinx stylesheet -- default theme.
949+ *
950+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
951+ * :license: BSD, see LICENSE for details.
952+ *
953+ */
954+
955+@import url("basic.css");
956+
957+/* -- page layout ----------------------------------------------------------- */
958+
959+body {
960+ font-family: Arial,Helvetica,sans-serif;
961+ font-size: 14px;
962+ background-color: #fff;
963+ color: #333333;
964+ line-height: 20px;
965+ margin: 0;
966+ padding: 0;
967+
968+}
969+
970+div.document {
971+ background-color: #fff;
972+ margin: 0 auto;
973+ overflow: hidden;
974+ padding: 30px 0;
975+ width: 960px;
976+}
977+
978+div.documentwrapper {
979+ /* float: left; */
980+ /* width: 100%; */
981+
982+}
983+
984+div.bodywrapper {
985+ margin: 10 0 0 0px;
986+ width: 660px;
987+ float:right;
988+}
989+
990+div.body {
991+ background-color: #fff;
992+ color: #333333;
993+ padding: 0 0 20px;
994+}
995+
996+div.footer {
997+ /* color: #ffffff; */
998+ /* width: 100%; */
999+ /* padding: 9px 0 9px 0; */
1000+ /* text-align: center; */
1001+ /* font-size: 75%; */
1002+ font: 80% "Lucida Grande",Verdana,Lucida,Helvetica,Arial,sans-serif;
1003+ background: none repeat scroll 0 0 #333333;
1004+ border-top: 2px solid #D95200;
1005+ overflow: hidden;
1006+}
1007+
1008+div.footer a {
1009+ color: #ffffff;
1010+ text-decoration: underline;
1011+}
1012+
1013+div.related {
1014+ background-color: #ccc;
1015+ line-height: 30px;
1016+ color: #333;
1017+ background: none repeat scroll 0 0 #F8F8F8;
1018+ border: 1px solid #E0E0E0;
1019+ clear: both;
1020+ padding: 10px;
1021+ width: 635px;
1022+ margin-bottom: 5px;
1023+}
1024+
1025+div.related a {
1026+ color: #999;
1027+}
1028+
1029+div.sphinxsidebar {
1030+ margin-left: 0px;
1031+ margin-right: 30px;
1032+ color: #eee;
1033+ font-family: Arial,Helvetica,sans-serif;
1034+ width: 260px;
1035+}
1036+
1037+div.sphinxsidebar h3 {
1038+ /* font-family: 'Arial', 'Helvetica' sans-serif; */
1039+ color: #999;
1040+ font-size: 18px;
1041+ line-height: 15px;
1042+ font-weight: 400;
1043+ margin-left: 5px;
1044+ padding: 0;
1045+}
1046+
1047+div.sphinxsidebar h3 a {
1048+ color: #333;
1049+}
1050+
1051+div.sphinxsidebar a:hover {
1052+ /* color: #333; */
1053+}
1054+
1055+div.sphinxsidebar h4 {
1056+ /* font-family: 'Arial', 'Helvetica' sans-serif; */
1057+ color: #666;
1058+ font-size: 18px;
1059+ font-weight: normal;
1060+ margin: 5px 0 0 5px;
1061+ padding: 0;
1062+}
1063+
1064+div.sphinxsidebar p {
1065+ color: #333;
1066+ margin-bottom: 5px;
1067+ margin-left: 5px;
1068+}
1069+
1070+div.sphinxsidebar p.topless {
1071+ margin: 5px 10px 10px 10px;
1072+}
1073+
1074+div.sphinxsidebar ul {
1075+ margin: 10px;
1076+ padding-left: 5px;
1077+ color: #333;
1078+}
1079+
1080+div.sphinxsidebar a {
1081+ color: #D12907;
1082+}
1083+
1084+div.sphinxsidebar input {
1085+ border: 1px solid #999;
1086+ font-family: sans-serif;
1087+ font-size: 1em;
1088+}
1089+
1090+
1091+
1092+/* -- hyperlink styles ------------------------------------------------------ */
1093+
1094+a {
1095+ color: #D12907;
1096+ text-decoration: underline;
1097+ border: medium none;
1098+ cursor: pointer;
1099+}
1100+
1101+a:visited {
1102+ color: #D12907;
1103+ text-decoration: underline;
1104+}
1105+
1106+a:hover {
1107+ color: #D12907;
1108+ text-decoration: underline;
1109+}
1110+
1111+
1112+
1113+/* -- body styles ----------------------------------------------------------- */
1114+
1115+div.body h1,
1116+div.body h2,
1117+div.body h3,
1118+div.body h4,
1119+div.body h5,
1120+div.body h6 {
1121+ font-family: Arial,Helvetica,sans-serif;
1122+ background-color: #fff;
1123+ font-weight: 400;
1124+
1125+ /* border-bottom: 1px solid #ccc; */
1126+ /* margin: 20px -20px 10px -20px; */
1127+ /* padding: 0; */
1128+ /* padding: 3px 0 3px 10px; */
1129+ text-decoration: none !important;
1130+
1131+ border-bottom: 1px solid #E0E0E0;
1132+ font-size: 20px;
1133+ line-height: 20px;
1134+ margin: 30px 0 15px;
1135+ padding: 0 0 3px;
1136+ color: #000;
1137+}
1138+
1139+div.body h1 {
1140+ font-size: 32px;
1141+ color: #D12907;
1142+ line-height: 40px;
1143+ margin: 10px 0 20px 0;
1144+ text-decoration: none !important;
1145+ border-bottom: none;
1146+ margin-top: 35px;
1147+}
1148+
1149+div.body h2 { font-size: 150%; }
1150+div.body h3 { font-size: 140%; }
1151+div.body h4 { font-size: 120%; }
1152+div.body h5 { font-size: 110%; }
1153+div.body h6 { font-size: 100%; }
1154+
1155+a.headerlink {
1156+ color: #c60f0f;
1157+ font-size: 0.8em;
1158+ padding: 0 4px 0 4px;
1159+ text-decoration: none;
1160+}
1161+
1162+a.headerlink:hover {
1163+ background-color: #c60f0f;
1164+ color: white;
1165+}
1166+
1167+div.body dd, div.body li {
1168+ text-align: justify;
1169+}
1170+
1171+div.body dt {
1172+ list-style-type: square;
1173+ /* margin: 8px 0 8px 30px; */
1174+ padding: 0 4px 0 5px;
1175+
1176+}
1177+
1178+div.body p {
1179+ text-align: justify;
1180+/* line-height: 130%;*/
1181+ margin: 10px 0;
1182+}
1183+
1184+/* div.body ul, */
1185+div.body li {
1186+ list-style-type: square;
1187+ margin: 8px 0 8px 30px;
1188+ padding: 0 4px 0 5px;
1189+}
1190+
1191+.reference em {
1192+ font-style: normal;
1193+}
1194+
1195+.std-term {
1196+ font-style: normal;
1197+ font-weight: 400;
1198+ color: #FF7400
1199+}
1200+
1201+div.admonition p.admonition-title + p {
1202+ display: inline;
1203+}
1204+
1205+div.admonition p {
1206+ margin-bottom: 5px;
1207+}
1208+
1209+div.admonition pre {
1210+ margin-bottom: 5px;
1211+}
1212+
1213+div.admonition ul, div.admonition ol {
1214+ margin-bottom: 5px;
1215+}
1216+
1217+div.note {
1218+ background-color: #eee;
1219+ border: 1px solid #ccc;
1220+}
1221+
1222+div.seealso {
1223+ background-color: #ffc;
1224+ border: 1px solid #ff6;
1225+}
1226+
1227+div.topic {
1228+ background-color: #eee;
1229+}
1230+
1231+div.warning {
1232+ background-color: #ffe4e4;
1233+ border: 1px solid #f66;
1234+}
1235+
1236+p.admonition-title {
1237+ display: inline;
1238+}
1239+
1240+p.admonition-title:after {
1241+ content: ":";
1242+}
1243+
1244+pre {
1245+ padding: 10px;
1246+ background-color: #F0E6D9/* #eeffcc */;
1247+ color: #333333;
1248+ line-height: 120%;
1249+ border: 1px dashed #ED9821;
1250+ font-size: 80%;
1251+ overflow: auto;
1252+ /* border-left: none; */
1253+ /* border-right: none; */
1254+}
1255+
1256+tt {
1257+/* background-color: #ecf0f3;
1258+ padding: 0 1px 0 1px;
1259+ font-size: 0.95em;*/
1260+ font-weight: 400;
1261+}
1262+
1263+div.body td {
1264+ text-align: none;
1265+}
1266+
1267+table.docutils th {
1268+ background-color: #DEE7EC;
1269+ border: 1px solid #8CACBB;
1270+ padding: 3px;
1271+ text-align: center;
1272+ font-style: normal;
1273+ font-weight: 400;
1274+}
1275+
1276+table.docutils td {
1277+ border: 1px solid #8CACBB;
1278+ padding: 3px;
1279+ line-height: 16px;
1280+ vertical-align: middle;
1281+}
1282+
1283+.warning tt {
1284+ background: #efc2c2;
1285+}
1286+
1287+.note tt {
1288+ background: #d6d6d6;
1289+}
1290+
1291+.viewcode-back {
1292+ font-family: sans-serif;
1293+}
1294+
1295+div.viewcode-block:target {
1296+ background-color: #f4debf;
1297+ border-top: 1px solid #ac9;
1298+ border-bottom: 1px solid #ac9;
1299+}
1300+
1301+.file-bugs {
1302+ background: none repeat scroll 0 0 #E8E8E8;
1303+ border: 1px solid #E0E0E0;
1304+ clear: both;
1305+ color: #333333;
1306+ padding: 10px;
1307+ text-align: center;
1308+ font-size: 90%;
1309+}
1310+
1311+div.footer .footer {
1312+ margin: 0 auto;
1313+ overflow: hidden;
1314+ padding: 10px 0;
1315+ width: 960px;
1316+ border-top: none;
1317+}
1318+
1319+div.footer .footer .logo {
1320+ float: left;
1321+ overflow: hidden;
1322+ padding: 17px 0 0;
1323+}
1324+
1325+div.footer .footer .text {
1326+ color: #E0E0E0;
1327+ float: right;
1328+ font-family: Arial,Helvetica,sans-serif;
1329+ font-size: 11px;
1330+ line-height: 15px;
1331+ overflow: hidden;
1332+ text-align: right;
1333+}
1334+
1335+div.license {
1336+ font-size: 80%;
1337+ /* padding: 0.5em; */
1338+ text-align: center;
1339+ margin: 13px 0 -15px;
1340+}
1341+
1342+#sidenavi.noborder {
1343+ border-right: medium none;
1344+ border-top: medium none;
1345+ margin: 0;
1346+}
1347+
1348+#sidenavi {
1349+ color: #333333;
1350+ /* float: left; */
1351+ font-family: Arial,Helvetica,sans-serif;
1352+ font-size: 18px;
1353+ line-height: 25px;
1354+ overflow: hidden;
1355+ padding: 10px 0 8px 0px;
1356+ width: 255px;
1357+}
1358
1359=== added file 'doc/build/html/_static/doctools.js'
1360--- doc/build/html/_static/doctools.js 1970-01-01 00:00:00 +0000
1361+++ doc/build/html/_static/doctools.js 2012-03-08 09:19:21 +0000
1362@@ -0,0 +1,247 @@
1363+/*
1364+ * doctools.js
1365+ * ~~~~~~~~~~~
1366+ *
1367+ * Sphinx JavaScript utilties for all documentation.
1368+ *
1369+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
1370+ * :license: BSD, see LICENSE for details.
1371+ *
1372+ */
1373+
1374+/**
1375+ * select a different prefix for underscore
1376+ */
1377+$u = _.noConflict();
1378+
1379+/**
1380+ * make the code below compatible with browsers without
1381+ * an installed firebug like debugger
1382+if (!window.console || !console.firebug) {
1383+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
1384+ "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
1385+ "profile", "profileEnd"];
1386+ window.console = {};
1387+ for (var i = 0; i < names.length; ++i)
1388+ window.console[names[i]] = function() {};
1389+}
1390+ */
1391+
1392+/**
1393+ * small helper function to urldecode strings
1394+ */
1395+jQuery.urldecode = function(x) {
1396+ return decodeURIComponent(x).replace(/\+/g, ' ');
1397+}
1398+
1399+/**
1400+ * small helper function to urlencode strings
1401+ */
1402+jQuery.urlencode = encodeURIComponent;
1403+
1404+/**
1405+ * This function returns the parsed url parameters of the
1406+ * current request. Multiple values per key are supported,
1407+ * it will always return arrays of strings for the value parts.
1408+ */
1409+jQuery.getQueryParameters = function(s) {
1410+ if (typeof s == 'undefined')
1411+ s = document.location.search;
1412+ var parts = s.substr(s.indexOf('?') + 1).split('&');
1413+ var result = {};
1414+ for (var i = 0; i < parts.length; i++) {
1415+ var tmp = parts[i].split('=', 2);
1416+ var key = jQuery.urldecode(tmp[0]);
1417+ var value = jQuery.urldecode(tmp[1]);
1418+ if (key in result)
1419+ result[key].push(value);
1420+ else
1421+ result[key] = [value];
1422+ }
1423+ return result;
1424+};
1425+
1426+/**
1427+ * small function to check if an array contains
1428+ * a given item.
1429+ */
1430+jQuery.contains = function(arr, item) {
1431+ for (var i = 0; i < arr.length; i++) {
1432+ if (arr[i] == item)
1433+ return true;
1434+ }
1435+ return false;
1436+};
1437+
1438+/**
1439+ * highlight a given string on a jquery object by wrapping it in
1440+ * span elements with the given class name.
1441+ */
1442+jQuery.fn.highlightText = function(text, className) {
1443+ function highlight(node) {
1444+ if (node.nodeType == 3) {
1445+ var val = node.nodeValue;
1446+ var pos = val.toLowerCase().indexOf(text);
1447+ if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
1448+ var span = document.createElement("span");
1449+ span.className = className;
1450+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
1451+ node.parentNode.insertBefore(span, node.parentNode.insertBefore(
1452+ document.createTextNode(val.substr(pos + text.length)),
1453+ node.nextSibling));
1454+ node.nodeValue = val.substr(0, pos);
1455+ }
1456+ }
1457+ else if (!jQuery(node).is("button, select, textarea")) {
1458+ jQuery.each(node.childNodes, function() {
1459+ highlight(this);
1460+ });
1461+ }
1462+ }
1463+ return this.each(function() {
1464+ highlight(this);
1465+ });
1466+};
1467+
1468+/**
1469+ * Small JavaScript module for the documentation.
1470+ */
1471+var Documentation = {
1472+
1473+ init : function() {
1474+ this.fixFirefoxAnchorBug();
1475+ this.highlightSearchWords();
1476+ this.initIndexTable();
1477+ },
1478+
1479+ /**
1480+ * i18n support
1481+ */
1482+ TRANSLATIONS : {},
1483+ PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
1484+ LOCALE : 'unknown',
1485+
1486+ // gettext and ngettext don't access this so that the functions
1487+ // can safely bound to a different name (_ = Documentation.gettext)
1488+ gettext : function(string) {
1489+ var translated = Documentation.TRANSLATIONS[string];
1490+ if (typeof translated == 'undefined')
1491+ return string;
1492+ return (typeof translated == 'string') ? translated : translated[0];
1493+ },
1494+
1495+ ngettext : function(singular, plural, n) {
1496+ var translated = Documentation.TRANSLATIONS[singular];
1497+ if (typeof translated == 'undefined')
1498+ return (n == 1) ? singular : plural;
1499+ return translated[Documentation.PLURALEXPR(n)];
1500+ },
1501+
1502+ addTranslations : function(catalog) {
1503+ for (var key in catalog.messages)
1504+ this.TRANSLATIONS[key] = catalog.messages[key];
1505+ this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
1506+ this.LOCALE = catalog.locale;
1507+ },
1508+
1509+ /**
1510+ * add context elements like header anchor links
1511+ */
1512+ addContextElements : function() {
1513+ $('div[id] > :header:first').each(function() {
1514+ $('<a class="headerlink">\u00B6</a>').
1515+ attr('href', '#' + this.id).
1516+ attr('title', _('Permalink to this headline')).
1517+ appendTo(this);
1518+ });
1519+ $('dt[id]').each(function() {
1520+ $('<a class="headerlink">\u00B6</a>').
1521+ attr('href', '#' + this.id).
1522+ attr('title', _('Permalink to this definition')).
1523+ appendTo(this);
1524+ });
1525+ },
1526+
1527+ /**
1528+ * workaround a firefox stupidity
1529+ */
1530+ fixFirefoxAnchorBug : function() {
1531+ if (document.location.hash && $.browser.mozilla)
1532+ window.setTimeout(function() {
1533+ document.location.href += '';
1534+ }, 10);
1535+ },
1536+
1537+ /**
1538+ * highlight the search words provided in the url in the text
1539+ */
1540+ highlightSearchWords : function() {
1541+ var params = $.getQueryParameters();
1542+ var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
1543+ if (terms.length) {
1544+ var body = $('div.body');
1545+ window.setTimeout(function() {
1546+ $.each(terms, function() {
1547+ body.highlightText(this.toLowerCase(), 'highlighted');
1548+ });
1549+ }, 10);
1550+ $('<li class="highlight-link"><a href="javascript:Documentation.' +
1551+ 'hideSearchWords()">' + _('Hide Search Matches') + '</a></li>')
1552+ .appendTo($('.sidebar .this-page-menu'));
1553+ }
1554+ },
1555+
1556+ /**
1557+ * init the domain index toggle buttons
1558+ */
1559+ initIndexTable : function() {
1560+ var togglers = $('img.toggler').click(function() {
1561+ var src = $(this).attr('src');
1562+ var idnum = $(this).attr('id').substr(7);
1563+ $('tr.cg-' + idnum).toggle();
1564+ if (src.substr(-9) == 'minus.png')
1565+ $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
1566+ else
1567+ $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
1568+ }).css('display', '');
1569+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
1570+ togglers.click();
1571+ }
1572+ },
1573+
1574+ /**
1575+ * helper function to hide the search marks again
1576+ */
1577+ hideSearchWords : function() {
1578+ $('.sidebar .this-page-menu li.highlight-link').fadeOut(300);
1579+ $('span.highlighted').removeClass('highlighted');
1580+ },
1581+
1582+ /**
1583+ * make the url absolute
1584+ */
1585+ makeURL : function(relativeURL) {
1586+ return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
1587+ },
1588+
1589+ /**
1590+ * get the current relative url
1591+ */
1592+ getCurrentURL : function() {
1593+ var path = document.location.pathname;
1594+ var parts = path.split(/\//);
1595+ $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
1596+ if (this == '..')
1597+ parts.pop();
1598+ });
1599+ var url = parts.join('/');
1600+ return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
1601+ }
1602+};
1603+
1604+// quick alias for translations
1605+_ = Documentation.gettext;
1606+
1607+$(document).ready(function() {
1608+ Documentation.init();
1609+});
1610
1611=== added file 'doc/build/html/_static/email-small.png'
1612Binary files doc/build/html/_static/email-small.png 1970-01-01 00:00:00 +0000 and doc/build/html/_static/email-small.png 2012-03-08 09:19:21 +0000 differ
1613=== added file 'doc/build/html/_static/file.png'
1614Binary files doc/build/html/_static/file.png 1970-01-01 00:00:00 +0000 and doc/build/html/_static/file.png 2012-03-08 09:19:21 +0000 differ
1615=== added file 'doc/build/html/_static/jquery.js'
1616--- doc/build/html/_static/jquery.js 1970-01-01 00:00:00 +0000
1617+++ doc/build/html/_static/jquery.js 2012-03-08 09:19:21 +0000
1618@@ -0,0 +1,8981 @@
1619+/*!
1620+ * jQuery JavaScript Library v1.6.2
1621+ * http://jquery.com/
1622+ *
1623+ * Copyright 2011, John Resig
1624+ * Dual licensed under the MIT or GPL Version 2 licenses.
1625+ * http://jquery.org/license
1626+ *
1627+ * Includes Sizzle.js
1628+ * http://sizzlejs.com/
1629+ * Copyright 2011, The Dojo Foundation
1630+ * Released under the MIT, BSD, and GPL Licenses.
1631+ *
1632+ * Date: Thu Jun 30 14:16:56 2011 -0400
1633+ */
1634+(function( window, undefined ) {
1635+
1636+// Use the correct document accordingly with window argument (sandbox)
1637+var document = window.document,
1638+ navigator = window.navigator,
1639+ location = window.location;
1640+var jQuery = (function() {
1641+
1642+// Define a local copy of jQuery
1643+var jQuery = function( selector, context ) {
1644+ // The jQuery object is actually just the init constructor 'enhanced'
1645+ return new jQuery.fn.init( selector, context, rootjQuery );
1646+ },
1647+
1648+ // Map over jQuery in case of overwrite
1649+ _jQuery = window.jQuery,
1650+
1651+ // Map over the $ in case of overwrite
1652+ _$ = window.$,
1653+
1654+ // A central reference to the root jQuery(document)
1655+ rootjQuery,
1656+
1657+ // A simple way to check for HTML strings or ID strings
1658+ // (both of which we optimize for)
1659+ quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
1660+
1661+ // Check if a string has a non-whitespace character in it
1662+ rnotwhite = /\S/,
1663+
1664+ // Used for trimming whitespace
1665+ trimLeft = /^\s+/,
1666+ trimRight = /\s+$/,
1667+
1668+ // Check for digits
1669+ rdigit = /\d/,
1670+
1671+ // Match a standalone tag
1672+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
1673+
1674+ // JSON RegExp
1675+ rvalidchars = /^[\],:{}\s]*$/,
1676+ rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
1677+ rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
1678+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
1679+
1680+ // Useragent RegExp
1681+ rwebkit = /(webkit)[ \/]([\w.]+)/,
1682+ ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
1683+ rmsie = /(msie) ([\w.]+)/,
1684+ rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
1685+
1686+ // Matches dashed string for camelizing
1687+ rdashAlpha = /-([a-z])/ig,
1688+
1689+ // Used by jQuery.camelCase as callback to replace()
1690+ fcamelCase = function( all, letter ) {
1691+ return letter.toUpperCase();
1692+ },
1693+
1694+ // Keep a UserAgent string for use with jQuery.browser
1695+ userAgent = navigator.userAgent,
1696+
1697+ // For matching the engine and version of the browser
1698+ browserMatch,
1699+
1700+ // The deferred used on DOM ready
1701+ readyList,
1702+
1703+ // The ready event handler
1704+ DOMContentLoaded,
1705+
1706+ // Save a reference to some core methods
1707+ toString = Object.prototype.toString,
1708+ hasOwn = Object.prototype.hasOwnProperty,
1709+ push = Array.prototype.push,
1710+ slice = Array.prototype.slice,
1711+ trim = String.prototype.trim,
1712+ indexOf = Array.prototype.indexOf,
1713+
1714+ // [[Class]] -> type pairs
1715+ class2type = {};
1716+
1717+jQuery.fn = jQuery.prototype = {
1718+ constructor: jQuery,
1719+ init: function( selector, context, rootjQuery ) {
1720+ var match, elem, ret, doc;
1721+
1722+ // Handle $(""), $(null), or $(undefined)
1723+ if ( !selector ) {
1724+ return this;
1725+ }
1726+
1727+ // Handle $(DOMElement)
1728+ if ( selector.nodeType ) {
1729+ this.context = this[0] = selector;
1730+ this.length = 1;
1731+ return this;
1732+ }
1733+
1734+ // The body element only exists once, optimize finding it
1735+ if ( selector === "body" && !context && document.body ) {
1736+ this.context = document;
1737+ this[0] = document.body;
1738+ this.selector = selector;
1739+ this.length = 1;
1740+ return this;
1741+ }
1742+
1743+ // Handle HTML strings
1744+ if ( typeof selector === "string" ) {
1745+ // Are we dealing with HTML string or an ID?
1746+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
1747+ // Assume that strings that start and end with <> are HTML and skip the regex check
1748+ match = [ null, selector, null ];
1749+
1750+ } else {
1751+ match = quickExpr.exec( selector );
1752+ }
1753+
1754+ // Verify a match, and that no context was specified for #id
1755+ if ( match && (match[1] || !context) ) {
1756+
1757+ // HANDLE: $(html) -> $(array)
1758+ if ( match[1] ) {
1759+ context = context instanceof jQuery ? context[0] : context;
1760+ doc = (context ? context.ownerDocument || context : document);
1761+
1762+ // If a single string is passed in and it's a single tag
1763+ // just do a createElement and skip the rest
1764+ ret = rsingleTag.exec( selector );
1765+
1766+ if ( ret ) {
1767+ if ( jQuery.isPlainObject( context ) ) {
1768+ selector = [ document.createElement( ret[1] ) ];
1769+ jQuery.fn.attr.call( selector, context, true );
1770+
1771+ } else {
1772+ selector = [ doc.createElement( ret[1] ) ];
1773+ }
1774+
1775+ } else {
1776+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
1777+ selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
1778+ }
1779+
1780+ return jQuery.merge( this, selector );
1781+
1782+ // HANDLE: $("#id")
1783+ } else {
1784+ elem = document.getElementById( match[2] );
1785+
1786+ // Check parentNode to catch when Blackberry 4.6 returns
1787+ // nodes that are no longer in the document #6963
1788+ if ( elem && elem.parentNode ) {
1789+ // Handle the case where IE and Opera return items
1790+ // by name instead of ID
1791+ if ( elem.id !== match[2] ) {
1792+ return rootjQuery.find( selector );
1793+ }
1794+
1795+ // Otherwise, we inject the element directly into the jQuery object
1796+ this.length = 1;
1797+ this[0] = elem;
1798+ }
1799+
1800+ this.context = document;
1801+ this.selector = selector;
1802+ return this;
1803+ }
1804+
1805+ // HANDLE: $(expr, $(...))
1806+ } else if ( !context || context.jquery ) {
1807+ return (context || rootjQuery).find( selector );
1808+
1809+ // HANDLE: $(expr, context)
1810+ // (which is just equivalent to: $(context).find(expr)
1811+ } else {
1812+ return this.constructor( context ).find( selector );
1813+ }
1814+
1815+ // HANDLE: $(function)
1816+ // Shortcut for document ready
1817+ } else if ( jQuery.isFunction( selector ) ) {
1818+ return rootjQuery.ready( selector );
1819+ }
1820+
1821+ if (selector.selector !== undefined) {
1822+ this.selector = selector.selector;
1823+ this.context = selector.context;
1824+ }
1825+
1826+ return jQuery.makeArray( selector, this );
1827+ },
1828+
1829+ // Start with an empty selector
1830+ selector: "",
1831+
1832+ // The current version of jQuery being used
1833+ jquery: "1.6.2",
1834+
1835+ // The default length of a jQuery object is 0
1836+ length: 0,
1837+
1838+ // The number of elements contained in the matched element set
1839+ size: function() {
1840+ return this.length;
1841+ },
1842+
1843+ toArray: function() {
1844+ return slice.call( this, 0 );
1845+ },
1846+
1847+ // Get the Nth element in the matched element set OR
1848+ // Get the whole matched element set as a clean array
1849+ get: function( num ) {
1850+ return num == null ?
1851+
1852+ // Return a 'clean' array
1853+ this.toArray() :
1854+
1855+ // Return just the object
1856+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
1857+ },
1858+
1859+ // Take an array of elements and push it onto the stack
1860+ // (returning the new matched element set)
1861+ pushStack: function( elems, name, selector ) {
1862+ // Build a new jQuery matched element set
1863+ var ret = this.constructor();
1864+
1865+ if ( jQuery.isArray( elems ) ) {
1866+ push.apply( ret, elems );
1867+
1868+ } else {
1869+ jQuery.merge( ret, elems );
1870+ }
1871+
1872+ // Add the old object onto the stack (as a reference)
1873+ ret.prevObject = this;
1874+
1875+ ret.context = this.context;
1876+
1877+ if ( name === "find" ) {
1878+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
1879+ } else if ( name ) {
1880+ ret.selector = this.selector + "." + name + "(" + selector + ")";
1881+ }
1882+
1883+ // Return the newly-formed element set
1884+ return ret;
1885+ },
1886+
1887+ // Execute a callback for every element in the matched set.
1888+ // (You can seed the arguments with an array of args, but this is
1889+ // only used internally.)
1890+ each: function( callback, args ) {
1891+ return jQuery.each( this, callback, args );
1892+ },
1893+
1894+ ready: function( fn ) {
1895+ // Attach the listeners
1896+ jQuery.bindReady();
1897+
1898+ // Add the callback
1899+ readyList.done( fn );
1900+
1901+ return this;
1902+ },
1903+
1904+ eq: function( i ) {
1905+ return i === -1 ?
1906+ this.slice( i ) :
1907+ this.slice( i, +i + 1 );
1908+ },
1909+
1910+ first: function() {
1911+ return this.eq( 0 );
1912+ },
1913+
1914+ last: function() {
1915+ return this.eq( -1 );
1916+ },
1917+
1918+ slice: function() {
1919+ return this.pushStack( slice.apply( this, arguments ),
1920+ "slice", slice.call(arguments).join(",") );
1921+ },
1922+
1923+ map: function( callback ) {
1924+ return this.pushStack( jQuery.map(this, function( elem, i ) {
1925+ return callback.call( elem, i, elem );
1926+ }));
1927+ },
1928+
1929+ end: function() {
1930+ return this.prevObject || this.constructor(null);
1931+ },
1932+
1933+ // For internal use only.
1934+ // Behaves like an Array's method, not like a jQuery method.
1935+ push: push,
1936+ sort: [].sort,
1937+ splice: [].splice
1938+};
1939+
1940+// Give the init function the jQuery prototype for later instantiation
1941+jQuery.fn.init.prototype = jQuery.fn;
1942+
1943+jQuery.extend = jQuery.fn.extend = function() {
1944+ var options, name, src, copy, copyIsArray, clone,
1945+ target = arguments[0] || {},
1946+ i = 1,
1947+ length = arguments.length,
1948+ deep = false;
1949+
1950+ // Handle a deep copy situation
1951+ if ( typeof target === "boolean" ) {
1952+ deep = target;
1953+ target = arguments[1] || {};
1954+ // skip the boolean and the target
1955+ i = 2;
1956+ }
1957+
1958+ // Handle case when target is a string or something (possible in deep copy)
1959+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
1960+ target = {};
1961+ }
1962+
1963+ // extend jQuery itself if only one argument is passed
1964+ if ( length === i ) {
1965+ target = this;
1966+ --i;
1967+ }
1968+
1969+ for ( ; i < length; i++ ) {
1970+ // Only deal with non-null/undefined values
1971+ if ( (options = arguments[ i ]) != null ) {
1972+ // Extend the base object
1973+ for ( name in options ) {
1974+ src = target[ name ];
1975+ copy = options[ name ];
1976+
1977+ // Prevent never-ending loop
1978+ if ( target === copy ) {
1979+ continue;
1980+ }
1981+
1982+ // Recurse if we're merging plain objects or arrays
1983+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
1984+ if ( copyIsArray ) {
1985+ copyIsArray = false;
1986+ clone = src && jQuery.isArray(src) ? src : [];
1987+
1988+ } else {
1989+ clone = src && jQuery.isPlainObject(src) ? src : {};
1990+ }
1991+
1992+ // Never move original objects, clone them
1993+ target[ name ] = jQuery.extend( deep, clone, copy );
1994+
1995+ // Don't bring in undefined values
1996+ } else if ( copy !== undefined ) {
1997+ target[ name ] = copy;
1998+ }
1999+ }
2000+ }
2001+ }
2002+
2003+ // Return the modified object
2004+ return target;
2005+};
2006+
2007+jQuery.extend({
2008+ noConflict: function( deep ) {
2009+ if ( window.$ === jQuery ) {
2010+ window.$ = _$;
2011+ }
2012+
2013+ if ( deep && window.jQuery === jQuery ) {
2014+ window.jQuery = _jQuery;
2015+ }
2016+
2017+ return jQuery;
2018+ },
2019+
2020+ // Is the DOM ready to be used? Set to true once it occurs.
2021+ isReady: false,
2022+
2023+ // A counter to track how many items to wait for before
2024+ // the ready event fires. See #6781
2025+ readyWait: 1,
2026+
2027+ // Hold (or release) the ready event
2028+ holdReady: function( hold ) {
2029+ if ( hold ) {
2030+ jQuery.readyWait++;
2031+ } else {
2032+ jQuery.ready( true );
2033+ }
2034+ },
2035+
2036+ // Handle when the DOM is ready
2037+ ready: function( wait ) {
2038+ // Either a released hold or an DOMready/load event and not yet ready
2039+ if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
2040+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
2041+ if ( !document.body ) {
2042+ return setTimeout( jQuery.ready, 1 );
2043+ }
2044+
2045+ // Remember that the DOM is ready
2046+ jQuery.isReady = true;
2047+
2048+ // If a normal DOM Ready event fired, decrement, and wait if need be
2049+ if ( wait !== true && --jQuery.readyWait > 0 ) {
2050+ return;
2051+ }
2052+
2053+ // If there are functions bound, to execute
2054+ readyList.resolveWith( document, [ jQuery ] );
2055+
2056+ // Trigger any bound ready events
2057+ if ( jQuery.fn.trigger ) {
2058+ jQuery( document ).trigger( "ready" ).unbind( "ready" );
2059+ }
2060+ }
2061+ },
2062+
2063+ bindReady: function() {
2064+ if ( readyList ) {
2065+ return;
2066+ }
2067+
2068+ readyList = jQuery._Deferred();
2069+
2070+ // Catch cases where $(document).ready() is called after the
2071+ // browser event has already occurred.
2072+ if ( document.readyState === "complete" ) {
2073+ // Handle it asynchronously to allow scripts the opportunity to delay ready
2074+ return setTimeout( jQuery.ready, 1 );
2075+ }
2076+
2077+ // Mozilla, Opera and webkit nightlies currently support this event
2078+ if ( document.addEventListener ) {
2079+ // Use the handy event callback
2080+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
2081+
2082+ // A fallback to window.onload, that will always work
2083+ window.addEventListener( "load", jQuery.ready, false );
2084+
2085+ // If IE event model is used
2086+ } else if ( document.attachEvent ) {
2087+ // ensure firing before onload,
2088+ // maybe late but safe also for iframes
2089+ document.attachEvent( "onreadystatechange", DOMContentLoaded );
2090+
2091+ // A fallback to window.onload, that will always work
2092+ window.attachEvent( "onload", jQuery.ready );
2093+
2094+ // If IE and not a frame
2095+ // continually check to see if the document is ready
2096+ var toplevel = false;
2097+
2098+ try {
2099+ toplevel = window.frameElement == null;
2100+ } catch(e) {}
2101+
2102+ if ( document.documentElement.doScroll && toplevel ) {
2103+ doScrollCheck();
2104+ }
2105+ }
2106+ },
2107+
2108+ // See test/unit/core.js for details concerning isFunction.
2109+ // Since version 1.3, DOM methods and functions like alert
2110+ // aren't supported. They return false on IE (#2968).
2111+ isFunction: function( obj ) {
2112+ return jQuery.type(obj) === "function";
2113+ },
2114+
2115+ isArray: Array.isArray || function( obj ) {
2116+ return jQuery.type(obj) === "array";
2117+ },
2118+
2119+ // A crude way of determining if an object is a window
2120+ isWindow: function( obj ) {
2121+ return obj && typeof obj === "object" && "setInterval" in obj;
2122+ },
2123+
2124+ isNaN: function( obj ) {
2125+ return obj == null || !rdigit.test( obj ) || isNaN( obj );
2126+ },
2127+
2128+ type: function( obj ) {
2129+ return obj == null ?
2130+ String( obj ) :
2131+ class2type[ toString.call(obj) ] || "object";
2132+ },
2133+
2134+ isPlainObject: function( obj ) {
2135+ // Must be an Object.
2136+ // Because of IE, we also have to check the presence of the constructor property.
2137+ // Make sure that DOM nodes and window objects don't pass through, as well
2138+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
2139+ return false;
2140+ }
2141+
2142+ // Not own constructor property must be Object
2143+ if ( obj.constructor &&
2144+ !hasOwn.call(obj, "constructor") &&
2145+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
2146+ return false;
2147+ }
2148+
2149+ // Own properties are enumerated firstly, so to speed up,
2150+ // if last one is own, then all properties are own.
2151+
2152+ var key;
2153+ for ( key in obj ) {}
2154+
2155+ return key === undefined || hasOwn.call( obj, key );
2156+ },
2157+
2158+ isEmptyObject: function( obj ) {
2159+ for ( var name in obj ) {
2160+ return false;
2161+ }
2162+ return true;
2163+ },
2164+
2165+ error: function( msg ) {
2166+ throw msg;
2167+ },
2168+
2169+ parseJSON: function( data ) {
2170+ if ( typeof data !== "string" || !data ) {
2171+ return null;
2172+ }
2173+
2174+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
2175+ data = jQuery.trim( data );
2176+
2177+ // Attempt to parse using the native JSON parser first
2178+ if ( window.JSON && window.JSON.parse ) {
2179+ return window.JSON.parse( data );
2180+ }
2181+
2182+ // Make sure the incoming data is actual JSON
2183+ // Logic borrowed from http://json.org/json2.js
2184+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
2185+ .replace( rvalidtokens, "]" )
2186+ .replace( rvalidbraces, "")) ) {
2187+
2188+ return (new Function( "return " + data ))();
2189+
2190+ }
2191+ jQuery.error( "Invalid JSON: " + data );
2192+ },
2193+
2194+ // Cross-browser xml parsing
2195+ // (xml & tmp used internally)
2196+ parseXML: function( data , xml , tmp ) {
2197+
2198+ if ( window.DOMParser ) { // Standard
2199+ tmp = new DOMParser();
2200+ xml = tmp.parseFromString( data , "text/xml" );
2201+ } else { // IE
2202+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
2203+ xml.async = "false";
2204+ xml.loadXML( data );
2205+ }
2206+
2207+ tmp = xml.documentElement;
2208+
2209+ if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
2210+ jQuery.error( "Invalid XML: " + data );
2211+ }
2212+
2213+ return xml;
2214+ },
2215+
2216+ noop: function() {},
2217+
2218+ // Evaluates a script in a global context
2219+ // Workarounds based on findings by Jim Driscoll
2220+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
2221+ globalEval: function( data ) {
2222+ if ( data && rnotwhite.test( data ) ) {
2223+ // We use execScript on Internet Explorer
2224+ // We use an anonymous function so that context is window
2225+ // rather than jQuery in Firefox
2226+ ( window.execScript || function( data ) {
2227+ window[ "eval" ].call( window, data );
2228+ } )( data );
2229+ }
2230+ },
2231+
2232+ // Converts a dashed string to camelCased string;
2233+ // Used by both the css and data modules
2234+ camelCase: function( string ) {
2235+ return string.replace( rdashAlpha, fcamelCase );
2236+ },
2237+
2238+ nodeName: function( elem, name ) {
2239+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
2240+ },
2241+
2242+ // args is for internal usage only
2243+ each: function( object, callback, args ) {
2244+ var name, i = 0,
2245+ length = object.length,
2246+ isObj = length === undefined || jQuery.isFunction( object );
2247+
2248+ if ( args ) {
2249+ if ( isObj ) {
2250+ for ( name in object ) {
2251+ if ( callback.apply( object[ name ], args ) === false ) {
2252+ break;
2253+ }
2254+ }
2255+ } else {
2256+ for ( ; i < length; ) {
2257+ if ( callback.apply( object[ i++ ], args ) === false ) {
2258+ break;
2259+ }
2260+ }
2261+ }
2262+
2263+ // A special, fast, case for the most common use of each
2264+ } else {
2265+ if ( isObj ) {
2266+ for ( name in object ) {
2267+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
2268+ break;
2269+ }
2270+ }
2271+ } else {
2272+ for ( ; i < length; ) {
2273+ if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
2274+ break;
2275+ }
2276+ }
2277+ }
2278+ }
2279+
2280+ return object;
2281+ },
2282+
2283+ // Use native String.trim function wherever possible
2284+ trim: trim ?
2285+ function( text ) {
2286+ return text == null ?
2287+ "" :
2288+ trim.call( text );
2289+ } :
2290+
2291+ // Otherwise use our own trimming functionality
2292+ function( text ) {
2293+ return text == null ?
2294+ "" :
2295+ text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
2296+ },
2297+
2298+ // results is for internal usage only
2299+ makeArray: function( array, results ) {
2300+ var ret = results || [];
2301+
2302+ if ( array != null ) {
2303+ // The window, strings (and functions) also have 'length'
2304+ // The extra typeof function check is to prevent crashes
2305+ // in Safari 2 (See: #3039)
2306+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
2307+ var type = jQuery.type( array );
2308+
2309+ if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
2310+ push.call( ret, array );
2311+ } else {
2312+ jQuery.merge( ret, array );
2313+ }
2314+ }
2315+
2316+ return ret;
2317+ },
2318+
2319+ inArray: function( elem, array ) {
2320+
2321+ if ( indexOf ) {
2322+ return indexOf.call( array, elem );
2323+ }
2324+
2325+ for ( var i = 0, length = array.length; i < length; i++ ) {
2326+ if ( array[ i ] === elem ) {
2327+ return i;
2328+ }
2329+ }
2330+
2331+ return -1;
2332+ },
2333+
2334+ merge: function( first, second ) {
2335+ var i = first.length,
2336+ j = 0;
2337+
2338+ if ( typeof second.length === "number" ) {
2339+ for ( var l = second.length; j < l; j++ ) {
2340+ first[ i++ ] = second[ j ];
2341+ }
2342+
2343+ } else {
2344+ while ( second[j] !== undefined ) {
2345+ first[ i++ ] = second[ j++ ];
2346+ }
2347+ }
2348+
2349+ first.length = i;
2350+
2351+ return first;
2352+ },
2353+
2354+ grep: function( elems, callback, inv ) {
2355+ var ret = [], retVal;
2356+ inv = !!inv;
2357+
2358+ // Go through the array, only saving the items
2359+ // that pass the validator function
2360+ for ( var i = 0, length = elems.length; i < length; i++ ) {
2361+ retVal = !!callback( elems[ i ], i );
2362+ if ( inv !== retVal ) {
2363+ ret.push( elems[ i ] );
2364+ }
2365+ }
2366+
2367+ return ret;
2368+ },
2369+
2370+ // arg is for internal usage only
2371+ map: function( elems, callback, arg ) {
2372+ var value, key, ret = [],
2373+ i = 0,
2374+ length = elems.length,
2375+ // jquery objects are treated as arrays
2376+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
2377+
2378+ // Go through the array, translating each of the items to their
2379+ if ( isArray ) {
2380+ for ( ; i < length; i++ ) {
2381+ value = callback( elems[ i ], i, arg );
2382+
2383+ if ( value != null ) {
2384+ ret[ ret.length ] = value;
2385+ }
2386+ }
2387+
2388+ // Go through every key on the object,
2389+ } else {
2390+ for ( key in elems ) {
2391+ value = callback( elems[ key ], key, arg );
2392+
2393+ if ( value != null ) {
2394+ ret[ ret.length ] = value;
2395+ }
2396+ }
2397+ }
2398+
2399+ // Flatten any nested arrays
2400+ return ret.concat.apply( [], ret );
2401+ },
2402+
2403+ // A global GUID counter for objects
2404+ guid: 1,
2405+
2406+ // Bind a function to a context, optionally partially applying any
2407+ // arguments.
2408+ proxy: function( fn, context ) {
2409+ if ( typeof context === "string" ) {
2410+ var tmp = fn[ context ];
2411+ context = fn;
2412+ fn = tmp;
2413+ }
2414+
2415+ // Quick check to determine if target is callable, in the spec
2416+ // this throws a TypeError, but we will just return undefined.
2417+ if ( !jQuery.isFunction( fn ) ) {
2418+ return undefined;
2419+ }
2420+
2421+ // Simulated bind
2422+ var args = slice.call( arguments, 2 ),
2423+ proxy = function() {
2424+ return fn.apply( context, args.concat( slice.call( arguments ) ) );
2425+ };
2426+
2427+ // Set the guid of unique handler to the same of original handler, so it can be removed
2428+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
2429+
2430+ return proxy;
2431+ },
2432+
2433+ // Mutifunctional method to get and set values to a collection
2434+ // The value/s can optionally be executed if it's a function
2435+ access: function( elems, key, value, exec, fn, pass ) {
2436+ var length = elems.length;
2437+
2438+ // Setting many attributes
2439+ if ( typeof key === "object" ) {
2440+ for ( var k in key ) {
2441+ jQuery.access( elems, k, key[k], exec, fn, value );
2442+ }
2443+ return elems;
2444+ }
2445+
2446+ // Setting one attribute
2447+ if ( value !== undefined ) {
2448+ // Optionally, function values get executed if exec is true
2449+ exec = !pass && exec && jQuery.isFunction(value);
2450+
2451+ for ( var i = 0; i < length; i++ ) {
2452+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
2453+ }
2454+
2455+ return elems;
2456+ }
2457+
2458+ // Getting an attribute
2459+ return length ? fn( elems[0], key ) : undefined;
2460+ },
2461+
2462+ now: function() {
2463+ return (new Date()).getTime();
2464+ },
2465+
2466+ // Use of jQuery.browser is frowned upon.
2467+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
2468+ uaMatch: function( ua ) {
2469+ ua = ua.toLowerCase();
2470+
2471+ var match = rwebkit.exec( ua ) ||
2472+ ropera.exec( ua ) ||
2473+ rmsie.exec( ua ) ||
2474+ ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
2475+ [];
2476+
2477+ return { browser: match[1] || "", version: match[2] || "0" };
2478+ },
2479+
2480+ sub: function() {
2481+ function jQuerySub( selector, context ) {
2482+ return new jQuerySub.fn.init( selector, context );
2483+ }
2484+ jQuery.extend( true, jQuerySub, this );
2485+ jQuerySub.superclass = this;
2486+ jQuerySub.fn = jQuerySub.prototype = this();
2487+ jQuerySub.fn.constructor = jQuerySub;
2488+ jQuerySub.sub = this.sub;
2489+ jQuerySub.fn.init = function init( selector, context ) {
2490+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
2491+ context = jQuerySub( context );
2492+ }
2493+
2494+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
2495+ };
2496+ jQuerySub.fn.init.prototype = jQuerySub.fn;
2497+ var rootjQuerySub = jQuerySub(document);
2498+ return jQuerySub;
2499+ },
2500+
2501+ browser: {}
2502+});
2503+
2504+// Populate the class2type map
2505+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
2506+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
2507+});
2508+
2509+browserMatch = jQuery.uaMatch( userAgent );
2510+if ( browserMatch.browser ) {
2511+ jQuery.browser[ browserMatch.browser ] = true;
2512+ jQuery.browser.version = browserMatch.version;
2513+}
2514+
2515+// Deprecated, use jQuery.browser.webkit instead
2516+if ( jQuery.browser.webkit ) {
2517+ jQuery.browser.safari = true;
2518+}
2519+
2520+// IE doesn't match non-breaking spaces with \s
2521+if ( rnotwhite.test( "\xA0" ) ) {
2522+ trimLeft = /^[\s\xA0]+/;
2523+ trimRight = /[\s\xA0]+$/;
2524+}
2525+
2526+// All jQuery objects should point back to these
2527+rootjQuery = jQuery(document);
2528+
2529+// Cleanup functions for the document ready method
2530+if ( document.addEventListener ) {
2531+ DOMContentLoaded = function() {
2532+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
2533+ jQuery.ready();
2534+ };
2535+
2536+} else if ( document.attachEvent ) {
2537+ DOMContentLoaded = function() {
2538+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
2539+ if ( document.readyState === "complete" ) {
2540+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
2541+ jQuery.ready();
2542+ }
2543+ };
2544+}
2545+
2546+// The DOM ready check for Internet Explorer
2547+function doScrollCheck() {
2548+ if ( jQuery.isReady ) {
2549+ return;
2550+ }
2551+
2552+ try {
2553+ // If IE is used, use the trick by Diego Perini
2554+ // http://javascript.nwbox.com/IEContentLoaded/
2555+ document.documentElement.doScroll("left");
2556+ } catch(e) {
2557+ setTimeout( doScrollCheck, 1 );
2558+ return;
2559+ }
2560+
2561+ // and execute any waiting functions
2562+ jQuery.ready();
2563+}
2564+
2565+return jQuery;
2566+
2567+})();
2568+
2569+
2570+var // Promise methods
2571+ promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
2572+ // Static reference to slice
2573+ sliceDeferred = [].slice;
2574+
2575+jQuery.extend({
2576+ // Create a simple deferred (one callbacks list)
2577+ _Deferred: function() {
2578+ var // callbacks list
2579+ callbacks = [],
2580+ // stored [ context , args ]
2581+ fired,
2582+ // to avoid firing when already doing so
2583+ firing,
2584+ // flag to know if the deferred has been cancelled
2585+ cancelled,
2586+ // the deferred itself
2587+ deferred = {
2588+
2589+ // done( f1, f2, ...)
2590+ done: function() {
2591+ if ( !cancelled ) {
2592+ var args = arguments,
2593+ i,
2594+ length,
2595+ elem,
2596+ type,
2597+ _fired;
2598+ if ( fired ) {
2599+ _fired = fired;
2600+ fired = 0;
2601+ }
2602+ for ( i = 0, length = args.length; i < length; i++ ) {
2603+ elem = args[ i ];
2604+ type = jQuery.type( elem );
2605+ if ( type === "array" ) {
2606+ deferred.done.apply( deferred, elem );
2607+ } else if ( type === "function" ) {
2608+ callbacks.push( elem );
2609+ }
2610+ }
2611+ if ( _fired ) {
2612+ deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
2613+ }
2614+ }
2615+ return this;
2616+ },
2617+
2618+ // resolve with given context and args
2619+ resolveWith: function( context, args ) {
2620+ if ( !cancelled && !fired && !firing ) {
2621+ // make sure args are available (#8421)
2622+ args = args || [];
2623+ firing = 1;
2624+ try {
2625+ while( callbacks[ 0 ] ) {
2626+ callbacks.shift().apply( context, args );
2627+ }
2628+ }
2629+ finally {
2630+ fired = [ context, args ];
2631+ firing = 0;
2632+ }
2633+ }
2634+ return this;
2635+ },
2636+
2637+ // resolve with this as context and given arguments
2638+ resolve: function() {
2639+ deferred.resolveWith( this, arguments );
2640+ return this;
2641+ },
2642+
2643+ // Has this deferred been resolved?
2644+ isResolved: function() {
2645+ return !!( firing || fired );
2646+ },
2647+
2648+ // Cancel
2649+ cancel: function() {
2650+ cancelled = 1;
2651+ callbacks = [];
2652+ return this;
2653+ }
2654+ };
2655+
2656+ return deferred;
2657+ },
2658+
2659+ // Full fledged deferred (two callbacks list)
2660+ Deferred: function( func ) {
2661+ var deferred = jQuery._Deferred(),
2662+ failDeferred = jQuery._Deferred(),
2663+ promise;
2664+ // Add errorDeferred methods, then and promise
2665+ jQuery.extend( deferred, {
2666+ then: function( doneCallbacks, failCallbacks ) {
2667+ deferred.done( doneCallbacks ).fail( failCallbacks );
2668+ return this;
2669+ },
2670+ always: function() {
2671+ return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
2672+ },
2673+ fail: failDeferred.done,
2674+ rejectWith: failDeferred.resolveWith,
2675+ reject: failDeferred.resolve,
2676+ isRejected: failDeferred.isResolved,
2677+ pipe: function( fnDone, fnFail ) {
2678+ return jQuery.Deferred(function( newDefer ) {
2679+ jQuery.each( {
2680+ done: [ fnDone, "resolve" ],
2681+ fail: [ fnFail, "reject" ]
2682+ }, function( handler, data ) {
2683+ var fn = data[ 0 ],
2684+ action = data[ 1 ],
2685+ returned;
2686+ if ( jQuery.isFunction( fn ) ) {
2687+ deferred[ handler ](function() {
2688+ returned = fn.apply( this, arguments );
2689+ if ( returned && jQuery.isFunction( returned.promise ) ) {
2690+ returned.promise().then( newDefer.resolve, newDefer.reject );
2691+ } else {
2692+ newDefer[ action ]( returned );
2693+ }
2694+ });
2695+ } else {
2696+ deferred[ handler ]( newDefer[ action ] );
2697+ }
2698+ });
2699+ }).promise();
2700+ },
2701+ // Get a promise for this deferred
2702+ // If obj is provided, the promise aspect is added to the object
2703+ promise: function( obj ) {
2704+ if ( obj == null ) {
2705+ if ( promise ) {
2706+ return promise;
2707+ }
2708+ promise = obj = {};
2709+ }
2710+ var i = promiseMethods.length;
2711+ while( i-- ) {
2712+ obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
2713+ }
2714+ return obj;
2715+ }
2716+ });
2717+ // Make sure only one callback list will be used
2718+ deferred.done( failDeferred.cancel ).fail( deferred.cancel );
2719+ // Unexpose cancel
2720+ delete deferred.cancel;
2721+ // Call given func if any
2722+ if ( func ) {
2723+ func.call( deferred, deferred );
2724+ }
2725+ return deferred;
2726+ },
2727+
2728+ // Deferred helper
2729+ when: function( firstParam ) {
2730+ var args = arguments,
2731+ i = 0,
2732+ length = args.length,
2733+ count = length,
2734+ deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
2735+ firstParam :
2736+ jQuery.Deferred();
2737+ function resolveFunc( i ) {
2738+ return function( value ) {
2739+ args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
2740+ if ( !( --count ) ) {
2741+ // Strange bug in FF4:
2742+ // Values changed onto the arguments object sometimes end up as undefined values
2743+ // outside the $.when method. Cloning the object into a fresh array solves the issue
2744+ deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
2745+ }
2746+ };
2747+ }
2748+ if ( length > 1 ) {
2749+ for( ; i < length; i++ ) {
2750+ if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
2751+ args[ i ].promise().then( resolveFunc(i), deferred.reject );
2752+ } else {
2753+ --count;
2754+ }
2755+ }
2756+ if ( !count ) {
2757+ deferred.resolveWith( deferred, args );
2758+ }
2759+ } else if ( deferred !== firstParam ) {
2760+ deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
2761+ }
2762+ return deferred.promise();
2763+ }
2764+});
2765+
2766+
2767+
2768+jQuery.support = (function() {
2769+
2770+ var div = document.createElement( "div" ),
2771+ documentElement = document.documentElement,
2772+ all,
2773+ a,
2774+ select,
2775+ opt,
2776+ input,
2777+ marginDiv,
2778+ support,
2779+ fragment,
2780+ body,
2781+ testElementParent,
2782+ testElement,
2783+ testElementStyle,
2784+ tds,
2785+ events,
2786+ eventName,
2787+ i,
2788+ isSupported;
2789+
2790+ // Preliminary tests
2791+ div.setAttribute("className", "t");
2792+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
2793+
2794+ all = div.getElementsByTagName( "*" );
2795+ a = div.getElementsByTagName( "a" )[ 0 ];
2796+
2797+ // Can't get basic test support
2798+ if ( !all || !all.length || !a ) {
2799+ return {};
2800+ }
2801+
2802+ // First batch of supports tests
2803+ select = document.createElement( "select" );
2804+ opt = select.appendChild( document.createElement("option") );
2805+ input = div.getElementsByTagName( "input" )[ 0 ];
2806+
2807+ support = {
2808+ // IE strips leading whitespace when .innerHTML is used
2809+ leadingWhitespace: ( div.firstChild.nodeType === 3 ),
2810+
2811+ // Make sure that tbody elements aren't automatically inserted
2812+ // IE will insert them into empty tables
2813+ tbody: !div.getElementsByTagName( "tbody" ).length,
2814+
2815+ // Make sure that link elements get serialized correctly by innerHTML
2816+ // This requires a wrapper element in IE
2817+ htmlSerialize: !!div.getElementsByTagName( "link" ).length,
2818+
2819+ // Get the style information from getAttribute
2820+ // (IE uses .cssText instead)
2821+ style: /top/.test( a.getAttribute("style") ),
2822+
2823+ // Make sure that URLs aren't manipulated
2824+ // (IE normalizes it by default)
2825+ hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
2826+
2827+ // Make sure that element opacity exists
2828+ // (IE uses filter instead)
2829+ // Use a regex to work around a WebKit issue. See #5145
2830+ opacity: /^0.55$/.test( a.style.opacity ),
2831+
2832+ // Verify style float existence
2833+ // (IE uses styleFloat instead of cssFloat)
2834+ cssFloat: !!a.style.cssFloat,
2835+
2836+ // Make sure that if no value is specified for a checkbox
2837+ // that it defaults to "on".
2838+ // (WebKit defaults to "" instead)
2839+ checkOn: ( input.value === "on" ),
2840+
2841+ // Make sure that a selected-by-default option has a working selected property.
2842+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
2843+ optSelected: opt.selected,
2844+
2845+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
2846+ getSetAttribute: div.className !== "t",
2847+
2848+ // Will be defined later
2849+ submitBubbles: true,
2850+ changeBubbles: true,
2851+ focusinBubbles: false,
2852+ deleteExpando: true,
2853+ noCloneEvent: true,
2854+ inlineBlockNeedsLayout: false,
2855+ shrinkWrapBlocks: false,
2856+ reliableMarginRight: true
2857+ };
2858+
2859+ // Make sure checked status is properly cloned
2860+ input.checked = true;
2861+ support.noCloneChecked = input.cloneNode( true ).checked;
2862+
2863+ // Make sure that the options inside disabled selects aren't marked as disabled
2864+ // (WebKit marks them as disabled)
2865+ select.disabled = true;
2866+ support.optDisabled = !opt.disabled;
2867+
2868+ // Test to see if it's possible to delete an expando from an element
2869+ // Fails in Internet Explorer
2870+ try {
2871+ delete div.test;
2872+ } catch( e ) {
2873+ support.deleteExpando = false;
2874+ }
2875+
2876+ if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
2877+ div.attachEvent( "onclick", function() {
2878+ // Cloning a node shouldn't copy over any
2879+ // bound event handlers (IE does this)
2880+ support.noCloneEvent = false;
2881+ });
2882+ div.cloneNode( true ).fireEvent( "onclick" );
2883+ }
2884+
2885+ // Check if a radio maintains it's value
2886+ // after being appended to the DOM
2887+ input = document.createElement("input");
2888+ input.value = "t";
2889+ input.setAttribute("type", "radio");
2890+ support.radioValue = input.value === "t";
2891+
2892+ input.setAttribute("checked", "checked");
2893+ div.appendChild( input );
2894+ fragment = document.createDocumentFragment();
2895+ fragment.appendChild( div.firstChild );
2896+
2897+ // WebKit doesn't clone checked state correctly in fragments
2898+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
2899+
2900+ div.innerHTML = "";
2901+
2902+ // Figure out if the W3C box model works as expected
2903+ div.style.width = div.style.paddingLeft = "1px";
2904+
2905+ body = document.getElementsByTagName( "body" )[ 0 ];
2906+ // We use our own, invisible, body unless the body is already present
2907+ // in which case we use a div (#9239)
2908+ testElement = document.createElement( body ? "div" : "body" );
2909+ testElementStyle = {
2910+ visibility: "hidden",
2911+ width: 0,
2912+ height: 0,
2913+ border: 0,
2914+ margin: 0
2915+ };
2916+ if ( body ) {
2917+ jQuery.extend( testElementStyle, {
2918+ position: "absolute",
2919+ left: -1000,
2920+ top: -1000
2921+ });
2922+ }
2923+ for ( i in testElementStyle ) {
2924+ testElement.style[ i ] = testElementStyle[ i ];
2925+ }
2926+ testElement.appendChild( div );
2927+ testElementParent = body || documentElement;
2928+ testElementParent.insertBefore( testElement, testElementParent.firstChild );
2929+
2930+ // Check if a disconnected checkbox will retain its checked
2931+ // value of true after appended to the DOM (IE6/7)
2932+ support.appendChecked = input.checked;
2933+
2934+ support.boxModel = div.offsetWidth === 2;
2935+
2936+ if ( "zoom" in div.style ) {
2937+ // Check if natively block-level elements act like inline-block
2938+ // elements when setting their display to 'inline' and giving
2939+ // them layout
2940+ // (IE < 8 does this)
2941+ div.style.display = "inline";
2942+ div.style.zoom = 1;
2943+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
2944+
2945+ // Check if elements with layout shrink-wrap their children
2946+ // (IE 6 does this)
2947+ div.style.display = "";
2948+ div.innerHTML = "<div style='width:4px;'></div>";
2949+ support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
2950+ }
2951+
2952+ div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
2953+ tds = div.getElementsByTagName( "td" );
2954+
2955+ // Check if table cells still have offsetWidth/Height when they are set
2956+ // to display:none and there are still other visible table cells in a
2957+ // table row; if so, offsetWidth/Height are not reliable for use when
2958+ // determining if an element has been hidden directly using
2959+ // display:none (it is still safe to use offsets if a parent element is
2960+ // hidden; don safety goggles and see bug #4512 for more information).
2961+ // (only IE 8 fails this test)
2962+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
2963+
2964+ tds[ 0 ].style.display = "";
2965+ tds[ 1 ].style.display = "none";
2966+
2967+ // Check if empty table cells still have offsetWidth/Height
2968+ // (IE < 8 fail this test)
2969+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
2970+ div.innerHTML = "";
2971+
2972+ // Check if div with explicit width and no margin-right incorrectly
2973+ // gets computed margin-right based on width of container. For more
2974+ // info see bug #3333
2975+ // Fails in WebKit before Feb 2011 nightlies
2976+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
2977+ if ( document.defaultView && document.defaultView.getComputedStyle ) {
2978+ marginDiv = document.createElement( "div" );
2979+ marginDiv.style.width = "0";
2980+ marginDiv.style.marginRight = "0";
2981+ div.appendChild( marginDiv );
2982+ support.reliableMarginRight =
2983+ ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
2984+ }
2985+
2986+ // Remove the body element we added
2987+ testElement.innerHTML = "";
2988+ testElementParent.removeChild( testElement );
2989+
2990+ // Technique from Juriy Zaytsev
2991+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
2992+ // We only care about the case where non-standard event systems
2993+ // are used, namely in IE. Short-circuiting here helps us to
2994+ // avoid an eval call (in setAttribute) which can cause CSP
2995+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
2996+ if ( div.attachEvent ) {
2997+ for( i in {
2998+ submit: 1,
2999+ change: 1,
3000+ focusin: 1
3001+ } ) {
3002+ eventName = "on" + i;
3003+ isSupported = ( eventName in div );
3004+ if ( !isSupported ) {
3005+ div.setAttribute( eventName, "return;" );
3006+ isSupported = ( typeof div[ eventName ] === "function" );
3007+ }
3008+ support[ i + "Bubbles" ] = isSupported;
3009+ }
3010+ }
3011+
3012+ // Null connected elements to avoid leaks in IE
3013+ testElement = fragment = select = opt = body = marginDiv = div = input = null;
3014+
3015+ return support;
3016+})();
3017+
3018+// Keep track of boxModel
3019+jQuery.boxModel = jQuery.support.boxModel;
3020+
3021+
3022+
3023+
3024+var rbrace = /^(?:\{.*\}|\[.*\])$/,
3025+ rmultiDash = /([a-z])([A-Z])/g;
3026+
3027+jQuery.extend({
3028+ cache: {},
3029+
3030+ // Please use with caution
3031+ uuid: 0,
3032+
3033+ // Unique for each copy of jQuery on the page
3034+ // Non-digits removed to match rinlinejQuery
3035+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
3036+
3037+ // The following elements throw uncatchable exceptions if you
3038+ // attempt to add expando properties to them.
3039+ noData: {
3040+ "embed": true,
3041+ // Ban all objects except for Flash (which handle expandos)
3042+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
3043+ "applet": true
3044+ },
3045+
3046+ hasData: function( elem ) {
3047+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
3048+
3049+ return !!elem && !isEmptyDataObject( elem );
3050+ },
3051+
3052+ data: function( elem, name, data, pvt /* Internal Use Only */ ) {
3053+ if ( !jQuery.acceptData( elem ) ) {
3054+ return;
3055+ }
3056+
3057+ var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
3058+
3059+ // We have to handle DOM nodes and JS objects differently because IE6-7
3060+ // can't GC object references properly across the DOM-JS boundary
3061+ isNode = elem.nodeType,
3062+
3063+ // Only DOM nodes need the global jQuery cache; JS object data is
3064+ // attached directly to the object so GC can occur automatically
3065+ cache = isNode ? jQuery.cache : elem,
3066+
3067+ // Only defining an ID for JS objects if its cache already exists allows
3068+ // the code to shortcut on the same path as a DOM node with no cache
3069+ id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
3070+
3071+ // Avoid doing any more work than we need to when trying to get data on an
3072+ // object that has no data at all
3073+ if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
3074+ return;
3075+ }
3076+
3077+ if ( !id ) {
3078+ // Only DOM nodes need a new unique ID for each element since their data
3079+ // ends up in the global cache
3080+ if ( isNode ) {
3081+ elem[ jQuery.expando ] = id = ++jQuery.uuid;
3082+ } else {
3083+ id = jQuery.expando;
3084+ }
3085+ }
3086+
3087+ if ( !cache[ id ] ) {
3088+ cache[ id ] = {};
3089+
3090+ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
3091+ // metadata on plain JS objects when the object is serialized using
3092+ // JSON.stringify
3093+ if ( !isNode ) {
3094+ cache[ id ].toJSON = jQuery.noop;
3095+ }
3096+ }
3097+
3098+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
3099+ // shallow copied over onto the existing cache
3100+ if ( typeof name === "object" || typeof name === "function" ) {
3101+ if ( pvt ) {
3102+ cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
3103+ } else {
3104+ cache[ id ] = jQuery.extend(cache[ id ], name);
3105+ }
3106+ }
3107+
3108+ thisCache = cache[ id ];
3109+
3110+ // Internal jQuery data is stored in a separate object inside the object's data
3111+ // cache in order to avoid key collisions between internal data and user-defined
3112+ // data
3113+ if ( pvt ) {
3114+ if ( !thisCache[ internalKey ] ) {
3115+ thisCache[ internalKey ] = {};
3116+ }
3117+
3118+ thisCache = thisCache[ internalKey ];
3119+ }
3120+
3121+ if ( data !== undefined ) {
3122+ thisCache[ jQuery.camelCase( name ) ] = data;
3123+ }
3124+
3125+ // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
3126+ // not attempt to inspect the internal events object using jQuery.data, as this
3127+ // internal data object is undocumented and subject to change.
3128+ if ( name === "events" && !thisCache[name] ) {
3129+ return thisCache[ internalKey ] && thisCache[ internalKey ].events;
3130+ }
3131+
3132+ return getByName ?
3133+ // Check for both converted-to-camel and non-converted data property names
3134+ thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] :
3135+ thisCache;
3136+ },
3137+
3138+ removeData: function( elem, name, pvt /* Internal Use Only */ ) {
3139+ if ( !jQuery.acceptData( elem ) ) {
3140+ return;
3141+ }
3142+
3143+ var internalKey = jQuery.expando, isNode = elem.nodeType,
3144+
3145+ // See jQuery.data for more information
3146+ cache = isNode ? jQuery.cache : elem,
3147+
3148+ // See jQuery.data for more information
3149+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3150+
3151+ // If there is already no cache entry for this object, there is no
3152+ // purpose in continuing
3153+ if ( !cache[ id ] ) {
3154+ return;
3155+ }
3156+
3157+ if ( name ) {
3158+ var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
3159+
3160+ if ( thisCache ) {
3161+ delete thisCache[ name ];
3162+
3163+ // If there is no data left in the cache, we want to continue
3164+ // and let the cache object itself get destroyed
3165+ if ( !isEmptyDataObject(thisCache) ) {
3166+ return;
3167+ }
3168+ }
3169+ }
3170+
3171+ // See jQuery.data for more information
3172+ if ( pvt ) {
3173+ delete cache[ id ][ internalKey ];
3174+
3175+ // Don't destroy the parent cache unless the internal data object
3176+ // had been the only thing left in it
3177+ if ( !isEmptyDataObject(cache[ id ]) ) {
3178+ return;
3179+ }
3180+ }
3181+
3182+ var internalCache = cache[ id ][ internalKey ];
3183+
3184+ // Browsers that fail expando deletion also refuse to delete expandos on
3185+ // the window, but it will allow it on all other JS objects; other browsers
3186+ // don't care
3187+ if ( jQuery.support.deleteExpando || cache != window ) {
3188+ delete cache[ id ];
3189+ } else {
3190+ cache[ id ] = null;
3191+ }
3192+
3193+ // We destroyed the entire user cache at once because it's faster than
3194+ // iterating through each key, but we need to continue to persist internal
3195+ // data if it existed
3196+ if ( internalCache ) {
3197+ cache[ id ] = {};
3198+ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
3199+ // metadata on plain JS objects when the object is serialized using
3200+ // JSON.stringify
3201+ if ( !isNode ) {
3202+ cache[ id ].toJSON = jQuery.noop;
3203+ }
3204+
3205+ cache[ id ][ internalKey ] = internalCache;
3206+
3207+ // Otherwise, we need to eliminate the expando on the node to avoid
3208+ // false lookups in the cache for entries that no longer exist
3209+ } else if ( isNode ) {
3210+ // IE does not allow us to delete expando properties from nodes,
3211+ // nor does it have a removeAttribute function on Document nodes;
3212+ // we must handle all of these cases
3213+ if ( jQuery.support.deleteExpando ) {
3214+ delete elem[ jQuery.expando ];
3215+ } else if ( elem.removeAttribute ) {
3216+ elem.removeAttribute( jQuery.expando );
3217+ } else {
3218+ elem[ jQuery.expando ] = null;
3219+ }
3220+ }
3221+ },
3222+
3223+ // For internal use only.
3224+ _data: function( elem, name, data ) {
3225+ return jQuery.data( elem, name, data, true );
3226+ },
3227+
3228+ // A method for determining if a DOM node can handle the data expando
3229+ acceptData: function( elem ) {
3230+ if ( elem.nodeName ) {
3231+ var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
3232+
3233+ if ( match ) {
3234+ return !(match === true || elem.getAttribute("classid") !== match);
3235+ }
3236+ }
3237+
3238+ return true;
3239+ }
3240+});
3241+
3242+jQuery.fn.extend({
3243+ data: function( key, value ) {
3244+ var data = null;
3245+
3246+ if ( typeof key === "undefined" ) {
3247+ if ( this.length ) {
3248+ data = jQuery.data( this[0] );
3249+
3250+ if ( this[0].nodeType === 1 ) {
3251+ var attr = this[0].attributes, name;
3252+ for ( var i = 0, l = attr.length; i < l; i++ ) {
3253+ name = attr[i].name;
3254+
3255+ if ( name.indexOf( "data-" ) === 0 ) {
3256+ name = jQuery.camelCase( name.substring(5) );
3257+
3258+ dataAttr( this[0], name, data[ name ] );
3259+ }
3260+ }
3261+ }
3262+ }
3263+
3264+ return data;
3265+
3266+ } else if ( typeof key === "object" ) {
3267+ return this.each(function() {
3268+ jQuery.data( this, key );
3269+ });
3270+ }
3271+
3272+ var parts = key.split(".");
3273+ parts[1] = parts[1] ? "." + parts[1] : "";
3274+
3275+ if ( value === undefined ) {
3276+ data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
3277+
3278+ // Try to fetch any internally stored data first
3279+ if ( data === undefined && this.length ) {
3280+ data = jQuery.data( this[0], key );
3281+ data = dataAttr( this[0], key, data );
3282+ }
3283+
3284+ return data === undefined && parts[1] ?
3285+ this.data( parts[0] ) :
3286+ data;
3287+
3288+ } else {
3289+ return this.each(function() {
3290+ var $this = jQuery( this ),
3291+ args = [ parts[0], value ];
3292+
3293+ $this.triggerHandler( "setData" + parts[1] + "!", args );
3294+ jQuery.data( this, key, value );
3295+ $this.triggerHandler( "changeData" + parts[1] + "!", args );
3296+ });
3297+ }
3298+ },
3299+
3300+ removeData: function( key ) {
3301+ return this.each(function() {
3302+ jQuery.removeData( this, key );
3303+ });
3304+ }
3305+});
3306+
3307+function dataAttr( elem, key, data ) {
3308+ // If nothing was found internally, try to fetch any
3309+ // data from the HTML5 data-* attribute
3310+ if ( data === undefined && elem.nodeType === 1 ) {
3311+ var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
3312+
3313+ data = elem.getAttribute( name );
3314+
3315+ if ( typeof data === "string" ) {
3316+ try {
3317+ data = data === "true" ? true :
3318+ data === "false" ? false :
3319+ data === "null" ? null :
3320+ !jQuery.isNaN( data ) ? parseFloat( data ) :
3321+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
3322+ data;
3323+ } catch( e ) {}
3324+
3325+ // Make sure we set the data so it isn't changed later
3326+ jQuery.data( elem, key, data );
3327+
3328+ } else {
3329+ data = undefined;
3330+ }
3331+ }
3332+
3333+ return data;
3334+}
3335+
3336+// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
3337+// property to be considered empty objects; this property always exists in
3338+// order to make sure JSON.stringify does not expose internal metadata
3339+function isEmptyDataObject( obj ) {
3340+ for ( var name in obj ) {
3341+ if ( name !== "toJSON" ) {
3342+ return false;
3343+ }
3344+ }
3345+
3346+ return true;
3347+}
3348+
3349+
3350+
3351+
3352+function handleQueueMarkDefer( elem, type, src ) {
3353+ var deferDataKey = type + "defer",
3354+ queueDataKey = type + "queue",
3355+ markDataKey = type + "mark",
3356+ defer = jQuery.data( elem, deferDataKey, undefined, true );
3357+ if ( defer &&
3358+ ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
3359+ ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
3360+ // Give room for hard-coded callbacks to fire first
3361+ // and eventually mark/queue something else on the element
3362+ setTimeout( function() {
3363+ if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
3364+ !jQuery.data( elem, markDataKey, undefined, true ) ) {
3365+ jQuery.removeData( elem, deferDataKey, true );
3366+ defer.resolve();
3367+ }
3368+ }, 0 );
3369+ }
3370+}
3371+
3372+jQuery.extend({
3373+
3374+ _mark: function( elem, type ) {
3375+ if ( elem ) {
3376+ type = (type || "fx") + "mark";
3377+ jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
3378+ }
3379+ },
3380+
3381+ _unmark: function( force, elem, type ) {
3382+ if ( force !== true ) {
3383+ type = elem;
3384+ elem = force;
3385+ force = false;
3386+ }
3387+ if ( elem ) {
3388+ type = type || "fx";
3389+ var key = type + "mark",
3390+ count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
3391+ if ( count ) {
3392+ jQuery.data( elem, key, count, true );
3393+ } else {
3394+ jQuery.removeData( elem, key, true );
3395+ handleQueueMarkDefer( elem, type, "mark" );
3396+ }
3397+ }
3398+ },
3399+
3400+ queue: function( elem, type, data ) {
3401+ if ( elem ) {
3402+ type = (type || "fx") + "queue";
3403+ var q = jQuery.data( elem, type, undefined, true );
3404+ // Speed up dequeue by getting out quickly if this is just a lookup
3405+ if ( data ) {
3406+ if ( !q || jQuery.isArray(data) ) {
3407+ q = jQuery.data( elem, type, jQuery.makeArray(data), true );
3408+ } else {
3409+ q.push( data );
3410+ }
3411+ }
3412+ return q || [];
3413+ }
3414+ },
3415+
3416+ dequeue: function( elem, type ) {
3417+ type = type || "fx";
3418+
3419+ var queue = jQuery.queue( elem, type ),
3420+ fn = queue.shift(),
3421+ defer;
3422+
3423+ // If the fx queue is dequeued, always remove the progress sentinel
3424+ if ( fn === "inprogress" ) {
3425+ fn = queue.shift();
3426+ }
3427+
3428+ if ( fn ) {
3429+ // Add a progress sentinel to prevent the fx queue from being
3430+ // automatically dequeued
3431+ if ( type === "fx" ) {
3432+ queue.unshift("inprogress");
3433+ }
3434+
3435+ fn.call(elem, function() {
3436+ jQuery.dequeue(elem, type);
3437+ });
3438+ }
3439+
3440+ if ( !queue.length ) {
3441+ jQuery.removeData( elem, type + "queue", true );
3442+ handleQueueMarkDefer( elem, type, "queue" );
3443+ }
3444+ }
3445+});
3446+
3447+jQuery.fn.extend({
3448+ queue: function( type, data ) {
3449+ if ( typeof type !== "string" ) {
3450+ data = type;
3451+ type = "fx";
3452+ }
3453+
3454+ if ( data === undefined ) {
3455+ return jQuery.queue( this[0], type );
3456+ }
3457+ return this.each(function() {
3458+ var queue = jQuery.queue( this, type, data );
3459+
3460+ if ( type === "fx" && queue[0] !== "inprogress" ) {
3461+ jQuery.dequeue( this, type );
3462+ }
3463+ });
3464+ },
3465+ dequeue: function( type ) {
3466+ return this.each(function() {
3467+ jQuery.dequeue( this, type );
3468+ });
3469+ },
3470+ // Based off of the plugin by Clint Helfers, with permission.
3471+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
3472+ delay: function( time, type ) {
3473+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
3474+ type = type || "fx";
3475+
3476+ return this.queue( type, function() {
3477+ var elem = this;
3478+ setTimeout(function() {
3479+ jQuery.dequeue( elem, type );
3480+ }, time );
3481+ });
3482+ },
3483+ clearQueue: function( type ) {
3484+ return this.queue( type || "fx", [] );
3485+ },
3486+ // Get a promise resolved when queues of a certain type
3487+ // are emptied (fx is the type by default)
3488+ promise: function( type, object ) {
3489+ if ( typeof type !== "string" ) {
3490+ object = type;
3491+ type = undefined;
3492+ }
3493+ type = type || "fx";
3494+ var defer = jQuery.Deferred(),
3495+ elements = this,
3496+ i = elements.length,
3497+ count = 1,
3498+ deferDataKey = type + "defer",
3499+ queueDataKey = type + "queue",
3500+ markDataKey = type + "mark",
3501+ tmp;
3502+ function resolve() {
3503+ if ( !( --count ) ) {
3504+ defer.resolveWith( elements, [ elements ] );
3505+ }
3506+ }
3507+ while( i-- ) {
3508+ if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
3509+ ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
3510+ jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
3511+ jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
3512+ count++;
3513+ tmp.done( resolve );
3514+ }
3515+ }
3516+ resolve();
3517+ return defer.promise();
3518+ }
3519+});
3520+
3521+
3522+
3523+
3524+var rclass = /[\n\t\r]/g,
3525+ rspace = /\s+/,
3526+ rreturn = /\r/g,
3527+ rtype = /^(?:button|input)$/i,
3528+ rfocusable = /^(?:button|input|object|select|textarea)$/i,
3529+ rclickable = /^a(?:rea)?$/i,
3530+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
3531+ rinvalidChar = /\:|^on/,
3532+ formHook, boolHook;
3533+
3534+jQuery.fn.extend({
3535+ attr: function( name, value ) {
3536+ return jQuery.access( this, name, value, true, jQuery.attr );
3537+ },
3538+
3539+ removeAttr: function( name ) {
3540+ return this.each(function() {
3541+ jQuery.removeAttr( this, name );
3542+ });
3543+ },
3544+
3545+ prop: function( name, value ) {
3546+ return jQuery.access( this, name, value, true, jQuery.prop );
3547+ },
3548+
3549+ removeProp: function( name ) {
3550+ name = jQuery.propFix[ name ] || name;
3551+ return this.each(function() {
3552+ // try/catch handles cases where IE balks (such as removing a property on window)
3553+ try {
3554+ this[ name ] = undefined;
3555+ delete this[ name ];
3556+ } catch( e ) {}
3557+ });
3558+ },
3559+
3560+ addClass: function( value ) {
3561+ var classNames, i, l, elem,
3562+ setClass, c, cl;
3563+
3564+ if ( jQuery.isFunction( value ) ) {
3565+ return this.each(function( j ) {
3566+ jQuery( this ).addClass( value.call(this, j, this.className) );
3567+ });
3568+ }
3569+
3570+ if ( value && typeof value === "string" ) {
3571+ classNames = value.split( rspace );
3572+
3573+ for ( i = 0, l = this.length; i < l; i++ ) {
3574+ elem = this[ i ];
3575+
3576+ if ( elem.nodeType === 1 ) {
3577+ if ( !elem.className && classNames.length === 1 ) {
3578+ elem.className = value;
3579+
3580+ } else {
3581+ setClass = " " + elem.className + " ";
3582+
3583+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
3584+ if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
3585+ setClass += classNames[ c ] + " ";
3586+ }
3587+ }
3588+ elem.className = jQuery.trim( setClass );
3589+ }
3590+ }
3591+ }
3592+ }
3593+
3594+ return this;
3595+ },
3596+
3597+ removeClass: function( value ) {
3598+ var classNames, i, l, elem, className, c, cl;
3599+
3600+ if ( jQuery.isFunction( value ) ) {
3601+ return this.each(function( j ) {
3602+ jQuery( this ).removeClass( value.call(this, j, this.className) );
3603+ });
3604+ }
3605+
3606+ if ( (value && typeof value === "string") || value === undefined ) {
3607+ classNames = (value || "").split( rspace );
3608+
3609+ for ( i = 0, l = this.length; i < l; i++ ) {
3610+ elem = this[ i ];
3611+
3612+ if ( elem.nodeType === 1 && elem.className ) {
3613+ if ( value ) {
3614+ className = (" " + elem.className + " ").replace( rclass, " " );
3615+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
3616+ className = className.replace(" " + classNames[ c ] + " ", " ");
3617+ }
3618+ elem.className = jQuery.trim( className );
3619+
3620+ } else {
3621+ elem.className = "";
3622+ }
3623+ }
3624+ }
3625+ }
3626+
3627+ return this;
3628+ },
3629+
3630+ toggleClass: function( value, stateVal ) {
3631+ var type = typeof value,
3632+ isBool = typeof stateVal === "boolean";
3633+
3634+ if ( jQuery.isFunction( value ) ) {
3635+ return this.each(function( i ) {
3636+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
3637+ });
3638+ }
3639+
3640+ return this.each(function() {
3641+ if ( type === "string" ) {
3642+ // toggle individual class names
3643+ var className,
3644+ i = 0,
3645+ self = jQuery( this ),
3646+ state = stateVal,
3647+ classNames = value.split( rspace );
3648+
3649+ while ( (className = classNames[ i++ ]) ) {
3650+ // check each className given, space seperated list
3651+ state = isBool ? state : !self.hasClass( className );
3652+ self[ state ? "addClass" : "removeClass" ]( className );
3653+ }
3654+
3655+ } else if ( type === "undefined" || type === "boolean" ) {
3656+ if ( this.className ) {
3657+ // store className if set
3658+ jQuery._data( this, "__className__", this.className );
3659+ }
3660+
3661+ // toggle whole className
3662+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
3663+ }
3664+ });
3665+ },
3666+
3667+ hasClass: function( selector ) {
3668+ var className = " " + selector + " ";
3669+ for ( var i = 0, l = this.length; i < l; i++ ) {
3670+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
3671+ return true;
3672+ }
3673+ }
3674+
3675+ return false;
3676+ },
3677+
3678+ val: function( value ) {
3679+ var hooks, ret,
3680+ elem = this[0];
3681+
3682+ if ( !arguments.length ) {
3683+ if ( elem ) {
3684+ hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
3685+
3686+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
3687+ return ret;
3688+ }
3689+
3690+ ret = elem.value;
3691+
3692+ return typeof ret === "string" ?
3693+ // handle most common string cases
3694+ ret.replace(rreturn, "") :
3695+ // handle cases where value is null/undef or number
3696+ ret == null ? "" : ret;
3697+ }
3698+
3699+ return undefined;
3700+ }
3701+
3702+ var isFunction = jQuery.isFunction( value );
3703+
3704+ return this.each(function( i ) {
3705+ var self = jQuery(this), val;
3706+
3707+ if ( this.nodeType !== 1 ) {
3708+ return;
3709+ }
3710+
3711+ if ( isFunction ) {
3712+ val = value.call( this, i, self.val() );
3713+ } else {
3714+ val = value;
3715+ }
3716+
3717+ // Treat null/undefined as ""; convert numbers to string
3718+ if ( val == null ) {
3719+ val = "";
3720+ } else if ( typeof val === "number" ) {
3721+ val += "";
3722+ } else if ( jQuery.isArray( val ) ) {
3723+ val = jQuery.map(val, function ( value ) {
3724+ return value == null ? "" : value + "";
3725+ });
3726+ }
3727+
3728+ hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
3729+
3730+ // If set returns undefined, fall back to normal setting
3731+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
3732+ this.value = val;
3733+ }
3734+ });
3735+ }
3736+});
3737+
3738+jQuery.extend({
3739+ valHooks: {
3740+ option: {
3741+ get: function( elem ) {
3742+ // attributes.value is undefined in Blackberry 4.7 but
3743+ // uses .value. See #6932
3744+ var val = elem.attributes.value;
3745+ return !val || val.specified ? elem.value : elem.text;
3746+ }
3747+ },
3748+ select: {
3749+ get: function( elem ) {
3750+ var value,
3751+ index = elem.selectedIndex,
3752+ values = [],
3753+ options = elem.options,
3754+ one = elem.type === "select-one";
3755+
3756+ // Nothing was selected
3757+ if ( index < 0 ) {
3758+ return null;
3759+ }
3760+
3761+ // Loop through all the selected options
3762+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
3763+ var option = options[ i ];
3764+
3765+ // Don't return options that are disabled or in a disabled optgroup
3766+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
3767+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
3768+
3769+ // Get the specific value for the option
3770+ value = jQuery( option ).val();
3771+
3772+ // We don't need an array for one selects
3773+ if ( one ) {
3774+ return value;
3775+ }
3776+
3777+ // Multi-Selects return an array
3778+ values.push( value );
3779+ }
3780+ }
3781+
3782+ // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
3783+ if ( one && !values.length && options.length ) {
3784+ return jQuery( options[ index ] ).val();
3785+ }
3786+
3787+ return values;
3788+ },
3789+
3790+ set: function( elem, value ) {
3791+ var values = jQuery.makeArray( value );
3792+
3793+ jQuery(elem).find("option").each(function() {
3794+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
3795+ });
3796+
3797+ if ( !values.length ) {
3798+ elem.selectedIndex = -1;
3799+ }
3800+ return values;
3801+ }
3802+ }
3803+ },
3804+
3805+ attrFn: {
3806+ val: true,
3807+ css: true,
3808+ html: true,
3809+ text: true,
3810+ data: true,
3811+ width: true,
3812+ height: true,
3813+ offset: true
3814+ },
3815+
3816+ attrFix: {
3817+ // Always normalize to ensure hook usage
3818+ tabindex: "tabIndex"
3819+ },
3820+
3821+ attr: function( elem, name, value, pass ) {
3822+ var nType = elem.nodeType;
3823+
3824+ // don't get/set attributes on text, comment and attribute nodes
3825+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
3826+ return undefined;
3827+ }
3828+
3829+ if ( pass && name in jQuery.attrFn ) {
3830+ return jQuery( elem )[ name ]( value );
3831+ }
3832+
3833+ // Fallback to prop when attributes are not supported
3834+ if ( !("getAttribute" in elem) ) {
3835+ return jQuery.prop( elem, name, value );
3836+ }
3837+
3838+ var ret, hooks,
3839+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
3840+
3841+ // Normalize the name if needed
3842+ if ( notxml ) {
3843+ name = jQuery.attrFix[ name ] || name;
3844+
3845+ hooks = jQuery.attrHooks[ name ];
3846+
3847+ if ( !hooks ) {
3848+ // Use boolHook for boolean attributes
3849+ if ( rboolean.test( name ) ) {
3850+
3851+ hooks = boolHook;
3852+
3853+ // Use formHook for forms and if the name contains certain characters
3854+ } else if ( formHook && name !== "className" &&
3855+ (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
3856+
3857+ hooks = formHook;
3858+ }
3859+ }
3860+ }
3861+
3862+ if ( value !== undefined ) {
3863+
3864+ if ( value === null ) {
3865+ jQuery.removeAttr( elem, name );
3866+ return undefined;
3867+
3868+ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
3869+ return ret;
3870+
3871+ } else {
3872+ elem.setAttribute( name, "" + value );
3873+ return value;
3874+ }
3875+
3876+ } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
3877+ return ret;
3878+
3879+ } else {
3880+
3881+ ret = elem.getAttribute( name );
3882+
3883+ // Non-existent attributes return null, we normalize to undefined
3884+ return ret === null ?
3885+ undefined :
3886+ ret;
3887+ }
3888+ },
3889+
3890+ removeAttr: function( elem, name ) {
3891+ var propName;
3892+ if ( elem.nodeType === 1 ) {
3893+ name = jQuery.attrFix[ name ] || name;
3894+
3895+ if ( jQuery.support.getSetAttribute ) {
3896+ // Use removeAttribute in browsers that support it
3897+ elem.removeAttribute( name );
3898+ } else {
3899+ jQuery.attr( elem, name, "" );
3900+ elem.removeAttributeNode( elem.getAttributeNode( name ) );
3901+ }
3902+
3903+ // Set corresponding property to false for boolean attributes
3904+ if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
3905+ elem[ propName ] = false;
3906+ }
3907+ }
3908+ },
3909+
3910+ attrHooks: {
3911+ type: {
3912+ set: function( elem, value ) {
3913+ // We can't allow the type property to be changed (since it causes problems in IE)
3914+ if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
3915+ jQuery.error( "type property can't be changed" );
3916+ } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
3917+ // Setting the type on a radio button after the value resets the value in IE6-9
3918+ // Reset value to it's default in case type is set after value
3919+ // This is for element creation
3920+ var val = elem.value;
3921+ elem.setAttribute( "type", value );
3922+ if ( val ) {
3923+ elem.value = val;
3924+ }
3925+ return value;
3926+ }
3927+ }
3928+ },
3929+ tabIndex: {
3930+ get: function( elem ) {
3931+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
3932+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
3933+ var attributeNode = elem.getAttributeNode("tabIndex");
3934+
3935+ return attributeNode && attributeNode.specified ?
3936+ parseInt( attributeNode.value, 10 ) :
3937+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
3938+ 0 :
3939+ undefined;
3940+ }
3941+ },
3942+ // Use the value property for back compat
3943+ // Use the formHook for button elements in IE6/7 (#1954)
3944+ value: {
3945+ get: function( elem, name ) {
3946+ if ( formHook && jQuery.nodeName( elem, "button" ) ) {
3947+ return formHook.get( elem, name );
3948+ }
3949+ return name in elem ?
3950+ elem.value :
3951+ null;
3952+ },
3953+ set: function( elem, value, name ) {
3954+ if ( formHook && jQuery.nodeName( elem, "button" ) ) {
3955+ return formHook.set( elem, value, name );
3956+ }
3957+ // Does not return so that setAttribute is also used
3958+ elem.value = value;
3959+ }
3960+ }
3961+ },
3962+
3963+ propFix: {
3964+ tabindex: "tabIndex",
3965+ readonly: "readOnly",
3966+ "for": "htmlFor",
3967+ "class": "className",
3968+ maxlength: "maxLength",
3969+ cellspacing: "cellSpacing",
3970+ cellpadding: "cellPadding",
3971+ rowspan: "rowSpan",
3972+ colspan: "colSpan",
3973+ usemap: "useMap",
3974+ frameborder: "frameBorder",
3975+ contenteditable: "contentEditable"
3976+ },
3977+
3978+ prop: function( elem, name, value ) {
3979+ var nType = elem.nodeType;
3980+
3981+ // don't get/set properties on text, comment and attribute nodes
3982+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
3983+ return undefined;
3984+ }
3985+
3986+ var ret, hooks,
3987+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
3988+
3989+ if ( notxml ) {
3990+ // Fix name and attach hooks
3991+ name = jQuery.propFix[ name ] || name;
3992+ hooks = jQuery.propHooks[ name ];
3993+ }
3994+
3995+ if ( value !== undefined ) {
3996+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
3997+ return ret;
3998+
3999+ } else {
4000+ return (elem[ name ] = value);
4001+ }
4002+
4003+ } else {
4004+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
4005+ return ret;
4006+
4007+ } else {
4008+ return elem[ name ];
4009+ }
4010+ }
4011+ },
4012+
4013+ propHooks: {}
4014+});
4015+
4016+// Hook for boolean attributes
4017+boolHook = {
4018+ get: function( elem, name ) {
4019+ // Align boolean attributes with corresponding properties
4020+ return jQuery.prop( elem, name ) ?
4021+ name.toLowerCase() :
4022+ undefined;
4023+ },
4024+ set: function( elem, value, name ) {
4025+ var propName;
4026+ if ( value === false ) {
4027+ // Remove boolean attributes when set to false
4028+ jQuery.removeAttr( elem, name );
4029+ } else {
4030+ // value is true since we know at this point it's type boolean and not false
4031+ // Set boolean attributes to the same name and set the DOM property
4032+ propName = jQuery.propFix[ name ] || name;
4033+ if ( propName in elem ) {
4034+ // Only set the IDL specifically if it already exists on the element
4035+ elem[ propName ] = true;
4036+ }
4037+
4038+ elem.setAttribute( name, name.toLowerCase() );
4039+ }
4040+ return name;
4041+ }
4042+};
4043+
4044+// IE6/7 do not support getting/setting some attributes with get/setAttribute
4045+if ( !jQuery.support.getSetAttribute ) {
4046+
4047+ // propFix is more comprehensive and contains all fixes
4048+ jQuery.attrFix = jQuery.propFix;
4049+
4050+ // Use this for any attribute on a form in IE6/7
4051+ formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = {
4052+ get: function( elem, name ) {
4053+ var ret;
4054+ ret = elem.getAttributeNode( name );
4055+ // Return undefined if nodeValue is empty string
4056+ return ret && ret.nodeValue !== "" ?
4057+ ret.nodeValue :
4058+ undefined;
4059+ },
4060+ set: function( elem, value, name ) {
4061+ // Check form objects in IE (multiple bugs related)
4062+ // Only use nodeValue if the attribute node exists on the form
4063+ var ret = elem.getAttributeNode( name );
4064+ if ( ret ) {
4065+ ret.nodeValue = value;
4066+ return value;
4067+ }
4068+ }
4069+ };
4070+
4071+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
4072+ // This is for removals
4073+ jQuery.each([ "width", "height" ], function( i, name ) {
4074+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
4075+ set: function( elem, value ) {
4076+ if ( value === "" ) {
4077+ elem.setAttribute( name, "auto" );
4078+ return value;
4079+ }
4080+ }
4081+ });
4082+ });
4083+}
4084+
4085+
4086+// Some attributes require a special call on IE
4087+if ( !jQuery.support.hrefNormalized ) {
4088+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
4089+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
4090+ get: function( elem ) {
4091+ var ret = elem.getAttribute( name, 2 );
4092+ return ret === null ? undefined : ret;
4093+ }
4094+ });
4095+ });
4096+}
4097+
4098+if ( !jQuery.support.style ) {
4099+ jQuery.attrHooks.style = {
4100+ get: function( elem ) {
4101+ // Return undefined in the case of empty string
4102+ // Normalize to lowercase since IE uppercases css property names
4103+ return elem.style.cssText.toLowerCase() || undefined;
4104+ },
4105+ set: function( elem, value ) {
4106+ return (elem.style.cssText = "" + value);
4107+ }
4108+ };
4109+}
4110+
4111+// Safari mis-reports the default selected property of an option
4112+// Accessing the parent's selectedIndex property fixes it
4113+if ( !jQuery.support.optSelected ) {
4114+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
4115+ get: function( elem ) {
4116+ var parent = elem.parentNode;
4117+
4118+ if ( parent ) {
4119+ parent.selectedIndex;
4120+
4121+ // Make sure that it also works with optgroups, see #5701
4122+ if ( parent.parentNode ) {
4123+ parent.parentNode.selectedIndex;
4124+ }
4125+ }
4126+ }
4127+ });
4128+}
4129+
4130+// Radios and checkboxes getter/setter
4131+if ( !jQuery.support.checkOn ) {
4132+ jQuery.each([ "radio", "checkbox" ], function() {
4133+ jQuery.valHooks[ this ] = {
4134+ get: function( elem ) {
4135+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
4136+ return elem.getAttribute("value") === null ? "on" : elem.value;
4137+ }
4138+ };
4139+ });
4140+}
4141+jQuery.each([ "radio", "checkbox" ], function() {
4142+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
4143+ set: function( elem, value ) {
4144+ if ( jQuery.isArray( value ) ) {
4145+ return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
4146+ }
4147+ }
4148+ });
4149+});
4150+
4151+
4152+
4153+
4154+var rnamespaces = /\.(.*)$/,
4155+ rformElems = /^(?:textarea|input|select)$/i,
4156+ rperiod = /\./g,
4157+ rspaces = / /g,
4158+ rescape = /[^\w\s.|`]/g,
4159+ fcleanup = function( nm ) {
4160+ return nm.replace(rescape, "\\$&");
4161+ };
4162+
4163+/*
4164+ * A number of helper functions used for managing events.
4165+ * Many of the ideas behind this code originated from
4166+ * Dean Edwards' addEvent library.
4167+ */
4168+jQuery.event = {
4169+
4170+ // Bind an event to an element
4171+ // Original by Dean Edwards
4172+ add: function( elem, types, handler, data ) {
4173+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4174+ return;
4175+ }
4176+
4177+ if ( handler === false ) {
4178+ handler = returnFalse;
4179+ } else if ( !handler ) {
4180+ // Fixes bug #7229. Fix recommended by jdalton
4181+ return;
4182+ }
4183+
4184+ var handleObjIn, handleObj;
4185+
4186+ if ( handler.handler ) {
4187+ handleObjIn = handler;
4188+ handler = handleObjIn.handler;
4189+ }
4190+
4191+ // Make sure that the function being executed has a unique ID
4192+ if ( !handler.guid ) {
4193+ handler.guid = jQuery.guid++;
4194+ }
4195+
4196+ // Init the element's event structure
4197+ var elemData = jQuery._data( elem );
4198+
4199+ // If no elemData is found then we must be trying to bind to one of the
4200+ // banned noData elements
4201+ if ( !elemData ) {
4202+ return;
4203+ }
4204+
4205+ var events = elemData.events,
4206+ eventHandle = elemData.handle;
4207+
4208+ if ( !events ) {
4209+ elemData.events = events = {};
4210+ }
4211+
4212+ if ( !eventHandle ) {
4213+ elemData.handle = eventHandle = function( e ) {
4214+ // Discard the second event of a jQuery.event.trigger() and
4215+ // when an event is called after a page has unloaded
4216+ return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
4217+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
4218+ undefined;
4219+ };
4220+ }
4221+
4222+ // Add elem as a property of the handle function
4223+ // This is to prevent a memory leak with non-native events in IE.
4224+ eventHandle.elem = elem;
4225+
4226+ // Handle multiple events separated by a space
4227+ // jQuery(...).bind("mouseover mouseout", fn);
4228+ types = types.split(" ");
4229+
4230+ var type, i = 0, namespaces;
4231+
4232+ while ( (type = types[ i++ ]) ) {
4233+ handleObj = handleObjIn ?
4234+ jQuery.extend({}, handleObjIn) :
4235+ { handler: handler, data: data };
4236+
4237+ // Namespaced event handlers
4238+ if ( type.indexOf(".") > -1 ) {
4239+ namespaces = type.split(".");
4240+ type = namespaces.shift();
4241+ handleObj.namespace = namespaces.slice(0).sort().join(".");
4242+
4243+ } else {
4244+ namespaces = [];
4245+ handleObj.namespace = "";
4246+ }
4247+
4248+ handleObj.type = type;
4249+ if ( !handleObj.guid ) {
4250+ handleObj.guid = handler.guid;
4251+ }
4252+
4253+ // Get the current list of functions bound to this event
4254+ var handlers = events[ type ],
4255+ special = jQuery.event.special[ type ] || {};
4256+
4257+ // Init the event handler queue
4258+ if ( !handlers ) {
4259+ handlers = events[ type ] = [];
4260+
4261+ // Check for a special event handler
4262+ // Only use addEventListener/attachEvent if the special
4263+ // events handler returns false
4264+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4265+ // Bind the global event handler to the element
4266+ if ( elem.addEventListener ) {
4267+ elem.addEventListener( type, eventHandle, false );
4268+
4269+ } else if ( elem.attachEvent ) {
4270+ elem.attachEvent( "on" + type, eventHandle );
4271+ }
4272+ }
4273+ }
4274+
4275+ if ( special.add ) {
4276+ special.add.call( elem, handleObj );
4277+
4278+ if ( !handleObj.handler.guid ) {
4279+ handleObj.handler.guid = handler.guid;
4280+ }
4281+ }
4282+
4283+ // Add the function to the element's handler list
4284+ handlers.push( handleObj );
4285+
4286+ // Keep track of which events have been used, for event optimization
4287+ jQuery.event.global[ type ] = true;
4288+ }
4289+
4290+ // Nullify elem to prevent memory leaks in IE
4291+ elem = null;
4292+ },
4293+
4294+ global: {},
4295+
4296+ // Detach an event or set of events from an element
4297+ remove: function( elem, types, handler, pos ) {
4298+ // don't do events on text and comment nodes
4299+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4300+ return;
4301+ }
4302+
4303+ if ( handler === false ) {
4304+ handler = returnFalse;
4305+ }
4306+
4307+ var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
4308+ elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
4309+ events = elemData && elemData.events;
4310+
4311+ if ( !elemData || !events ) {
4312+ return;
4313+ }
4314+
4315+ // types is actually an event object here
4316+ if ( types && types.type ) {
4317+ handler = types.handler;
4318+ types = types.type;
4319+ }
4320+
4321+ // Unbind all events for the element
4322+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
4323+ types = types || "";
4324+
4325+ for ( type in events ) {
4326+ jQuery.event.remove( elem, type + types );
4327+ }
4328+
4329+ return;
4330+ }
4331+
4332+ // Handle multiple events separated by a space
4333+ // jQuery(...).unbind("mouseover mouseout", fn);
4334+ types = types.split(" ");
4335+
4336+ while ( (type = types[ i++ ]) ) {
4337+ origType = type;
4338+ handleObj = null;
4339+ all = type.indexOf(".") < 0;
4340+ namespaces = [];
4341+
4342+ if ( !all ) {
4343+ // Namespaced event handlers
4344+ namespaces = type.split(".");
4345+ type = namespaces.shift();
4346+
4347+ namespace = new RegExp("(^|\\.)" +
4348+ jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
4349+ }
4350+
4351+ eventType = events[ type ];
4352+
4353+ if ( !eventType ) {
4354+ continue;
4355+ }
4356+
4357+ if ( !handler ) {
4358+ for ( j = 0; j < eventType.length; j++ ) {
4359+ handleObj = eventType[ j ];
4360+
4361+ if ( all || namespace.test( handleObj.namespace ) ) {
4362+ jQuery.event.remove( elem, origType, handleObj.handler, j );
4363+ eventType.splice( j--, 1 );
4364+ }
4365+ }
4366+
4367+ continue;
4368+ }
4369+
4370+ special = jQuery.event.special[ type ] || {};
4371+
4372+ for ( j = pos || 0; j < eventType.length; j++ ) {
4373+ handleObj = eventType[ j ];
4374+
4375+ if ( handler.guid === handleObj.guid ) {
4376+ // remove the given handler for the given type
4377+ if ( all || namespace.test( handleObj.namespace ) ) {
4378+ if ( pos == null ) {
4379+ eventType.splice( j--, 1 );
4380+ }
4381+
4382+ if ( special.remove ) {
4383+ special.remove.call( elem, handleObj );
4384+ }
4385+ }
4386+
4387+ if ( pos != null ) {
4388+ break;
4389+ }
4390+ }
4391+ }
4392+
4393+ // remove generic event handler if no more handlers exist
4394+ if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
4395+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
4396+ jQuery.removeEvent( elem, type, elemData.handle );
4397+ }
4398+
4399+ ret = null;
4400+ delete events[ type ];
4401+ }
4402+ }
4403+
4404+ // Remove the expando if it's no longer used
4405+ if ( jQuery.isEmptyObject( events ) ) {
4406+ var handle = elemData.handle;
4407+ if ( handle ) {
4408+ handle.elem = null;
4409+ }
4410+
4411+ delete elemData.events;
4412+ delete elemData.handle;
4413+
4414+ if ( jQuery.isEmptyObject( elemData ) ) {
4415+ jQuery.removeData( elem, undefined, true );
4416+ }
4417+ }
4418+ },
4419+
4420+ // Events that are safe to short-circuit if no handlers are attached.
4421+ // Native DOM events should not be added, they may have inline handlers.
4422+ customEvent: {
4423+ "getData": true,
4424+ "setData": true,
4425+ "changeData": true
4426+ },
4427+
4428+ trigger: function( event, data, elem, onlyHandlers ) {
4429+ // Event object or event type
4430+ var type = event.type || event,
4431+ namespaces = [],
4432+ exclusive;
4433+
4434+ if ( type.indexOf("!") >= 0 ) {
4435+ // Exclusive events trigger only for the exact event (no namespaces)
4436+ type = type.slice(0, -1);
4437+ exclusive = true;
4438+ }
4439+
4440+ if ( type.indexOf(".") >= 0 ) {
4441+ // Namespaced trigger; create a regexp to match event type in handle()
4442+ namespaces = type.split(".");
4443+ type = namespaces.shift();
4444+ namespaces.sort();
4445+ }
4446+
4447+ if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
4448+ // No jQuery handlers for this event type, and it can't have inline handlers
4449+ return;
4450+ }
4451+
4452+ // Caller can pass in an Event, Object, or just an event type string
4453+ event = typeof event === "object" ?
4454+ // jQuery.Event object
4455+ event[ jQuery.expando ] ? event :
4456+ // Object literal
4457+ new jQuery.Event( type, event ) :
4458+ // Just the event type (string)
4459+ new jQuery.Event( type );
4460+
4461+ event.type = type;
4462+ event.exclusive = exclusive;
4463+ event.namespace = namespaces.join(".");
4464+ event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
4465+
4466+ // triggerHandler() and global events don't bubble or run the default action
4467+ if ( onlyHandlers || !elem ) {
4468+ event.preventDefault();
4469+ event.stopPropagation();
4470+ }
4471+
4472+ // Handle a global trigger
4473+ if ( !elem ) {
4474+ // TODO: Stop taunting the data cache; remove global events and always attach to document
4475+ jQuery.each( jQuery.cache, function() {
4476+ // internalKey variable is just used to make it easier to find
4477+ // and potentially change this stuff later; currently it just
4478+ // points to jQuery.expando
4479+ var internalKey = jQuery.expando,
4480+ internalCache = this[ internalKey ];
4481+ if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
4482+ jQuery.event.trigger( event, data, internalCache.handle.elem );
4483+ }
4484+ });
4485+ return;
4486+ }
4487+
4488+ // Don't do events on text and comment nodes
4489+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4490+ return;
4491+ }
4492+
4493+ // Clean up the event in case it is being reused
4494+ event.result = undefined;
4495+ event.target = elem;
4496+
4497+ // Clone any incoming data and prepend the event, creating the handler arg list
4498+ data = data != null ? jQuery.makeArray( data ) : [];
4499+ data.unshift( event );
4500+
4501+ var cur = elem,
4502+ // IE doesn't like method names with a colon (#3533, #8272)
4503+ ontype = type.indexOf(":") < 0 ? "on" + type : "";
4504+
4505+ // Fire event on the current element, then bubble up the DOM tree
4506+ do {
4507+ var handle = jQuery._data( cur, "handle" );
4508+
4509+ event.currentTarget = cur;
4510+ if ( handle ) {
4511+ handle.apply( cur, data );
4512+ }
4513+
4514+ // Trigger an inline bound script
4515+ if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
4516+ event.result = false;
4517+ event.preventDefault();
4518+ }
4519+
4520+ // Bubble up to document, then to window
4521+ cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
4522+ } while ( cur && !event.isPropagationStopped() );
4523+
4524+ // If nobody prevented the default action, do it now
4525+ if ( !event.isDefaultPrevented() ) {
4526+ var old,
4527+ special = jQuery.event.special[ type ] || {};
4528+
4529+ if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
4530+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
4531+
4532+ // Call a native DOM method on the target with the same name name as the event.
4533+ // Can't use an .isFunction)() check here because IE6/7 fails that test.
4534+ // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
4535+ try {
4536+ if ( ontype && elem[ type ] ) {
4537+ // Don't re-trigger an onFOO event when we call its FOO() method
4538+ old = elem[ ontype ];
4539+
4540+ if ( old ) {
4541+ elem[ ontype ] = null;
4542+ }
4543+
4544+ jQuery.event.triggered = type;
4545+ elem[ type ]();
4546+ }
4547+ } catch ( ieError ) {}
4548+
4549+ if ( old ) {
4550+ elem[ ontype ] = old;
4551+ }
4552+
4553+ jQuery.event.triggered = undefined;
4554+ }
4555+ }
4556+
4557+ return event.result;
4558+ },
4559+
4560+ handle: function( event ) {
4561+ event = jQuery.event.fix( event || window.event );
4562+ // Snapshot the handlers list since a called handler may add/remove events.
4563+ var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
4564+ run_all = !event.exclusive && !event.namespace,
4565+ args = Array.prototype.slice.call( arguments, 0 );
4566+
4567+ // Use the fix-ed Event rather than the (read-only) native event
4568+ args[0] = event;
4569+ event.currentTarget = this;
4570+
4571+ for ( var j = 0, l = handlers.length; j < l; j++ ) {
4572+ var handleObj = handlers[ j ];
4573+
4574+ // Triggered event must 1) be non-exclusive and have no namespace, or
4575+ // 2) have namespace(s) a subset or equal to those in the bound event.
4576+ if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
4577+ // Pass in a reference to the handler function itself
4578+ // So that we can later remove it
4579+ event.handler = handleObj.handler;
4580+ event.data = handleObj.data;
4581+ event.handleObj = handleObj;
4582+
4583+ var ret = handleObj.handler.apply( this, args );
4584+
4585+ if ( ret !== undefined ) {
4586+ event.result = ret;
4587+ if ( ret === false ) {
4588+ event.preventDefault();
4589+ event.stopPropagation();
4590+ }
4591+ }
4592+
4593+ if ( event.isImmediatePropagationStopped() ) {
4594+ break;
4595+ }
4596+ }
4597+ }
4598+ return event.result;
4599+ },
4600+
4601+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
4602+
4603+ fix: function( event ) {
4604+ if ( event[ jQuery.expando ] ) {
4605+ return event;
4606+ }
4607+
4608+ // store a copy of the original event object
4609+ // and "clone" to set read-only properties
4610+ var originalEvent = event;
4611+ event = jQuery.Event( originalEvent );
4612+
4613+ for ( var i = this.props.length, prop; i; ) {
4614+ prop = this.props[ --i ];
4615+ event[ prop ] = originalEvent[ prop ];
4616+ }
4617+
4618+ // Fix target property, if necessary
4619+ if ( !event.target ) {
4620+ // Fixes #1925 where srcElement might not be defined either
4621+ event.target = event.srcElement || document;
4622+ }
4623+
4624+ // check if target is a textnode (safari)
4625+ if ( event.target.nodeType === 3 ) {
4626+ event.target = event.target.parentNode;
4627+ }
4628+
4629+ // Add relatedTarget, if necessary
4630+ if ( !event.relatedTarget && event.fromElement ) {
4631+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
4632+ }
4633+
4634+ // Calculate pageX/Y if missing and clientX/Y available
4635+ if ( event.pageX == null && event.clientX != null ) {
4636+ var eventDocument = event.target.ownerDocument || document,
4637+ doc = eventDocument.documentElement,
4638+ body = eventDocument.body;
4639+
4640+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
4641+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
4642+ }
4643+
4644+ // Add which for key events
4645+ if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
4646+ event.which = event.charCode != null ? event.charCode : event.keyCode;
4647+ }
4648+
4649+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
4650+ if ( !event.metaKey && event.ctrlKey ) {
4651+ event.metaKey = event.ctrlKey;
4652+ }
4653+
4654+ // Add which for click: 1 === left; 2 === middle; 3 === right
4655+ // Note: button is not normalized, so don't use it
4656+ if ( !event.which && event.button !== undefined ) {
4657+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
4658+ }
4659+
4660+ return event;
4661+ },
4662+
4663+ // Deprecated, use jQuery.guid instead
4664+ guid: 1E8,
4665+
4666+ // Deprecated, use jQuery.proxy instead
4667+ proxy: jQuery.proxy,
4668+
4669+ special: {
4670+ ready: {
4671+ // Make sure the ready event is setup
4672+ setup: jQuery.bindReady,
4673+ teardown: jQuery.noop
4674+ },
4675+
4676+ live: {
4677+ add: function( handleObj ) {
4678+ jQuery.event.add( this,
4679+ liveConvert( handleObj.origType, handleObj.selector ),
4680+ jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
4681+ },
4682+
4683+ remove: function( handleObj ) {
4684+ jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
4685+ }
4686+ },
4687+
4688+ beforeunload: {
4689+ setup: function( data, namespaces, eventHandle ) {
4690+ // We only want to do this special case on windows
4691+ if ( jQuery.isWindow( this ) ) {
4692+ this.onbeforeunload = eventHandle;
4693+ }
4694+ },
4695+
4696+ teardown: function( namespaces, eventHandle ) {
4697+ if ( this.onbeforeunload === eventHandle ) {
4698+ this.onbeforeunload = null;
4699+ }
4700+ }
4701+ }
4702+ }
4703+};
4704+
4705+jQuery.removeEvent = document.removeEventListener ?
4706+ function( elem, type, handle ) {
4707+ if ( elem.removeEventListener ) {
4708+ elem.removeEventListener( type, handle, false );
4709+ }
4710+ } :
4711+ function( elem, type, handle ) {
4712+ if ( elem.detachEvent ) {
4713+ elem.detachEvent( "on" + type, handle );
4714+ }
4715+ };
4716+
4717+jQuery.Event = function( src, props ) {
4718+ // Allow instantiation without the 'new' keyword
4719+ if ( !this.preventDefault ) {
4720+ return new jQuery.Event( src, props );
4721+ }
4722+
4723+ // Event object
4724+ if ( src && src.type ) {
4725+ this.originalEvent = src;
4726+ this.type = src.type;
4727+
4728+ // Events bubbling up the document may have been marked as prevented
4729+ // by a handler lower down the tree; reflect the correct value.
4730+ this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
4731+ src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
4732+
4733+ // Event type
4734+ } else {
4735+ this.type = src;
4736+ }
4737+
4738+ // Put explicitly provided properties onto the event object
4739+ if ( props ) {
4740+ jQuery.extend( this, props );
4741+ }
4742+
4743+ // timeStamp is buggy for some events on Firefox(#3843)
4744+ // So we won't rely on the native value
4745+ this.timeStamp = jQuery.now();
4746+
4747+ // Mark it as fixed
4748+ this[ jQuery.expando ] = true;
4749+};
4750+
4751+function returnFalse() {
4752+ return false;
4753+}
4754+function returnTrue() {
4755+ return true;
4756+}
4757+
4758+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4759+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4760+jQuery.Event.prototype = {
4761+ preventDefault: function() {
4762+ this.isDefaultPrevented = returnTrue;
4763+
4764+ var e = this.originalEvent;
4765+ if ( !e ) {
4766+ return;
4767+ }
4768+
4769+ // if preventDefault exists run it on the original event
4770+ if ( e.preventDefault ) {
4771+ e.preventDefault();
4772+
4773+ // otherwise set the returnValue property of the original event to false (IE)
4774+ } else {
4775+ e.returnValue = false;
4776+ }
4777+ },
4778+ stopPropagation: function() {
4779+ this.isPropagationStopped = returnTrue;
4780+
4781+ var e = this.originalEvent;
4782+ if ( !e ) {
4783+ return;
4784+ }
4785+ // if stopPropagation exists run it on the original event
4786+ if ( e.stopPropagation ) {
4787+ e.stopPropagation();
4788+ }
4789+ // otherwise set the cancelBubble property of the original event to true (IE)
4790+ e.cancelBubble = true;
4791+ },
4792+ stopImmediatePropagation: function() {
4793+ this.isImmediatePropagationStopped = returnTrue;
4794+ this.stopPropagation();
4795+ },
4796+ isDefaultPrevented: returnFalse,
4797+ isPropagationStopped: returnFalse,
4798+ isImmediatePropagationStopped: returnFalse
4799+};
4800+
4801+// Checks if an event happened on an element within another element
4802+// Used in jQuery.event.special.mouseenter and mouseleave handlers
4803+var withinElement = function( event ) {
4804+
4805+ // Check if mouse(over|out) are still within the same parent element
4806+ var related = event.relatedTarget,
4807+ inside = false,
4808+ eventType = event.type;
4809+
4810+ event.type = event.data;
4811+
4812+ if ( related !== this ) {
4813+
4814+ if ( related ) {
4815+ inside = jQuery.contains( this, related );
4816+ }
4817+
4818+ if ( !inside ) {
4819+
4820+ jQuery.event.handle.apply( this, arguments );
4821+
4822+ event.type = eventType;
4823+ }
4824+ }
4825+},
4826+
4827+// In case of event delegation, we only need to rename the event.type,
4828+// liveHandler will take care of the rest.
4829+delegate = function( event ) {
4830+ event.type = event.data;
4831+ jQuery.event.handle.apply( this, arguments );
4832+};
4833+
4834+// Create mouseenter and mouseleave events
4835+jQuery.each({
4836+ mouseenter: "mouseover",
4837+ mouseleave: "mouseout"
4838+}, function( orig, fix ) {
4839+ jQuery.event.special[ orig ] = {
4840+ setup: function( data ) {
4841+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
4842+ },
4843+ teardown: function( data ) {
4844+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
4845+ }
4846+ };
4847+});
4848+
4849+// submit delegation
4850+if ( !jQuery.support.submitBubbles ) {
4851+
4852+ jQuery.event.special.submit = {
4853+ setup: function( data, namespaces ) {
4854+ if ( !jQuery.nodeName( this, "form" ) ) {
4855+ jQuery.event.add(this, "click.specialSubmit", function( e ) {
4856+ var elem = e.target,
4857+ type = elem.type;
4858+
4859+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
4860+ trigger( "submit", this, arguments );
4861+ }
4862+ });
4863+
4864+ jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
4865+ var elem = e.target,
4866+ type = elem.type;
4867+
4868+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
4869+ trigger( "submit", this, arguments );
4870+ }
4871+ });
4872+
4873+ } else {
4874+ return false;
4875+ }
4876+ },
4877+
4878+ teardown: function( namespaces ) {
4879+ jQuery.event.remove( this, ".specialSubmit" );
4880+ }
4881+ };
4882+
4883+}
4884+
4885+// change delegation, happens here so we have bind.
4886+if ( !jQuery.support.changeBubbles ) {
4887+
4888+ var changeFilters,
4889+
4890+ getVal = function( elem ) {
4891+ var type = elem.type, val = elem.value;
4892+
4893+ if ( type === "radio" || type === "checkbox" ) {
4894+ val = elem.checked;
4895+
4896+ } else if ( type === "select-multiple" ) {
4897+ val = elem.selectedIndex > -1 ?
4898+ jQuery.map( elem.options, function( elem ) {
4899+ return elem.selected;
4900+ }).join("-") :
4901+ "";
4902+
4903+ } else if ( jQuery.nodeName( elem, "select" ) ) {
4904+ val = elem.selectedIndex;
4905+ }
4906+
4907+ return val;
4908+ },
4909+
4910+ testChange = function testChange( e ) {
4911+ var elem = e.target, data, val;
4912+
4913+ if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
4914+ return;
4915+ }
4916+
4917+ data = jQuery._data( elem, "_change_data" );
4918+ val = getVal(elem);
4919+
4920+ // the current data will be also retrieved by beforeactivate
4921+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
4922+ jQuery._data( elem, "_change_data", val );
4923+ }
4924+
4925+ if ( data === undefined || val === data ) {
4926+ return;
4927+ }
4928+
4929+ if ( data != null || val ) {
4930+ e.type = "change";
4931+ e.liveFired = undefined;
4932+ jQuery.event.trigger( e, arguments[1], elem );
4933+ }
4934+ };
4935+
4936+ jQuery.event.special.change = {
4937+ filters: {
4938+ focusout: testChange,
4939+
4940+ beforedeactivate: testChange,
4941+
4942+ click: function( e ) {
4943+ var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
4944+
4945+ if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
4946+ testChange.call( this, e );
4947+ }
4948+ },
4949+
4950+ // Change has to be called before submit
4951+ // Keydown will be called before keypress, which is used in submit-event delegation
4952+ keydown: function( e ) {
4953+ var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
4954+
4955+ if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
4956+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
4957+ type === "select-multiple" ) {
4958+ testChange.call( this, e );
4959+ }
4960+ },
4961+
4962+ // Beforeactivate happens also before the previous element is blurred
4963+ // with this event you can't trigger a change event, but you can store
4964+ // information
4965+ beforeactivate: function( e ) {
4966+ var elem = e.target;
4967+ jQuery._data( elem, "_change_data", getVal(elem) );
4968+ }
4969+ },
4970+
4971+ setup: function( data, namespaces ) {
4972+ if ( this.type === "file" ) {
4973+ return false;
4974+ }
4975+
4976+ for ( var type in changeFilters ) {
4977+ jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
4978+ }
4979+
4980+ return rformElems.test( this.nodeName );
4981+ },
4982+
4983+ teardown: function( namespaces ) {
4984+ jQuery.event.remove( this, ".specialChange" );
4985+
4986+ return rformElems.test( this.nodeName );
4987+ }
4988+ };
4989+
4990+ changeFilters = jQuery.event.special.change.filters;
4991+
4992+ // Handle when the input is .focus()'d
4993+ changeFilters.focus = changeFilters.beforeactivate;
4994+}
4995+
4996+function trigger( type, elem, args ) {
4997+ // Piggyback on a donor event to simulate a different one.
4998+ // Fake originalEvent to avoid donor's stopPropagation, but if the
4999+ // simulated event prevents default then we do the same on the donor.
5000+ // Don't pass args or remember liveFired; they apply to the donor event.
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches