Commits

Romain Pelisse committed 44946b1 Merge

merge with André Sintzoff

Comments (0)

Files changed (56)

 FORMATS=html html-single pdf epub
 
 PO_LANGUAGES := zh
-DBK_LANGUAGES := en
+DBK_LANGUAGES := en it
 LANGUAGES := $(DBK_LANGUAGES) $(PO_LANGUAGES)
 
 UPDATEPO = PERLLIB=$(PO4A_LIB) $(PO4A_HOME)/po4a-updatepo -M UTF-8 \
 #rev_id = $(shell hg parents --template '{node|short} ({date|isodate})')
 rev_id = $(shell hg parents --template '{node|short} ({date|shortdate})')
 
-images := \
-	en/figs/bad-merge-1.png \
-	en/figs/bad-merge-2.png \
-	en/figs/bad-merge-3.png \
-	en/figs/bad-merge-4.png \
-	en/figs/bad-merge-5.png \
-	en/figs/feature-branches.png \
-	en/figs/filelog.png \
-	en/figs/metadata.png \
-	en/figs/mq-stack.png \
-	en/figs/revlog.png \
-	en/figs/snapshot.png \
-	en/figs/tour-history.png \
-	en/figs/tour-merge-conflict.png \
-	en/figs/tour-merge-merge.png \
-	en/figs/tour-merge-pull.png \
-	en/figs/tour-merge-sep-repos.png \
-	en/figs/undo-manual-merge.png \
-	en/figs/undo-manual.png \
-	en/figs/undo-non-tip.png \
-	en/figs/undo-simple.png \
-	en/figs/wdir-after-commit.png \
-	en/figs/wdir-branch.png \
-	en/figs/wdir-merge.png \
-	en/figs/wdir.png \
-	en/figs/wdir-pre-branch.png
+images-dot := $(wildcard en/figs/*.dot)
+
+images-svg := $(wildcard en/figs/*.svg)
+images-svg :=$(filter-out %-tmp.svg, $(images-svg))
+images-svg -= $(images-dot:dot=svg)
+
+images-dst := $(wildcard en/figs/*.png)
+images-dst += $(images-dot:dot=png)
+images-dst += $(images-svg:svg=png)
+
+images-gen := $(images-dot:dot=png)
+images-gen += $(images-svg:svg=png)
+images-gen += $(wildcard en/figs/*-tmp.svg)
 
 help:
-	@echo "  make epub         [LINGUA=en|zh|...]"
-	@echo "  make html         [LINGUA=en|zh|...]"
-	@echo "  make html-single  [LINGUA=en|zh|...]"
-	@echo "  make pdf          [LINGUA=en|zh|...]"
-	@echo "  make validate     [LINGUA=en|zh|...] # always before commit!"
+	@echo "  make epub         [LINGUA=en|it|zh|...]"
+	@echo "  make html         [LINGUA=en|it|zh|...]"
+	@echo "  make html-single  [LINGUA=en|it|zh|...]"
+	@echo "  make pdf          [LINGUA=en|it|zh|...]"
+	@echo "  make validate     [LINGUA=en|it|zh|...] # always before commit!"
 	@echo "  make tidypo       [LINGUA=zh|...]    # always before commit!"
 	@echo "  make updatepo     [LINGUA=zh|...]    # update po files."
-	@echo "  make all          [LINGUA=en|zh|...]"
+	@echo "  make all          [LINGUA=en|it|zh|...]"
 	@echo "  make stat         # print statistics about po files."
 	@echo "  make clean        # Remove the build files."
 
 clean:
-	@rm -fr build po/*.mo hello en/hello en/html en/.validated-00book.xml en/examples/.run en/examples/results \
-          stylesheets/system-xsl en/figs/*-tmp.svg \
-          web/index-read.html.in \
-          en/figs/bad-merge-1.png \
-          en/figs/bad-merge-2.png \
-          en/figs/bad-merge-3.png \
-          en/figs/bad-merge-4.png \
-          en/figs/bad-merge-5.png \
-          en/figs/feature-branches.png \
-          en/figs/filelog.png \
-          en/figs/feature-branches.png \
-          en/figs/filelog.png \
-          en/figs/metadata.png \
-          en/figs/mq-stack.png \
-          en/figs/revlog.png \
-          en/figs/snapshot.png \
-          en/figs/tour-history.png \
-          en/figs/tour-merge-conflict.png \
-          en/figs/tour-merge-merge.png \
-          en/figs/tour-merge-pull.png \
-          en/figs/tour-merge-sep-repos.png \
-          en/figs/undo-manual-merge.png \
-          en/figs/undo-manual.png \
-          en/figs/undo-non-tip.png \
-          en/figs/undo-simple.png \
-          en/figs/wdir-after-commit.png \
-          en/figs/wdir-branch.png \
-          en/figs/wdir-merge.png \
-          en/figs/wdir-pre-branch.png \
-          en/figs/wdir.png
+	@rm -fr build hello po/*.mo /tmp/REV*-hello en/examples/results
+
+	@(for l in $(DBK_LANGUAGES); do \
+	  rm -fr $(subst en/figs/, $$l/figs/, $(images-gen))  $$l/examples/.run;\
+	done)
 
 all:
 ifdef LINGUA
 
 tidypo:
 ifdef LINGUA
+  ifneq "$(findstring $(LINGUA),$(PO_LANGUAGES))" ""
 	msgcat --sort-by-file --width=80 po/$(LINGUA).po > po/$(LINGUA).tmp && \
 	    mv po/$(LINGUA).tmp po/$(LINGUA).po;
+  endif
 else
 	for po in $(wildcard po/*.po); do \
 	    msgcat --sort-by-file --width=80 $$po > $$po.tmp && mv $$po.tmp $$po; \
 	    $(MAKE) $@ LINGUA=$$l; \
 	done
 else
-updatepo:
-ifneq "$(findstring $(LINGUA),$(PO_LANGUAGES))" ""
+po/$(LINGUA).po: $(wildcard en/*.xml)
+  ifneq "$(findstring $(LINGUA),$(PO_LANGUAGES))" ""
 	(cd po; \
 	$(UPDATEPO) -m ../en/00book.xml -p $(LINGUA).po; \
 	)
 	$(MAKE) tidypo LINGUA=$(LINGUA)
-endif
+  endif
+
+updatepo: po/$(LINGUA).po
 endif
 
 ifndef LINGUA
 validate: build/$(LINGUA)/source/hgbook.xml
 	xmllint --nonet --noout --postvalid --xinclude $<
 
-ifneq "$(findstring $(LINGUA),$(DBK_LANGUAGES))" ""
+  ifneq "$(findstring $(LINGUA),$(DBK_LANGUAGES))" ""
 $(LINGUA)/examples/.run:
-	(cd $(LINGUA)/examples; ./run-example -v -a)
+	if test -x $(LINGUA)/examples/run-example; then \
+	  (cd $(LINGUA)/examples; ./run-example -a); \
+	else \
+	  touch $@; \
+	fi
 
-build/$(LINGUA)/source/hgbook.xml: $(wildcard $(LINGUA)/*.xml) $(images) $(LINGUA)/examples/.run
+build/$(LINGUA)/source/hgbook.xml: $(wildcard $(LINGUA)/*.xml) $(subst en/figs/, $(LINGUA)/figs/, $(images-dst)) $(LINGUA)/examples/.run
 	mkdir -p build/$(LINGUA)/source/figs
 	cp $(LINGUA)/figs/*.png build/$(LINGUA)/source/figs
 	cp stylesheets/hgbook.css build/$(LINGUA)/source
 	(cd $(LINGUA); xmllint --nonet --noent --xinclude --postvalid --output ../$@.tmp 00book.xml)
 	cat $@.tmp | sed 's/\$$rev_id\$$/${rev_id}/' > $@
-else
+  else
 en/examples/.run:
-	(cd en/examples; ./run-example -v -a)
+	(cd en/examples; ./run-example -a)
 
 build/en/source/hgbook.xml:
 	${MAKE} LINGUA=en $@
 
-build/$(LINGUA)/source/hgbook.xml: $(wildcard en/*.xml) po/$(LINGUA).po $(images)
+build/$(LINGUA)/source/hgbook.xml: $(wildcard en/*.xml) po/$(LINGUA).po $(images-dst) en/examples/.run
 	mkdir -p build/$(LINGUA)/source/figs
 	cp en/figs/*.png build/$(LINGUA)/source/figs
 	cp stylesheets/hgbook.css build/$(LINGUA)/source
 	xmllint --nonet --noent --xinclude --postvalid --output $@.tmp en/hgbook.xml.$(LINGUA)
 	cat $@.tmp | sed 's/\$$rev_id\$$/${rev_id}/' > $@
 	mv en/hgbook.xml.$(LINGUA) build/$(LINGUA)/source
-endif
+  endif
 
 endif
 
 	(cd build/$(LINGUA)/source && $(FOP_HOME)/fop.sh -c $(FOP_HOME)/conf/userconfig.xml hgbook.fo ../pdf/hgbook.pdf)
 endif
 
+$(LINGUA)/figs/%.png: $(LINGUA)/figs/%.svg 
+	if test -x $(LINGUA)/fixsvg; then \
+	  $(LINGUA)/fixsvg $<; \
+	  inkscape -D -d 120 -e $@ $<-tmp.svg; \
+	else \
+	  inkscape -D -d 120 -e $@ $<; \
+	fi
+
+$(LINGUA)/figs/%.svg: $(LINGUA)/figs/%.dot
+	dot -Tsvg -o $@ $<
+
 en/figs/%.png: en/figs/%.svg en/fixsvg
 	en/fixsvg $<
 	inkscape -D -d 120 -e $@ $<-tmp.svg
 #
-# Please create your Makefile.vars file from this template file.
+# Please create your Makefile.vars from this template file.
 #
 # Please use absolute path, DO NOT use relative path !
 #
 
-# po4a (>= 0.36.1): Only for PO based Makefile !
+# po4a (>= 0.36.1): Only for PO based translation !
 # po4A_HOME=/usr/bin
 # PO4A_LIB=/usr/share/perl5
-PO4A_HOME=/home/dongsheng/var/svn/i18n-zh/trunk/lib/po4a
+PO4A_HOME=/home/dongsheng/vcs/svn/i18n-zh/trunk/lib/po4a
 PO4A_LIB=$(PO4A_HOME)/lib
 
 # saxon65.jar, saxon65-dbxsl.jar, xml-commons-resolver-1.2.jar: Only for pdf format !
-JAVA_LIB=/home/dongsheng/var/svn/i18n-zh/trunk/lib/share/java
+JAVA_LIB=/home/dongsheng/vcs/svn/i18n-zh/trunk/lib/share/java
 
 # fop (>= 0.9.6): Only for pdf format !
-FOP_HOME=/home/dongsheng/var/svn/i18n-zh/trunk/lib/fop
+FOP_HOME=/home/dongsheng/vcs/svn/i18n-zh/trunk/lib/fop
 
 # docbook-xsl (>= 1.74.3): Only for ePub format !
-DB2EPUB=/home/dongsheng/var/svn/i18n-zh/trunk/lib/docbook/docbook-xsl/epub/bin/dbtoepub
+DB2EPUB=/home/dongsheng/vcs/svn/i18n-zh/trunk/lib/docbook/docbook-xsl/epub/bin/dbtoepub
 
 Here's a top-level tour of interesting directories:
 
-en        English-language content
-es        Spanish-language content
-examples  Miscellaneous example scripts
-tools     Old, largely unused conversion scripts
-web       Content and comment system for http://hgbook.red-bean.com/
-xsl       XSLT scripts for generating HTML
+contrib         Miscellaneous scripts
+en              English-language content (DocBook XML format)
+stylesheets     XSLT scripts for generating HTML
+web             Content and comment system for http://hgbook.red-bean.com/
+
+po              PO based translation    Chinese translation
+
+it              Italian translation     DocBook XML format
+es              Spanish translation     old tex format
+ja              Japanese translation    old tex format
 
 I. PRIMER
 
-  DocBook has a tortured, confusing history.  Before you do anything,
-  take a look at Eric Raymond's excellent "DocBook Demystification HOWTO":
+  DocBook has a tortured, confusing history. Before you do anything,
+  take a look at:
 
-      http://tldp.org/HOWTO/DocBook-Demystification-HOWTO/
-
-  It's very short and clears up many things.
-
+      http://wiki.docbook.org/topic/DocBookTutorials
 
 II. COMPILING THE DOCS
 
-
 1. Install XML DTD and XSL stylesheets for DocBook
 
       % sudo apt-get install docbook-xml docbook-xsl
 
       % sudo apt-get install libxml2-utils
 
-3. Install graph drawing tools
+3. Install graph drawing and patches tools
 
-      % sudo apt-get install graphviz inkscape
+      % sudo apt-get install graphviz inkscape patchutils
 
 4. Install pdf support
 
       % sudo apt-get install openjdk-6-jdk docbook-xsl-saxon libsaxon-java fop
 
-  The Makefile will actually invoke tools/fop/fop.sh, you should do
+  The Makefile will actually invoke $FOP_HOME/fop.sh, you should do
   some trick, let fop's CLASSPATH include saxon.jar and docbook-xsl-saxon.jar .
 
-5. Make
+5. Configure XML Catalogs
+  For non pdf output, we use xsltproc for XSLT process, xsltproc use system
+  catalog files automatically, usually /etc/xml/catalog. Users do not need to
+  care about it.
+
+  For pdf output, we need use the xsl extensions (docbook-xsl-saxon), so we must
+  create file $JAVA_LIB/CatalogManager.properties like this:
+
+      catalogs=/etc/xml/catalog
+      relative-catalogs=true
+      static-catalog=yes
+      catalog-class-name=org.apache.xml.resolver.Resolver
+      verbosity=1
+
+6. Create Makefile.vars
+  Please create your Makefile.vars from Makefile.vars.tmpl .
+
+7. Make
   Run 'make' for more details, for example:
 
-  * make all document(pdf, html and html-single for all languages)
+  * make all document(pdf, epub, html and html-single for all languages)
       % make all
 
-  * make english document(pdf, html and html-single for all languages)
+  * make english document(pdf, epub, html and html-single for all languages)
       % make LINGUA=en all
 
-  * make Chinese document(pdf, html and html-single for all languages)
+  * make Chinese document(pdf, epub, html and html-single for all languages)
       % make LINGUA=zh all
 
   * make Chinese pdf document
 
 In addition to everything in section II:
 
-
-1. Get a nice editing environment for SGML/XML.
+1. Get a nice editing environment for XML
 
   This isn't strictly required, but it's nice when your editor
   colorizes things, understands the DTD, tells you what tags you can
   insert, etc.
 
-  If you use emacs, we recommend the PSGML major-mode.  Most free
+  If you use emacs, we recommend the nxml-mode. Most free
   operating systems package it, or its home page is here:
 
-      http://www.lysator.liu.se/projects/about_psgml.html
+      http://www.emacswiki.org/emacs/NxmlMode
 
   If you use vim, you might check out xmledit, at:
 
       http://www.vim.org/scripts/script.php?script_id=301
 
-
-2. Get a validating parser.
+2. Get a validating parser
 
   Actually, if you have what you need to compile the documentation,
   then you almost certainly have an XML validator installed already -
 
       $ make validate
 
-3. Read about DocBook.
+3. Read about DocBook
 
   You'll want to get real intimate with a DocBook reference, such as
   can be found at:  http://www.docbook.org/tdg/en/html/
 #!/bin/sh
 
+#
+# Package build results & Upload to i18n-zh
+#
+
 build_dir=`dirname "$0"`/../build
 rev_id=`hg parents --template '{date|shortdate}' | sed 's/-//g'`
 
-for l in en zh; do
+for l in en zh it; do
   (
   if [ ! -d "${build_dir}/${l}" ] ; then
     continue
 	<command role="hg-ext-mq">qpop</command> each operate on a
 	single patch at a time by default, you can push and pop many
 	patches in one go.  The <option
-	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
+	  role="hg-ext-mq-cmd-qpush-opt">-a</option> option to
 	<command role="hg-ext-mq">qpush</command> causes it to push
 	all unapplied patches, while the <option
 	  role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command
 	named <option>-f</option>.  The exact meaning of
 	<option>-f</option> depends on the command.  For example,
 	<command role="hg-cmd">hg qnew <option
-	    role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
+	    role="hg-ext-mq-cmd-qnew-opt">-f</option></command>
 	will incorporate any outstanding changes into the new patch it
 	creates, but <command role="hg-cmd">hg qpop <option
-	    role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
+	    role="hg-ext-mq-cmd-qpop-opt">-f</option></command>
 	will revert modifications to any files affected by the patch
 	that it is popping.  Be sure to read the documentation for a
 	command's <option>-f</option> option before you use it!</para>
 
     <para id="x_404">On my old, slow laptop, I was able to <command
 	role="hg-cmd">hg qpush <option
-	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
+	  role="hg-ext-mq-cmd-qpush-opt">-a</option></command> all
       1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop
-	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
+	<option role="hg-ext-mq-cmd-qpop-opt">-a</option></command>
       them all in 30 seconds.  (On a newer laptop, the time to push
       all patches dropped to two minutes.)  I could <command
 	role="hg-ext-mq">qrefresh</command> one of the biggest patches
 	  -a</option></command> your patches, then <command
 	role="hg-cmd">hg pull</command> changes into the underlying
       repository, and finally <command role="hg-cmd">hg qpush <option
-	  role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your
+	  role="hg-ext-mq-cmd-qpop-opt">-a</option></command> your
       patches again.  MQ will stop pushing any time it runs across a
       patch that fails to apply during conflicts, allowing you to fix
       your conflicts, <command role="hg-ext-mq">qrefresh</command> the
 	  update</command> changes to patches or the <filename
 	  role="special">series</filename> file, you will have to
 	<command role="hg-cmd">hg qpop <option
-	    role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
+	    role="hg-ext-mq-cmd-qpop-opt">-a</option></command> and
 	then <command role="hg-cmd">hg qpush <option
-	    role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in
+	    role="hg-ext-mq-cmd-qpush-opt">-a</option></command> in
 	the underlying repository to see those changes show up there.
 	If you forget to do this, you can confuse MQ's idea of which
 	patches are applied.</para>
 
 <preface id="chap:preface">
   <?dbhtml filename="preface.html"?>
-  <title>Preface</title>
+  <title>Préface</title>
 
   <sect1>
     <title>Un conte technique</title>
 
     <para id="x_72f">Bien qu'à cette époque je passais beaucoup de temps
     à travailler sur les entrailles de Mercurial, je me suis mis à la 
-    rédaction de ce livre parce que ça me semblait être la manière la plus efficace
+    rédaction de ce livre parce qu'il me semblait la manière la plus efficace
     d'aider notre logiciel à atteindre un vaste auditoire, toujours avec 
-    l'idée que la gestion de révisions devrait être distribuée par nature. J'ai 
+    l'idée que la gestion de révision devrait être distribuée par nature. J'ai 
     publié ce libre en ligne sous une licence libre pour la même raison : pour 
     diffuser la parole auprès du monde.</para>
 
     <para id="x_730">Il y a un rythme familier à un bon livre sur un logiciel 
     qui ressemble de près au fait de conter une histoire : Pourquoi ceci est ? 
-    Pourquoi ceci est important ? Comment peut il m'aider ? Comment m'en 
+    Pourquoi ceci est important ? Comment peut-il m'aider ? Comment m'en 
     servir ? Dans ce livre, j'essaye de répondre à toutes ces questions pour
     la gestion de révisions distribuée en général, et pour Mercurial en 
     particulier.</para>
     </para>
 
     <para id="x_734">Mes collègues et amis m'ont aidé et assisté de 
-    de nombreuses manières. Cette liste de personne est nécessaire mais très
+    de nombreuses manières. Cette liste de personnes est forcément très
     incomplète : Stephen Hahn, Karyn Ritter, Bonnie Corwin, James Vasile,
     Matt Norwood, Eben Moglen, Bradley Kuhn, Robert Walsh, Jeremy
     Fitzhardinge, Rachel Chalmers.</para>
 
     <para id="x_735">J'ai conçu ce livre de manière ouverte, en publiant
-    des brouillons de chapitres du livre sur des site web, au fur et à 
+    des brouillons des chapitres du livre sur des site web, au fur et à 
     mesure que je les réalisais. Leurs lecteurs m'ont fait des retours 
     utilisant l'application web que j'avais développée. A la fin de sa
     conception, plus de 100 personnes m'avaient fait des commentaires, 
-    un chiffre incroyable quand on considère que ce système de 
+    un chiffre incroyable quand l'on considère que ce système de 
     commentaire n'a tourné que dans les deux derniers mois de la 
     rédaction du livre.</para>
 
     <para id="x_736">J'aimerais particulièrement remercier les 
     personnes suivantes, dont les commentaires représentent plus
-    d'un tiers de l'ensemble de ces derniers. Je voudrai les 
+    d'un tiers de l'ensemble de ces derniers. Je voudrais les 
     remercier pour leurs attentions et efforts à me faire des retours
     très détaillés.</para>
 
 	<command role="hg-ext-mq">qpop</command> each operate on a
 	single patch at a time by default, you can push and pop many
 	patches in one go.  The <option
-	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option> option to
+	  role="hg-ext-mq-cmd-qpush-opt">-a</option> option to
 	<command role="hg-ext-mq">qpush</command> causes it to push
 	all unapplied patches, while the <option
 	  role="hg-ext-mq-cmd-qpop-opt">-a</option> option to <command
 	named <option>-f</option>.  The exact meaning of
 	<option>-f</option> depends on the command.  For example,
 	<command role="hg-cmd">hg qnew <option
-	    role="hg-ext-mq-cmd-qnew-opt">hg -f</option></command>
+	    role="hg-ext-mq-cmd-qnew-opt">-f</option></command>
 	will incorporate any outstanding changes into the new patch it
 	creates, but <command role="hg-cmd">hg qpop <option
-	    role="hg-ext-mq-cmd-qpop-opt">hg -f</option></command>
+	    role="hg-ext-mq-cmd-qpop-opt">-f</option></command>
 	will revert modifications to any files affected by the patch
 	that it is popping.  Be sure to read the documentation for a
 	command's <option>-f</option> option before you use it!</para>
 
     <para id="x_404">On my old, slow laptop, I was able to <command
 	role="hg-cmd">hg qpush <option
-	  role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> all
+	  role="hg-ext-mq-cmd-qpush-opt">-a</option></command> all
       1,738 patches in 3.5 minutes, and <command role="hg-cmd">hg qpop
-	<option role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command>
+	<option role="hg-ext-mq-cmd-qpop-opt">-a</option></command>
       them all in 30 seconds.  (On a newer laptop, the time to push
       all patches dropped to two minutes.)  I could <command
 	role="hg-ext-mq">qrefresh</command> one of the biggest patches
 	  -a</option></command> your patches, then <command
 	role="hg-cmd">hg pull</command> changes into the underlying
       repository, and finally <command role="hg-cmd">hg qpush <option
-	  role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> your
+	  role="hg-ext-mq-cmd-qpop-opt">-a</option></command> your
       patches again.  MQ will stop pushing any time it runs across a
       patch that fails to apply during conflicts, allowing you to fix
       your conflicts, <command role="hg-ext-mq">qrefresh</command> the
 	  update</command> changes to patches or the <filename
 	  role="special">series</filename> file, you will have to
 	<command role="hg-cmd">hg qpop <option
-	    role="hg-ext-mq-cmd-qpop-opt">hg -a</option></command> and
+	    role="hg-ext-mq-cmd-qpop-opt">-a</option></command> and
 	then <command role="hg-cmd">hg qpush <option
-	    role="hg-ext-mq-cmd-qpush-opt">hg -a</option></command> in
+	    role="hg-ext-mq-cmd-qpush-opt">-a</option></command> in
 	the underlying repository to see those changes show up there.
 	If you forget to do this, you can confuse MQ's idea of which
 	patches are applied.</para>

it/figs/caution.png

Added
New image

it/figs/note.png

Added
New image

it/figs/tip.png

Added
New image

it/figs/warning.png

Added
New image

plastex-theme/README.txt

+This is a theme designed to use with the plasTeX page template
+renderer to generate commentable documents.
+
+To "install" it, symlink this folder from the plasTeX XHTML Themes
+folder. Example:
+
+faraday:/usr/lib/pymodules/python2.5/plasTeX/Renderers/XHTML/Themes#
+ln -s (this folder) alqua
+
+Usage example:
+
+$ plastex --theme=alqua --split-level=0 mylatex.tex

plastex-theme/default-layout.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html tal:define="links self/links" 
+      xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+
+    <meta name="generator" content="plasTeX" />
+    <meta http-equiv="content-type"
+          tal:attributes="content string:text/html;; charset=${config/files/output-encoding}" />
+
+    <title tal:condition="python:path('self/level') &gt; -10"
+           tal:content="stripped string:${links/document/title}: ${self/title}">
+      Book title
+    </title>
+    <link tal:condition="links/next" 
+          rel="next" 
+          tal:attributes="href links/next/url; title links/next/title/textContent" />
+    <link tal:condition="links/prev" 
+          rel="prev" 
+          tal:attributes="href links/prev/url; title links/prev/title/textContent" />
+    <link tal:condition="links/up" 
+          rel="up" 
+          tal:attributes="href links/up/url; title links/up/title/textContent" />
+
+    <link rel="stylesheet" href="styles/styles.css"/>
+    <link rel="stylesheet" href="/support/styles/styles.css"/>
+
+    <link rel="alternate" type="application/atom+xml" title="Comments"
+          href="/feeds/comments/"/>
+    <link rel="shortcut icon" type="image/png"
+          href="/support/figs/favicon.png"/>
+
+    <script type="text/javascript" src="/support/javascript/jquery.js"></script>
+    <script type="text/javascript" src="/support/javascript/form-min.js"></script>
+
+  </head>
+
+  <body>
+
+    <div class="navheader"><h2 class="booktitle">
+        <tal:booktitle replace="links/document/title" />
+        <div class="authors">by 
+          <tal:author tal:content="links/document/attributes/author">
+            Author
+          </tal:author>
+        </div>
+      </h2>
+    </div>
+
+    <div class="navheader" metal:define-macro="navigation">
+      <table width="100%">
+        <tr>
+          <td width="40%" align="left">
+            <a tal:condition="links/prev"
+               tal:attributes="href links/prev/url;
+                               title stripped:links/prev/title"
+               accesskey="p">Prev</a> </td>
+          <td width="20%" align="center"> 
+            <a tal:condition="links/up"
+               tal:attributes="href links/up/url">Up</a>
+          </td>
+          <td width="40%" align="right"> 
+            <a tal:condition="links/next"
+               tal:attributes="href links/next/url;
+                               title stripped:links/next/title"
+               accesskey="n">Next</a>
+          </td>
+        </tr>
+        <tr>
+          <td width="40%" align="left">
+            <span tal:condition="links/prev"
+               tal:replace="stripped:links/prev/title">Prev</span>
+          </td>
+          <td width="20%" align="center"> </td>
+          <td width="40%" align="right"> 
+            <span tal:condition="links/next"
+               tal:replace="stripped:links/next/title">Next</span>
+          </td>
+        </tr>
+      </table>
+    </div>
+
+    <div class="chapter" 
+         tal:attributes="id string:${links/document/title}: ${self/title}">
+      
+      <div class="file_contents" tal:content="self">File contents.</div>
+      
+      <div tal:condition="self/tableofcontents" 
+           tal:attributes="class
+                           string:contents
+                           ${self/nodeName}-contents">
+        <ul>
+          <li tal:repeat="section self/tableofcontents"><a href="." tal:attributes="href section/url" tal:content="section/fullTocEntry">Aliquam est. Aliquam fringilla pede</a>
+            <ul tal:condition="section/tableofcontents">
+              <li tal:repeat="subsection section/tableofcontents"><a href="." tal:attributes="href subsection/url" tal:content="subsection/fullTocEntry"></a>
+                <ul tal:condition="subsection/tableofcontents">
+                  <li tal:repeat="subsubsection subsection/tableofcontents"><a href="." tal:attributes="href subsubsection/url" tal:content="subsubsection/fullTocEntry"></a>
+                    <ul tal:condition="subsubsection/tableofcontents">
+                      <li tal:repeat="paragraph subsubsection/tableofcontents"><a href="." tal:attributes="href paragraph/url" tal:content="paragraph/fullTocEntry"></a>
+                        <ul tal:condition="paragraph/tableofcontents">
+                          <li tal:repeat="subparagraph paragraph/tableofcontents"><a href="." tal:attributes="href subparagraph/url" tal:content="subparagraph/fullTocEntry"></a></li>
+                        </ul>
+                      </li>
+                    </ul>
+                  </li>
+                </ul>
+              </li>
+            </ul>
+          </li>
+          <li tal:replace="nothing"><a href=".">Maecenas id purus</a></li>
+        </ul>
+      </div>
+
+
+      <div id="footnotes" tal:condition="self/footnotes">
+        <p><b>Footnotes</b></p>
+        <ol>
+          <li tal:repeat="footnote self/footnotes" 
+              tal:content="footnote" 
+              tal:attributes="id footnote/id">footnote text</li>
+        </ol>
+      </div>
+
+    </div>
+
+    <div class="navfooter"
+	 metal:use-macro="template/macros/navigation" />
+
+    <div class="hgbookfooter"> <p><img src="/support/icons/rss.png"> Want to stay
+	up to date? Subscribe to the comment feed for the 
+        <a class="feed"
+	   href="/feeds/comments/">entire book</a>.</p> 
+      <p>Icons by
+	<a href="mailto:mattahan@gmail.com">Paul Davey</a> aka 
+        <a href="http://mattahan.deviantart.com/">Mattahan</a>.</p>
+      </div>
+
+  </body>
+
+  <script language="javascript" src="icons/imgadjust.js"
+	  type="text/javascript">
+  </script>
+  <script type="text/javascript" src="/support/javascript/hsbook.js">
+  </script>
+
+</html>
 msgstr ""
 "Project-Id-Version: hgbook 1.2\n"
 "POT-Creation-Date: 2009-05-21 14:26+0800\n"
-"PO-Revision-Date: 2009-05-21 16:42+0800\n"
+"PO-Revision-Date: 2009-10-21 16:42+0800\n"
 "Last-Translator: 宋冬生 <songdonogsheng@live.cn>\n"
 "Language-Team: Simplified Chinese <i18n-zh@googlegroups.com >\n"
 "MIME-Version: 1.0\n"
 #. type: Content of: <book><chapter><title>
 #: ../en/ch01-intro.xml:5
 msgid "How did we get here?"
-msgstr ""
+msgstr "写在前面"
 
 #. type: Content of: <book><chapter><sect1><title>
 #: ../en/ch01-intro.xml:8
 <?xml version="1.0"?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+      xmlns:fo="http://www.w3.org/1999/XSL/Format"
+      version='1.0'>
 
   <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
 
+  <xsl:param name="l10n.gentext.language" select="'en'"/>
+  <xsl:param name="paper.type" select="'A4'"></xsl:param>
   <xsl:param name="draft.mode" select="no"/>
 
   <!-- These extensions are required for table printing and other stuff -->
   <xsl:param name="section.autolabel" select="1" />
   <xsl:param name="section.label.includes.component.label">1</xsl:param>
 
-  <xsl:param name="variablelist.as.blocks" select="1" />        <!-- fo only -->
-  <xsl:param name="hyphenate">false</xsl:param>                 <!-- fo only -->
-  <xsl:param name="paper.type" select="'A4'"></xsl:param>       <!-- fo only -->
+  <xsl:param name="variablelist.as.blocks" select="1" />
+  <xsl:param name="hyphenate">false</xsl:param>
 
-  <!-- Default font settings -->
-  <!--
-  <xsl:param name="title.font.family">sans-serif</xsl:param>
-  <xsl:param name="body.font.family">serif</xsl:param>
-  <xsl:param name="sans.font.family">sans-serif</xsl:param>
-  <xsl:param name="dingbat.font.family">serif</xsl:param>
-  <xsl:param name="monospace.font.family">monospace</xsl:param>
+  <!-- Font settings, we use characters out of base14 even for english -->
+  <xsl:param name="title.font.family">sans-serif,Arial</xsl:param>
+  <xsl:param name="body.font.family">serif,Times New Roman</xsl:param>
+  <xsl:param name="sans.font.family">sans-serif,Arial</xsl:param>
+  <xsl:param name="dingbat.font.family">serif,Times New Roman</xsl:param>
+  <xsl:param name="monospace.font.family">monospace,Courier New</xsl:param>
   <xsl:param name="symbol.font.family">Symbol,ZapfDingbats</xsl:param>
-  -->
 
-  <!-- Custom font settings - preferred truetype font -->
-  <xsl:param name="title.font.family">Calibri,sans-serif,SimHei</xsl:param>
-  <xsl:param name="body.font.family">Cambria,Cambria Math,serif,SimSun</xsl:param>
-  <xsl:param name="sans.font.family">Calibri,sans-serif,SimHei</xsl:param>
-  <xsl:param name="dingbat.font.family">Cambria,Cambria Math,serif,SimSun</xsl:param>
-  <xsl:param name="monospace.font.family">Courier New,monospace,FangSong</xsl:param>
-
-  <!-- Page related Settings -->
+  <!-- Page related settings -->
   <xsl:param name="page.margin.inner">1.5cm</xsl:param>
   <xsl:param name="page.margin.outer">1.5cm</xsl:param>
   <xsl:param name="title.margin.left">0pt</xsl:param>
   <xsl:param name="body.start.indent">24pt</xsl:param>
   <xsl:param name="body.end.indent">0pt</xsl:param>
 
-  <!-- Breaking long lines -->
-  <xsl:param name="hyphenate.verbatim">0</xsl:param>
-  <xsl:attribute-set name="monospace.verbatim.properties"
-                     use-attribute-sets="verbatim.properties monospace.properties">
-    <xsl:attribute name="wrap-option">wrap</xsl:attribute>
-    <xsl:attribute name="hyphenation-character">&#x25BA;</xsl:attribute>
-  </xsl:attribute-set>
-
   <!-- Prevent blank pages in output -->
   <xsl:template name="book.titlepage.before.verso">
   </xsl:template>
   <xsl:template name="book.titlepage.separator">
   </xsl:template>
 
+  <!-- titlepage settings -->
+  <xsl:template name="book.titlepage">
+    <fo:block>
+        <fo:table table-layout="fixed" space-after.optimum="10pt" width="100%">
+            <fo:table-body>
+                <fo:table-row>
+                    <fo:table-cell>
+                        <fo:block text-align="center">
+                          <!--fo:external-graphic src="url(figs/cover-logo.png)"
+                              width="90%"  height="auto" content-width="scale-to-fit" content-height="scale-to-fit" /-->
+                        </fo:block>
+                    </fo:table-cell>
+                </fo:table-row>
+            </fo:table-body>
+        </fo:table>
+    </fo:block>
+
+    <fo:block text-align="center" color="#000000" margin-left="1cm" margin-right="1cm"
+        space-before.optimum="3cm" space-after.optimum="5.0cm"
+        font-weight="900" font-size="32pt">
+      <xsl:attribute name="font-family"><xsl:value-of select="$title.font.family" /></xsl:attribute>
+
+      <xsl:value-of select="/book/title"/>
+    </fo:block>
+
+    <fo:block text-align="center" color="#000080" margin-left="1cm" margin-right="1cm"
+        space-before.optimum="2cm" space-after.optimum="8.0cm"
+        font-weight="900" font-size="16pt">
+      <xsl:attribute name="font-family"><xsl:value-of select="$title.font.family" /></xsl:attribute>
+
+      <xsl:value-of select="/book/subtitle"/>
+    </fo:block>
+
+    <fo:block text-align="center" color="#000000" margin-left="1cm" margin-right="1cm"
+        space-before.optimum="8cm" space-after.optimum="10cm"
+        font-weight="600" font-size="24pt">
+      <xsl:attribute name="font-family"><xsl:value-of select="$title.font.family" /></xsl:attribute>
+
+      <xsl:call-template name="person.name.list">
+        <xsl:with-param name="person.list" select="bookinfo/authorgroup/author"/>
+      </xsl:call-template>
+    </fo:block>
+
+    <!--fo:block text-align="end"    color="#666D70" margin-left="1cm" margin-right="1cm"
+        font-family="sans-serif" font-weight="normal" font-size="10pt" >
+      <xsl:value-of select="/book/subtitle"/>
+    </fo:block-->
+  </xsl:template>
+
+  <!-- title settings -->
+  <xsl:attribute-set name="preface.titlepage.recto.style">
+    <xsl:attribute name="color">#7C1C51</xsl:attribute>
+  </xsl:attribute-set>
+  <xsl:attribute-set name="chapter.titlepage.recto.style">
+    <xsl:attribute name="color">#7C1C51</xsl:attribute>
+  </xsl:attribute-set>
+  <xsl:attribute-set name="section.titlepage.recto.style">
+    <xsl:attribute name="color">#7C1C51</xsl:attribute>
+  </xsl:attribute-set>
+  <xsl:attribute-set name="appendix.titlepage.recto.style">
+    <xsl:attribute name="color">#7C1C51</xsl:attribute>
+  </xsl:attribute-set>
+
+  <!-- Verbatim related settings -->
+  <xsl:param name="hyphenate.verbatim">0</xsl:param>
+
+  <xsl:attribute-set name="monospace.properties">
+    <xsl:attribute name="font-family">
+      <xsl:value-of select="$monospace.font.family"/>
+    </xsl:attribute>
+      <xsl:attribute name="color">#000080</xsl:attribute>
+  </xsl:attribute-set>
+
+  <xsl:attribute-set name="monospace.verbatim.properties"
+                     use-attribute-sets="verbatim.properties monospace.properties">
+    <xsl:attribute name="border-color">blue</xsl:attribute>
+    <xsl:attribute name="border-width">thin</xsl:attribute>
+    <xsl:attribute name="border-style">solid</xsl:attribute>
+    <xsl:attribute name="font-size">8pt</xsl:attribute>
+    <xsl:attribute name="wrap-option">wrap</xsl:attribute>
+    <xsl:attribute name="hyphenation-character">&#x25BA;</xsl:attribute>
+    <!--xsl:attribute name="hyphenation-character">&#x27A4;</xsl:attribute-->
+  </xsl:attribute-set>
+
+  <!-- emphasis settings -->
+  <xsl:template match="emphasis">
+    <xsl:param name="content">
+      <xsl:call-template name="simple.xlink">
+        <xsl:with-param name="content">
+          <xsl:apply-templates/>
+        </xsl:with-param>
+      </xsl:call-template>
+    </xsl:param>
+
+    <fo:inline color="#7C1C51" font-weight="bold">
+      <xsl:copy-of select="$content"/>
+    </fo:inline>
+  </xsl:template>
+
   <!-- Colourize links in output -->
   <xsl:attribute-set name="xref.properties">
     <xsl:attribute name="color">

stylesheets/zh/fo.xsl

   <xsl:param name="l10n.gentext.language" select="'zh'"/>
 
   <!-- Chinese font related settings -->
+  <xsl:param name="title.font.family">Calibri,sans-serif,SimHei</xsl:param>
+  <xsl:param name="body.font.family">Cambria,Cambria Math,serif,SimSun</xsl:param>
+  <xsl:param name="sans.font.family">Calibri,sans-serif,SimHei</xsl:param>
+  <xsl:param name="dingbat.font.family">Cambria,Cambria Math,serif,SimSun</xsl:param>
+  <xsl:param name="monospace.font.family">Courier New,monospace,FangSong</xsl:param>
+
+  <!-- Chinese para related settings -->
   <xsl:param name="body.font.master">12</xsl:param>
 
   <xsl:attribute-set name="standard.para.spacing" use-attribute-sets="normal.para.spacing">

web/hgbook/__init__.py

+import admin
     date_hierarchy = 'date'
     list_filter = ['date', 'submitter_name']
     search_fields = ['title', 'submitter_name', 'submitter_url']
-    fields = (
+    fieldsets = (
         (None, {'fields': ('submitter_name', 'element', 'comment')}),
-        ('Review and presentation state',
-         {'fields': ('reviewed', 'hidden')}),
-        ('Other info', {'fields': ('date', 'submitter_url', 'ip')}),
+        ('Review and presentation state', {'fields': ('reviewed', 'hidden')}),
+        ('Other info', {'fields': ('submitter_url', 'ip')}),
         )
+    # XXX: adding 'date' to the 'Other info' fieldset results in a
+    # ImproperlyConfigured error. :S
 
 class ElementAdmin(admin.ModelAdmin):
     search_fields = ['id', 'chapter']

web/hgbook/comments/models.py

 class Element(models.Model):
     id = models.CharField('ID attribute', max_length=64, editable=False,
                           primary_key=True)
-    chapter = models.CharField('Chapter ID', max_length=64, editable=False,
+    chapter = models.CharField('Chapter ID', max_length=100, editable=False,
                                db_index=True)
     title = models.CharField('Section title', max_length=256, editable=False)
 

web/hgbook/converter.py

+from lxml import etree
+from lxml import html
+from lxml.cssselect import CSSSelector
+import md5
+import sys
+
+
+args = sys.argv[1:]
+
+# django stuff
+from django.core.management import setup_environ
+import settings # Assumed to be in the same directory.
+setup_environ(settings)       # ugly django collateral effects :(
+from comments.models import Element
+
+doc_id = 'MMSC'
+sel = CSSSelector('div.chapter p, pre, h1, table.equation')
+chapter_sel = CSSSelector('div.chapter')
+
+try:
+    filename = args[0]
+except IndexError:
+    raise IndexError("Usage: %s <path-to-html-file>" % __file__)
+
+tree = etree.parse(filename, html.HTMLParser(remove_blank_text=True))
+root = tree.getroot()
+
+chapter = chapter_sel(root)[0]
+chapter_title = chapter.get('id').split(':')[1]
+chapter_hash = md5.new(chapter.get('id').encode('utf8')).hexdigest()
+
+chapter.set('id', chapter_hash)
+
+for element in sel(root):
+    hsh_source = element.text or element.get('alt') or etree.tostring(element)
+
+    if hsh_source:
+        hsh_source_encoded = hsh_source.encode('utf8')
+        hsh = md5.new(hsh_source_encoded).hexdigest()
+        element.set('id', '%s-%s' % (chapter_hash, hsh))
+    
+        # create the commentable element in the DB
+        e = Element()
+        e.id = '%s-%s' % (chapter_hash, hsh)
+        e.chapter = chapter_hash
+        e.title = chapter_title
+        e.save()
+
+
+
+print etree.tostring(root)      # pipe to a file if you wish
+

web/hgbook/settings.py

 TEMPLATE_DEBUG = DEBUG
 
 ADMINS = (
-    ("Bryan O'Sullivan", 'bos@serpentine.com'),
+    ("Bryan O'Sullivan", 'bos@localhost'),
 )
 
 MANAGERS = ADMINS
-import os
+import os, sys
 from django.conf.urls.defaults import *
 import hgbook.comments.feeds as feeds
 from django.contrib import admin
      {'feed_dict': feeds}),          
 
     # Only uncomment this for local testing without Apache.
-    # (r'^html/(?P<path>.*)$', 'django.views.static.serve',
-    # {'document_root': os.path.realpath(os.path.dirname(
-    #    sys.modules[__name__].__file__) + '/../../en/html'),
+     (r'^html/(?P<path>.*)$', 'django.views.static.serve',
+     {'document_root': os.path.realpath(os.path.dirname(
+        sys.modules[__name__].__file__) + '/../html')}),
+     (r'^support/(?P<path>.*)$', 'django.views.static.serve',
+     {'document_root': os.path.realpath(os.path.dirname(
+        sys.modules[__name__].__file__) + '/../support')}),
 
     # Uncomment this for admin:
     (r'^admin/(.*)', admin.site.root),

web/icons/caution.png

Removed
Old image

web/icons/favicon.png

Removed
Old image

web/icons/important.png

Removed
Old image

web/icons/note.png

Removed
Old image

web/icons/remark.png

Removed
Old image

web/icons/rss.png

Removed
Old image

web/icons/shell.png

Removed
Old image

web/icons/source.png

Removed
Old image

web/icons/tip.png

Removed
Old image

web/icons/warning.png

Removed
Old image

web/javascript/form-min.js

-(function($){$.fn.ajaxSubmit=function(_2){if(typeof _2=="function"){_2={success:_2};}_2=$.extend({url:this.attr("action")||window.location,type:this.attr("method")||"GET"},_2||{});var _3={};$.event.trigger("form.pre.serialize",[this,_2,_3]);if(_3.veto){return this;}var a=this.formToArray(_2.semantic);if(_2.data){for(var n in _2.data){a.push({name:n,value:_2.data[n]});}}if(_2.beforeSubmit&&_2.beforeSubmit(a,this,_2)===false){return this;}$.event.trigger("form.submit.validate",[a,this,_2,_3]);if(_3.veto){return this;}var q=$.param(a);if(_2.type.toUpperCase()=="GET"){_2.url+=(_2.url.indexOf("?")>=0?"&":"?")+q;_2.data=null;}else{_2.data=q;}var _7=this,callbacks=[];if(_2.resetForm){callbacks.push(function(){_7.resetForm();});}if(_2.clearForm){callbacks.push(function(){_7.clearForm();});}if(!_2.dataType&&_2.target){var _8=_2.success||function(){};callbacks.push(function(_9){if(this.evalScripts){$(_2.target).attr("innerHTML",_9).evalScripts().each(_8,arguments);}else{$(_2.target).html(_9).each(_8,arguments);}});}else{if(_2.success){callbacks.push(_2.success);}}_2.success=function(_a,_b){for(var i=0,max=callbacks.length;i<max;i++){callbacks[i](_a,_b,_7);}};var _d=$("input:file",this).fieldValue();var _e=false;for(var j=0;j<_d.length;j++){if(_d[j]){_e=true;}}if(_2.iframe||_e){fileUpload();}else{$.ajax(_2);}$.event.trigger("form.submit.notify",[this,_2]);return this;function fileUpload(){var _10=_7[0];var _11=$.extend({},$.ajaxSettings,_2);var id="jqFormIO"+$.fn.ajaxSubmit.counter++;var $io=$("<iframe id=\""+id+"\" name=\""+id+"\" />");var io=$io[0];var op8=$.browser.opera&&window.opera.version()<9;if($.browser.msie||op8){io.src="javascript:false;document.write(\"\");";}$io.css({position:"absolute",top:"-1000px",left:"-1000px"});var xhr={responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){}};var g=_11.global;if(g&&!$.active++){$.event.trigger("ajaxStart");}if(g){$.event.trigger("ajaxSend",[xhr,_11]);}var _18=0;var _19=0;setTimeout(function(){$io.appendTo("body");io.attachEvent?io.attachEvent("onload",cb):io.addEventListener("load",cb,false);var _1a=_10.encoding?"encoding":"enctype";var t=_7.attr("target");_7.attr({target:id,method:"POST",action:_11.url});_10[_1a]="multipart/form-data";if(_11.timeout){setTimeout(function(){_19=true;cb();},_11.timeout);}_10.submit();_7.attr("target",t);},10);function cb(){if(_18++){return;}io.detachEvent?io.detachEvent("onload",cb):io.removeEventListener("load",cb,false);var ok=true;try{if(_19){throw "timeout";}var _1d,doc;doc=io.contentWindow?io.contentWindow.document:io.contentDocument?io.contentDocument:io.document;xhr.responseText=doc.body?doc.body.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(_11.dataType=="json"||_11.dataType=="script"){var ta=doc.getElementsByTagName("textarea")[0];_1d=ta?ta.value:xhr.responseText;if(_11.dataType=="json"){eval("data = "+_1d);}else{$.globalEval(_1d);}}else{if(_11.dataType=="xml"){_1d=xhr.responseXML;if(!_1d&&xhr.responseText!=null){_1d=toXml(xhr.responseText);}}else{_1d=xhr.responseText;}}}catch(e){ok=false;$.handleError(_11,xhr,"error",e);}if(ok){_11.success(_1d,"success");if(g){$.event.trigger("ajaxSuccess",[xhr,_11]);}}if(g){$.event.trigger("ajaxComplete",[xhr,_11]);}if(g&&!--$.active){$.event.trigger("ajaxStop");}if(_11.complete){_11.complete(xhr,ok?"success":"error");}setTimeout(function(){$io.remove();xhr.responseXML=null;},100);}function toXml(s,doc){if(window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.async="false";doc.loadXML(s);}else{doc=(new DOMParser()).parseFromString(s,"text/xml");}return (doc&&doc.documentElement&&doc.documentElement.tagName!="parsererror")?doc:null;}}};$.fn.ajaxSubmit.counter=0;$.fn.ajaxForm=function(_21){return this.ajaxFormUnbind().submit(submitHandler).each(function(){this.formPluginId=$.fn.ajaxForm.counter++;$.fn.ajaxForm.optionHash[this.formPluginId]=_21;$(":submit,input:image",this).click(clickHandler);});};$.fn.ajaxForm.counter=1;$.fn.ajaxForm.optionHash={};function clickHandler(e){var _23=this.form;_23.clk=this;if(this.type=="image"){if(e.offsetX!=undefined){_23.clk_x=e.offsetX;_23.clk_y=e.offsetY;}else{if(typeof $.fn.offset=="function"){var _24=$(this).offset();_23.clk_x=e.pageX-_24.left;_23.clk_y=e.pageY-_24.top;}else{_23.clk_x=e.pageX-this.offsetLeft;_23.clk_y=e.pageY-this.offsetTop;}}}setTimeout(function(){_23.clk=_23.clk_x=_23.clk_y=null;},10);}function submitHandler(){var id=this.formPluginId;var _26=$.fn.ajaxForm.optionHash[id];$(this).ajaxSubmit(_26);return false;}$.fn.ajaxFormUnbind=function(){this.unbind("submit",submitHandler);return this.each(function(){$(":submit,input:image",this).unbind("click",clickHandler);});};$.fn.formToArray=function(_27){var a=[];if(this.length==0){return a;}var _29=this[0];var els=_27?_29.getElementsByTagName("*"):_29.elements;if(!els){return a;}for(var i=0,max=els.length;i<max;i++){var el=els[i];var n=el.name;if(!n){continue;}if(_27&&_29.clk&&el.type=="image"){if(!el.disabled&&_29.clk==el){a.push({name:n+".x",value:_29.clk_x},{name:n+".y",value:_29.clk_y});}continue;}var v=$.fieldValue(el,true);if(v&&v.constructor==Array){for(var j=0,jmax=v.length;j<jmax;j++){a.push({name:n,value:v[j]});}}else{if(v!==null&&typeof v!="undefined"){a.push({name:n,value:v});}}}if(!_27&&_29.clk){var _30=_29.getElementsByTagName("input");for(var i=0,max=_30.length;i<max;i++){var _32=_30[i];var n=_32.name;if(n&&!_32.disabled&&_32.type=="image"&&_29.clk==_32){a.push({name:n+".x",value:_29.clk_x},{name:n+".y",value:_29.clk_y});}}}return a;};$.fn.formSerialize=function(_34){return $.param(this.formToArray(_34));};$.fn.fieldSerialize=function(_35){var a=[];this.each(function(){var n=this.name;if(!n){return;}var v=$.fieldValue(this,_35);if(v&&v.constructor==Array){for(var i=0,max=v.length;i<max;i++){a.push({name:n,value:v[i]});}}else{if(v!==null&&typeof v!="undefined"){a.push({name:this.name,value:v});}}});return $.param(a);};$.fn.fieldValue=function(_3a){for(var val=[],i=0,max=this.length;i<max;i++){var el=this[i];var v=$.fieldValue(el,_3a);if(v===null||typeof v=="undefined"||(v.constructor==Array&&!v.length)){continue;}v.constructor==Array?$.merge(val,v):val.push(v);}return val;};$.fieldValue=function(el,_3f){var n=el.name,t=el.type,tag=el.tagName.toLowerCase();if(typeof _3f=="undefined"){_3f=true;}if(_3f&&(!n||el.disabled||t=="reset"||t=="button"||(t=="checkbox"||t=="radio")&&!el.checked||(t=="submit"||t=="image")&&el.form&&el.form.clk!=el||tag=="select"&&el.selectedIndex==-1)){return null;}if(tag=="select"){var _41=el.selectedIndex;if(_41<0){return null;}var a=[],ops=el.options;var one=(t=="select-one");var max=(one?_41+1:ops.length);for(var i=(one?_41:0);i<max;i++){var op=ops[i];if(op.selected){var v=$.browser.msie&&!(op.attributes["value"].specified)?op.text:op.value;if(one){return v;}a.push(v);}}return a;}return el.value;};$.fn.clearForm=function(){return this.each(function(){$("input,select,textarea",this).clearFields();});};$.fn.clearFields=$.fn.clearInputs=function(){return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(t=="text"||t=="password"||tag=="textarea"){this.value="";}else{if(t=="checkbox"||t=="radio"){this.checked=false;}else{if(tag=="select"){this.selectedIndex=-1;}}}});};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset();}});};})(jQuery);

web/javascript/form.js

-/*
- * jQuery Form Plugin
- * @requires jQuery v1.1 or later
- *
- * Examples at: http://malsup.com/jquery/form/
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- *
- * Revision: $Id$
- */
- (function($) {
-/**
- * ajaxSubmit() provides a mechanism for submitting an HTML form using AJAX.
- *
- * ajaxSubmit accepts a single argument which can be either a success callback function
- * or an options Object.  If a function is provided it will be invoked upon successful
- * completion of the submit and will be passed the response from the server.
- * If an options Object is provided, the following attributes are supported:
- *
- *  target:   Identifies the element(s) in the page to be updated with the server response.
- *            This value may be specified as a jQuery selection string, a jQuery object,
- *            or a DOM element.
- *            default value: null
- *
- *  url:      URL to which the form data will be submitted.
- *            default value: value of form's 'action' attribute
- *
- *  type:     The method in which the form data should be submitted, 'GET' or 'POST'.
- *            default value: value of form's 'method' attribute (or 'GET' if none found)
- *
- *  data:     Additional data to add to the request, specified as key/value pairs (see $.ajax).
- *
- *  beforeSubmit:  Callback method to be invoked before the form is submitted.
- *            default value: null
- *
- *  success:  Callback method to be invoked after the form has been successfully submitted
- *            and the response has been returned from the server
- *            default value: null
- *
- *  dataType: Expected dataType of the response.  One of: null, 'xml', 'script', or 'json'
- *            default value: null
- *
- *  semantic: Boolean flag indicating whether data must be submitted in semantic order (slower).
- *            default value: false
- *
- *  resetForm: Boolean flag indicating whether the form should be reset if the submit is successful
- *
- *  clearForm: Boolean flag indicating whether the form should be cleared if the submit is successful
- *
- *
- * The 'beforeSubmit' callback can be provided as a hook for running pre-submit logic or for
- * validating the form data.  If the 'beforeSubmit' callback returns false then the form will
- * not be submitted. The 'beforeSubmit' callback is invoked with three arguments: the form data
- * in array format, the jQuery object, and the options object passed into ajaxSubmit.
- * The form data array takes the following form:
- *
- *     [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
- *
- * If a 'success' callback method is provided it is invoked after the response has been returned
- * from the server.  It is passed the responseText or responseXML value (depending on dataType).
- * See jQuery.ajax for further details.
- *
- *
- * The dataType option provides a means for specifying how the server response should be handled.
- * This maps directly to the jQuery.httpData method.  The following values are supported:
- *
- *      'xml':    if dataType == 'xml' the server response is treated as XML and the 'success'
- *                   callback method, if specified, will be passed the responseXML value
- *      'json':   if dataType == 'json' the server response will be evaluted and passed to
- *                   the 'success' callback, if specified
- *      'script': if dataType == 'script' the server response is evaluated in the global context
- *
- *
- * Note that it does not make sense to use both the 'target' and 'dataType' options.  If both
- * are provided the target will be ignored.
- *
- * The semantic argument can be used to force form serialization in semantic order.
- * This is normally true anyway, unless the form contains input elements of type='image'.
- * If your form must be submitted with name/value pairs in semantic order and your form
- * contains an input of type='image" then pass true for this arg, otherwise pass false
- * (or nothing) to avoid the overhead for this logic.
- *
- *
- * When used on its own, ajaxSubmit() is typically bound to a form's submit event like this:
- *
- * $("#form-id").submit(function() {
- *     $(this).ajaxSubmit(options);
- *     return false; // cancel conventional submit
- * });
- *
- * When using ajaxForm(), however, this is done for you.
- *
- * @example
- * $('#myForm').ajaxSubmit(function(data) {
- *     alert('Form submit succeeded! Server returned: ' + data);
- * });
- * @desc Submit form and alert server response
- *
- *
- * @example
- * var options = {
- *     target: '#myTargetDiv'
- * };
- * $('#myForm').ajaxSubmit(options);
- * @desc Submit form and update page element with server response
- *
- *
- * @example
- * var options = {
- *     success: function(responseText) {
- *         alert(responseText);
- *     }
- * };
- * $('#myForm').ajaxSubmit(options);
- * @desc Submit form and alert the server response
- *
- *
- * @example
- * var options = {
- *     beforeSubmit: function(formArray, jqForm) {
- *         if (formArray.length == 0) {
- *             alert('Please enter data.');
- *             return false;
- *         }
- *     }
- * };
- * $('#myForm').ajaxSubmit(options);
- * @desc Pre-submit validation which aborts the submit operation if form data is empty
- *
- *
- * @example
- * var options = {
- *     url: myJsonUrl.php,
- *     dataType: 'json',
- *     success: function(data) {
- *        // 'data' is an object representing the the evaluated json data
- *     }
- * };
- * $('#myForm').ajaxSubmit(options);
- * @desc json data returned and evaluated
- *
- *
- * @example
- * var options = {
- *     url: myXmlUrl.php,
- *     dataType: 'xml',
- *     success: function(responseXML) {
- *        // responseXML is XML document object
- *        var data = $('myElement', responseXML).text();
- *     }
- * };
- * $('#myForm').ajaxSubmit(options);
- * @desc XML data returned from server
- *
- *
- * @example
- * var options = {
- *     resetForm: true
- * };
- * $('#myForm').ajaxSubmit(options);
- * @desc submit form and reset it if successful
- *
- * @example
- * $('#myForm).submit(function() {
- *    $(this).ajaxSubmit();
- *    return false;
- * });
- * @desc Bind form's submit event to use ajaxSubmit
- *
- *
- * @name ajaxSubmit
- * @type jQuery
- * @param options  object literal containing options which control the form submission process
- * @cat Plugins/Form
- * @return jQuery
- */
-$.fn.ajaxSubmit = function(options) {
-    if (typeof options == 'function')
-        options = { success: options };
-
-    options = $.extend({
-        url:  this.attr('action') || window.location,
-        type: this.attr('method') || 'GET'
-    }, options || {});
-
-    // hook for manipulating the form data before it is extracted;
-    // convenient for use with rich editors like tinyMCE or FCKEditor
-    var veto = {};
-    $.event.trigger('form.pre.serialize', [this, options, veto]);
-    if (veto.veto) return this;
-
-    var a = this.formToArray(options.semantic);
-	if (options.data) {
-	    for (var n in options.data)
-	        a.push( { name: n, value: options.data[n] } );
-	}
-
-    // give pre-submit callback an opportunity to abort the submit
-    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) return this;
-
-    // fire vetoable 'validate' event
-    $.event.trigger('form.submit.validate', [a, this, options, veto]);
-    if (veto.veto) return this;
-
-    var q = $.param(a);//.replace(/%20/g,'+');
-
-    if (options.type.toUpperCase() == 'GET') {
-        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
-        options.data = null;  // data is null for 'get'
-    }
-    else
-        options.data = q; // data is the query string for 'post'
-
-    var $form = this, callbacks = [];
-    if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
-    if (options.clearForm) callbacks.push(function() { $form.clearForm(); });
-
-    // perform a load on the target only if dataType is not provided
-    if (!options.dataType && options.target) {
-        var oldSuccess = options.success || function(){};
-        callbacks.push(function(data) {
-            if (this.evalScripts)
-                $(options.target).attr("innerHTML", data).evalScripts().each(oldSuccess, arguments);
-            else // jQuery v1.1.4
-                $(options.target).html(data).each(oldSuccess, arguments);
-        });
-    }
-    else if (options.success)
-        callbacks.push(options.success);
-
-    options.success = function(data, status) {
-        for (var i=0, max=callbacks.length; i < max; i++)
-            callbacks[i](data, status, $form);
-    };
-
-    // are there files to upload?
-    var files = $('input:file', this).fieldValue();
-    var found = false;
-    for (var j=0; j < files.length; j++)
-        if (files[j])
-            found = true;
-
-    if (options.iframe || found) // options.iframe allows user to force iframe mode
-        fileUpload();
-    else
-        $.ajax(options);
-
-    // fire 'notify' event
-    $.event.trigger('form.submit.notify', [this, options]);
-    return this;
-
-
-    // private function for handling file uploads (hat tip to YAHOO!)
-    function fileUpload() {
-        var form = $form[0];
-        var opts = $.extend({}, $.ajaxSettings, options);
-
-        var id = 'jqFormIO' + $.fn.ajaxSubmit.counter++;
-        var $io = $('<iframe id="' + id + '" name="' + id + '" />');
-        var io = $io[0];
-        var op8 = $.browser.opera && window.opera.version() < 9;
-        if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
-        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
-
-        var xhr = { // mock object
-            responseText: null,
-            responseXML: null,
-            status: 0,
-            statusText: 'n/a',
-            getAllResponseHeaders: function() {},
-            getResponseHeader: function() {},
-            setRequestHeader: function() {}
-        };
-
-        var g = opts.global;
-        // trigger ajax global events so that activity/block indicators work like normal
-        if (g && ! $.active++) $.event.trigger("ajaxStart");
-        if (g) $.event.trigger("ajaxSend", [xhr, opts]);
-
-        var cbInvoked = 0;
-        var timedOut = 0;
-
-        // take a breath so that pending repaints get some cpu time before the upload starts
-        setTimeout(function() {
-            $io.appendTo('body');
-            // jQuery's event binding doesn't work for iframe events in IE
-            io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
-
-            // make sure form attrs are set
-            var encAttr = form.encoding ? 'encoding' : 'enctype';
-            var t = $form.attr('target');
-            $form.attr({
-                target:   id,
-                method:  'POST',
-                action:   opts.url
-            });
-            form[encAttr] = 'multipart/form-data';
-
-            // support timout
-            if (opts.timeout)
-                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);
-
-            form.submit();
-            $form.attr('target', t); // reset target
-        }, 10);
-
-        function cb() {
-            if (cbInvoked++) return;
-
-            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);
-
-            var ok = true;
-            try {
-                if (timedOut) throw 'timeout';
-                // extract the server response from the iframe
-                var data, doc;
-                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
-                xhr.responseText = doc.body ? doc.body.innerHTML : null;
-                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
-
-                if (opts.dataType == 'json' || opts.dataType == 'script') {
-                    var ta = doc.getElementsByTagName('textarea')[0];
-                    data = ta ? ta.value : xhr.responseText;
-                    if (opts.dataType == 'json')
-                        eval("data = " + data);
-                    else
-                        $.globalEval(data);
-                }
-                else if (opts.dataType == 'xml') {
-                    data = xhr.responseXML;
-                    if (!data && xhr.responseText != null)
-                        data = toXml(xhr.responseText);
-                }
-                else {
-                    data = xhr.responseText;
-                }
-            }
-            catch(e){
-                ok = false;
-                $.handleError(opts, xhr, 'error', e);
-            }
-
-            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
-            if (ok) {
-                opts.success(data, 'success');
-                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
-            }
-            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
-            if (g && ! --$.active) $.event.trigger("ajaxStop");
-            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');
-
-            // clean up
-            setTimeout(function() {
-                $io.remove();
-                xhr.responseXML = null;
-            }, 100);
-        };
-
-        function toXml(s, doc) {
-            if (window.ActiveXObject) {
-                doc = new ActiveXObject('Microsoft.XMLDOM');
-                doc.async = 'false';
-                doc.loadXML(s);
-            }
-            else
-                doc = (new DOMParser()).parseFromString(s, 'text/xml');
-            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
-        };
-    };
-};
-$.fn.ajaxSubmit.counter = 0; // used to create unique iframe ids
-
-/**
- * ajaxForm() provides a mechanism for fully automating form submission.
- *
- * The advantages of using this method instead of ajaxSubmit() are:
- *
- * 1: This method will include coordinates for <input type="image" /> elements (if the element
- *    is used to submit the form).
- * 2. This method will include the submit element's name/value data (for the element that was
- *    used to submit the form).
- * 3. This method binds the submit() method to the form for you.
- *
- * Note that for accurate x/y coordinates of image submit elements in all browsers
- * you need to also use the "dimensions" plugin (this method will auto-detect its presence).
- *
- * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
- * passes the options argument along after properly binding events for submit elements and
- * the form itself.  See ajaxSubmit for a full description of the options argument.
- *
- *
- * @example
- * var options = {
- *     target: '#myTargetDiv'
- * };
- * $('#myForm').ajaxSForm(options);
- * @desc Bind form's submit event so that 'myTargetDiv' is updated with the server response
- *       when the form is submitted.
- *
- *
- * @example
- * var options = {
- *     success: function(responseText) {
- *         alert(responseText);
- *     }
- * };
- * $('#myForm').ajaxSubmit(options);
- * @desc Bind form's submit event so that server response is alerted after the form is submitted.
- *
- *
- * @example
- * var options = {
- *     beforeSubmit: function(formArray, jqForm) {
- *         if (formArray.length == 0) {
- *             alert('Please enter data.');
- *             return false;
- *         }
- *     }
- * };
- * $('#myForm').ajaxSubmit(options);
- * @desc Bind form's submit event so that pre-submit callback is invoked before the form
- *       is submitted.
- *
- *
- * @name   ajaxForm
- * @param  options  object literal containing options which control the form submission process
- * @return jQuery
- * @cat    Plugins/Form
- * @type   jQuery
- */
-$.fn.ajaxForm = function(options) {
-    return this.ajaxFormUnbind().submit(submitHandler).each(function() {
-        // store options in hash
-        this.formPluginId = $.fn.ajaxForm.counter++;
-        $.fn.ajaxForm.optionHash[this.formPluginId] = options;
-        $(":submit,input:image", this).click(clickHandler);
-    });
-};
-
-$.fn.ajaxForm.counter = 1;
-$.fn.ajaxForm.optionHash = {};
-
-function clickHandler(e) {
-    var $form = this.form;
-    $form.clk = this;
-    if (this.type == 'image') {
-        if (e.offsetX != undefined) {
-            $form.clk_x = e.offsetX;
-            $form.clk_y = e.offsetY;
-        } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
-            var offset = $(this).offset();
-            $form.clk_x = e.pageX - offset.left;
-            $form.clk_y = e.pageY - offset.top;
-        } else {
-            $form.clk_x = e.pageX - this.offsetLeft;
-            $form.clk_y = e.pageY - this.offsetTop;
-        }
-    }
-    // clear form vars
-    setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
-};
-
-function submitHandler() {
-    // retrieve options from hash
-    var id = this.formPluginId;
-    var options = $.fn.ajaxForm.optionHash[id];
-    $(this).ajaxSubmit(options);
-    return false;
-};
-
-/**
- * ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
- *
- * @name   ajaxFormUnbind
- * @return jQuery
- * @cat    Plugins/Form
- * @type   jQuery
- */
-$.fn.ajaxFormUnbind = function() {
-    this.unbind('submit', submitHandler);
-    return this.each(function() {
-        $(":submit,input:image", this).unbind('click', clickHandler);
-    });
-
-};
-
-/**
- * formToArray() gathers form element data into an array of objects that can
- * be passed to any of the following ajax functions: $.get, $.post, or load.
- * Each object in the array has both a 'name' and 'value' property.  An example of
- * an array for a simple login form might be:
- *
- * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
- *
- * It is this array that is passed to pre-submit callback functions provided to the
- * ajaxSubmit() and ajaxForm() methods.
- *
- * The semantic argument can be used to force form serialization in semantic order.
- * This is normally true anyway, unless the form contains input elements of type='image'.
- * If your form must be submitted with name/value pairs in semantic order and your form
- * contains an input of type='image" then pass true for this arg, otherwise pass false
- * (or nothing) to avoid the overhead for this logic.
- *
- * @example var data = $("#myForm").formToArray();
- * $.post( "myscript.cgi", data );
- * @desc Collect all the data from a form and submit it to the server.
- *
- * @name formToArray
- * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
- * @type Array<Object>
- * @cat Plugins/Form
- */
-$.fn.formToArray = function(semantic) {
-    var a = [];
-    if (this.length == 0) return a;
-
-    var form = this[0];
-    var els = semantic ? form.getElementsByTagName('*') : form.elements;
-    if (!els) return a;
-    for(var i=0, max=els.length; i < max; i++) {
-        var el = els[i];
-        var n = el.name;
-        if (!n) continue;
-
-        if (semantic && form.clk && el.type == "image") {
-            // handle image inputs on the fly when semantic == true
-            if(!el.disabled && form.clk == el)
-                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
-            continue;
-        }
-
-        var v = $.fieldValue(el, true);
-        if (v && v.constructor == Array) {
-            for(var j=0, jmax=v.length; j < jmax; j++)
-                a.push({name: n, value: v[j]});
-        }
-        else if (v !== null && typeof v != 'undefined')
-            a.push({name: n, value: v});
-    }
-
-    if (!semantic && form.clk) {
-        // input type=='image' are not found in elements array! handle them here
-        var inputs = form.getElementsByTagName("input");
-        for(var i=0, max=inputs.length; i < max; i++) {
-            var input = inputs[i];
-            var n = input.name;
-            if(n && !input.disabled && input.type == "image" && form.clk == input)
-                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
-        }
-    }
-    return a;
-};
-
-
-/**
- * Serializes form data into a 'submittable' string. This method will return a string
- * in the format: name1=value1&amp;name2=value2
- *
- * The semantic argument can be used to force form serialization in semantic order.
- * If your form must be submitted with name/value pairs in semantic order then pass
- * true for this arg, otherwise pass false (or nothing) to avoid the overhead for
- * this logic (which can be significant for very large forms).
- *
- * @example var data = $("#myForm").formSerialize();
- * $.ajax('POST', "myscript.cgi", data);
- * @desc Collect all the data from a form into a single string
- *
- * @name formSerialize
- * @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
- * @type String
- * @cat Plugins/Form
- */
-$.fn.formSerialize = function(semantic) {
-    //hand off to jQuery.param for proper encoding
-    return $.param(this.formToArray(semantic));
-};
-
-
-/**
- * Serializes all field elements in the jQuery object into a query string.
- * This method will return a string in the format: name1=value1&amp;name2=value2
- *
- * The successful argument controls whether or not serialization is limited to
- * 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
- * The default value of the successful argument is true.
- *
- * @example var data = $("input").formSerialize();
- * @desc Collect the data from all successful input elements into a query string
- *
- * @example var data = $(":radio").formSerialize();
- * @desc Collect the data from all successful radio input elements into a query string
- *
- * @example var data = $("#myForm :checkbox").formSerialize();
- * @desc Collect the data from all successful checkbox input elements in myForm into a query string
- *
- * @example var data = $("#myForm :checkbox").formSerialize(false);
- * @desc Collect the data from all checkbox elements in myForm (even the unchecked ones) into a query string
- *
- * @example var data = $(":input").formSerialize();
- * @desc Collect the data from all successful input, select, textarea and button elements into a query string
- *
- * @name fieldSerialize
- * @param successful true if only successful controls should be serialized (default is true)
- * @type String
- * @cat Plugins/Form
- */
-$.fn.fieldSerialize = function(successful) {
-    var a = [];
-    this.each(function() {
-        var n = this.name;
-        if (!n) return;
-        var v = $.fieldValue(this, successful);
-        if (v && v.constructor == Array) {
-            for (var i=0,max=v.length; i < max; i++)
-                a.push({name: n, value: v[i]});
-        }
-        else if (v !== null && typeof v != 'undefined')
-            a.push({name: this.name, value: v});
-    });
-    //hand off to jQuery.param for proper encoding
-    return $.param(a);
-};
-
-
-/**
- * Returns the value(s) of the element in the matched set.  For example, consider the following form:
- *
- *  <form><fieldset>
- *      <input name="A" type="text" />
- *      <input name="A" type="text" />
- *      <input name="B" type="checkbox" value="B1" />
- *      <input name="B" type="checkbox" value="B2"/>
- *      <input name="C" type="radio" value="C1" />
- *      <input name="C" type="radio" value="C2" />
- *  </fieldset></form>
- *
- *  var v = $(':text').fieldValue();
- *  // if no values are entered into the text inputs
- *  v == ['','']
- *  // if values entered into the text inputs are 'foo' and 'bar'
- *  v == ['foo','bar']
- *
- *  var v = $(':checkbox').fieldValue();
- *  // if neither checkbox is checked
- *  v === undefined
- *  // if both checkboxes are checked
- *  v == ['B1', 'B2']
- *
- *  var v = $(':radio').fieldValue();
- *  // if neither radio is checked
- *  v === undefined
- *  // if first radio is checked
- *  v == ['C1']
- *
- * The successful argument controls whether or not the field element must be 'successful'
- * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
- * The default value of the successful argument is true.  If this value is false the value(s)
- * for each element is returned.
- *
- * Note: This method *always* returns an array.  If no valid value can be determined the
- *       array will be empty, otherwise it will contain one or more values.
- *
- * @example var data = $("#myPasswordElement").fieldValue();
- * alert(data[0]);
- * @desc Alerts the current value of the myPasswordElement element
- *
- * @example var data = $("#myForm :input").fieldValue();
- * @desc Get the value(s) of the form elements in myForm
- *
- * @example var data = $("#myForm :checkbox").fieldValue();
- * @desc Get the value(s) for the successful checkbox element(s) in the jQuery object.
- *
- * @example var data = $("#mySingleSelect").fieldValue();
- * @desc Get the value(s) of the select control
- *
- * @example var data = $(':text').fieldValue();
- * @desc Get the value(s) of the text input or textarea elements
- *
- * @example var data = $("#myMultiSelect").fieldValue();
- * @desc Get the values for the select-multiple control
- *
- * @name fieldValue
- * @param Boolean successful true if only the values for successful controls should be returned (default is true)
- * @type Array<String>
- * @cat Plugins/Form
- */
-$.fn.fieldValue = function(successful) {
-    for (var val=[], i=0, max=this.length; i < max; i++) {
-        var el = this[i];
-        var v = $.fieldValue(el, successful);
-        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
-            continue;
-        v.constructor == Array ? $.merge(val, v) : val.push(v);
-    }
-    return val;
-};
-
-/**
- * Returns the value of the field element.
- *
- * The successful argument controls whether or not the field element must be 'successful'
- * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
- * The default value of the successful argument is true.  If the given element is not
- * successful and the successful arg is not false then the returned value will be null.
- *
- * Note: If the successful flag is true (default) but the element is not successful, the return will be null
- * Note: The value returned for a successful select-multiple element will always be an array.
- * Note: If the element has no value the return value will be undefined.
- *
- * @example var data = jQuery.fieldValue($("#myPasswordElement")[0]);
- * @desc Gets the current value of the myPasswordElement element
- *
- * @name fieldValue
- * @param Element el The DOM element for which the value will be returned
- * @param Boolean successful true if value returned must be for a successful controls (default is true)
- * @type String or Array<String> or null or undefined
- * @cat Plugins/Form
- */
-$.fieldValue = function(el, successful) {
-    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
-    if (typeof successful == 'undefined') successful = true;
-
-    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
-        (t == 'checkbox' || t == 'radio') && !el.checked ||
-        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
-        tag == 'select' && el.selectedIndex == -1))
-            return null;
-
-    if (tag == 'select') {
-        var index = el.selectedIndex;
-        if (index < 0) return null;
-        var a = [], ops = el.options;
-        var one = (t == 'select-one');
-        var max = (one ? index+1 : ops.length);
-        for(var i=(one ? index : 0); i < max; i++) {
-            var op = ops[i];
-            if (op.selected) {
-                // extra pain for IE...
-                var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
-                if (one) return v;
-                a.push(v);
-            }
-        }
-        return a;
-    }
-    return el.value;
-};
-
-
-/**
- * Clears the form data.  Takes the following actions on the form's input fields:
- *  - input text fields will have their 'value' property set to the empty string
- *  - select elements will have their 'selectedIndex' property set to -1
- *  - checkbox and radio inputs will have their 'checked' property set to false
- *  - inputs of type submit, button, reset, and hidden will *not* be effected
- *  - button elements will *not* be effected
- *
- * @example $('form').clearForm();
- * @desc Clears all forms on the page.
- *
- * @name clearForm
- * @type jQuery
- * @cat Plugins/Form
- */
-$.fn.clearForm = function() {
-    return this.each(function() {
-        $('input,select,textarea', this).clearFields();
-    });
-};
-
-/**
- * Clears the selected form elements.  Takes the following actions on the matched elements:
- *  - input text fields will have their 'value' property set to the empty string
- *  - select elements will have their 'selectedIndex' property set to -1
- *  - checkbox and radio inputs will have their 'checked' property set to false
- *  - inputs of type submit, button, reset, and hidden will *not* be effected
- *  - button elements will *not* be effected
- *
- * @example $('.myInputs').clearFields();
- * @desc Clears all inputs with class myInputs
- *
- * @name clearFields
- * @type jQuery
- * @cat Plugins/Form
- */
-$.fn.clearFields = $.fn.clearInputs = function() {
-    return this.each(function() {
-        var t = this.type, tag = this.tagName.toLowerCase();
-        if (t == 'text' || t == 'password' || tag == 'textarea')
-            this.value = '';
-        else if (t == 'checkbox' || t == 'radio')
-            this.checked = false;
-        else if (tag == 'select')
-            this.selectedIndex = -1;
-    });
-};
-
-
-/**
- * Resets the form data.  Causes all form elements to be reset to their original value.
- *
- * @example $('form').resetForm();
- * @desc Resets all forms on the page.
- *
- * @name resetForm
- * @type jQuery
- * @cat Plugins/Form
- */
-$.fn.resetForm = function() {
-    return this.each(function() {
-        // guard against an input with the name of 'reset'
-        // note that IE reports the reset function as an 'object'
-        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
-            this.reset();
-    });
-};
-
-})(jQuery);

web/javascript/hsbook.js

   $("p[@id]").each(function() {
     $(this).append(loading($(this).attr("id")));
   });
+  $("table[@id].equation").each(function() {
+    $(this).after(loading($(this).attr("id")));
+  });
   $("pre[@id]").each(function() {
     $(this).after(loading($(this).attr("id")));
   });
-  var chapid = $("div.preface, div.chapter, div.appendix, div.bibliography").attr("id");
+  var chapid = $("body, div.preface, div.chapter, div.appendix, div.bibliography").attr("id");
   $("#chapterfeed").attr("href",
 			 $("#chapterfeed").attr("href") + chapid + "/");
   $.getJSON(location.protocol + "//" + location.host + "/comments/chapter/" +

web/javascript/jquery-min.js

-/*
- * jQuery 1.2.1 - New Wave Javascript
- *
- * Copyright (c) 2007 John Resig (jquery.com)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
- * $Rev: 3353 $
- */
-(function(){if(typeof jQuery!="undefined")var _jQuery=jQuery;var jQuery=window.jQuery=function(selector,context){return this instanceof jQuery?this.init(selector,context):new jQuery(selector,context);};if(typeof $!="undefined")var _$=$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(typeof selector=="string"){var m=quickExpr.exec(selector);if(m&&(m[1]||!context)){if(m[1])selector=jQuery.clean([m[1]],context);else{var tmp=document.getElementById(m[3]);if(tmp)if(tmp.id!=m[3])return jQuery().find(selector);else{this[0]=tmp;this.length=1;return this;}else
-selector=[];}}else
-return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.1",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(a){var ret=jQuery(a);ret.prevObject=this;return ret;},setArray:function(a){this.length=0;Array.prototype.push.apply(this,a);return this;},each:function(fn,args){return jQuery.each(this,fn,args);},index:function(obj){var pos=-1;this.each(function(i){if(this==obj)pos=i;});return pos;},attr:function(key,value,type){var obj=key;if(key.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],key)||undefined;else{obj={};obj[key]=value;}return this.each(function(index){for(var prop in obj)jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop));});},css:function(key,value){return this.attr(key,value,"curCSS");},text:function(e){if(typeof e!="object"&&e!=null)return this.empty().append(document.createTextNode(e));var t="";jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return t;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,1,function(a){this.appendChild(a);});},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild);});},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this);});},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(t){var data=jQuery.map(this,function(a){return jQuery.find(t,a);});return this.pushStack(/[^+>] [^+>]/.test(t)||t.indexOf("..")>-1?jQuery.unique(data):data);},clone:function(events){var ret=this.map(function(){return this.outerHTML?jQuery(this.outerHTML)[0]:this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index]);})||jQuery.multiFilter(t,this));},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t;}));},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||jQuery.nodeName(t,"form"))?t:[t]));},is:function(expr){return expr?jQuery.multiFilter(expr,this).length>0:false;},hasClass:function(expr){return this.is("."+expr);},val:function(val){if(val==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,a=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){var val=jQuery.browser.msie&&!option.attributes["value"].specified?option.text:option.value;if(one)return val;a.push(val);}}return a;}else
-return this[0].value.replace(/\r/g,"");}}else
-return this.each(function(){if(val.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,val)>=0||jQuery.inArray(this.name,val)>=0);else if(jQuery.nodeName(this,"select")){var tmp=val.constructor==Array?val:[val];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,tmp)>=0||jQuery.inArray(this.text,tmp)>=0);});if(!tmp.length)this.selectedIndex=-1;}else
-this.value=val;});},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val);},replaceWith:function(val){return this.after(val).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(fn){return this.pushStack(jQuery.map(this,function(elem,i){return fn.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,dir,fn){var clone=this.length>1,a;return this.each(function(){if(!a){a=jQuery.clean(args,this.ownerDocument);if(dir<0)a.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));jQuery.each(a,function(){var elem=clone?this.cloneNode(true):this;if(!evalScript(0,elem))fn.call(obj,elem);});});}};function evalScript(i,elem){var script=jQuery.nodeName(elem,"script");if(script){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
-jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}else if(elem.nodeType==1)jQuery("script",elem).each(evalScript);return script;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},a=1,al=arguments.length,deep=false;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};}if(al==1){target=this;a=0;}var prop;for(;a<al;a++)if((prop=arguments[a])!=null)for(var i in prop){if(target==prop[i])continue;if(deep&&typeof prop[i]=='object'&&target[i])jQuery.extend(target[i],prop[i]);else if(prop[i]!=undefined)target[i]=prop[i];}return target;};var expando="jQuery"+(new Date()).getTime(),uuid=0,win={};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/function/i.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){if(window.execScript)window.execScript(data);else if(jQuery.browser.safari)window.setTimeout(data,0);else
-eval.call(window,data);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?win:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!=undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?win:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(obj,fn,args){if(args){if(obj.length==undefined)for(var i in obj)fn.apply(obj[i],args);else
-for(var i=0,ol=obj.length;i<ol;i++)if(fn.apply(obj[i],args)===false)break;}else{if(obj.length==undefined)for(var i in obj)fn.call(obj[i],i,obj[i]);else
-for(var i=0,ol=obj.length,val=obj[0];i<ol&&fn.call(val,i,val)!==false;val=obj[++i]){}}return obj;},prop:function(elem,value,type,index,prop){if(jQuery.isFunction(value))value=value.call(elem,[index]);var exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i;return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(prop)?value+"px":value;},className:{add:function(elem,c){jQuery.each((c||"").split(/\s+/),function(i,cur){if(!jQuery.className.has(elem.className,cur))elem.className+=(elem.className?" ":"")+cur;});},remove:function(elem,c){elem.className=c!=undefined?jQuery.grep(elem.className.split(/\s+/),function(cur){return!jQuery.className.has(c,cur);}).join(" "):"";},has:function(t,c){return jQuery.inArray(c,(t.className||t).toString().split(/\s+/))>-1;}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];e.style[i]=o[i];}f.apply(e,[]);for(var i in o)e.style[i]=e.style["old"+i];},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];jQuery.each(d,function(){old["padding"+this]=0;old["border"+this+"Width"]=0;});jQuery.swap(e,old,function(){if(jQuery(e).is(':visible')){oHeight=e.offsetHeight;oWidth=e.offsetWidth;}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];var parPos=jQuery.css(e.parentNode,"position")||"static";if(parPos=="static")e.parentNode.style.position="relative";oHeight=e.clientHeight;oWidth=e.clientWidth;if(parPos=="static")e.parentNode.style.position="static";e.parentNode.removeChild(e);}});return p=="height"?oHeight:oWidth;}return jQuery.curCSS(e,p);},curCSS:function(elem,prop,force){var ret,stack=[],swap=[];function color(a){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(a,null);return!ret||ret.getPropertyValue("color")=="";}if(prop=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(prop.match(/float/i))prop=styleFloat;if(!force&&elem.style[prop])ret=elem.style[prop];else if(document.defaultView&&document.defaultView.getComputedStyle){if(prop.match(/float/i))prop="float";prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();var cur=document.defaultView.getComputedStyle(elem,null);if(cur&&!color(elem))ret=cur.getPropertyValue(prop);else{for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(a=0;a<stack.length;a++)if(color(stack[a])){swap[a]=stack[a].style.display;stack[a].style.display="block";}ret=prop=="display"&&swap[stack.length-1]!=null?"none":document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop)||"";for(a=0;a<swap.length;a++)if(swap[a]!=null)stack[a].style.display=swap[a];}if(prop=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var newProp=prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});ret=elem.currentStyle[prop]||elem.currentStyle[newProp];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var style=elem.style.left;var runtimeStyle=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;elem.style.left=ret||0;ret=elem.style.pixelLeft+"px";elem.style.left=style;elem.runtimeStyle.left=runtimeStyle;}}return ret;},clean:function(a,doc){var r=[];doc=doc||document;jQuery.each(a,function(i,arg){if(!arg)return;if(arg.constructor==Number)arg=arg.toString();if(typeof arg=="string"){arg=arg.replace(/(<(\w+)[^>]*?)\/>/g,function(m,all,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)?m:all+"></"+tag+">";});var s=jQuery.trim(arg).toLowerCase(),div=doc.createElement("div"),tb=[];var wrap=!s.indexOf("<opt")&&[1,"<select>","</select>"]||!s.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||s.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!s.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!s.indexOf("<td")||!s.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!s.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+arg+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){if(!s.indexOf("<table")&&s.indexOf("<tbody")<0)tb=div.firstChild&&div.firstChild.childNodes;else if(wrap[1]=="<table>"&&s.indexOf("<tbody")<0)tb=div.childNodes;for(var n=tb.length-1;n>=0;--n)if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length)tb[n].parentNode.removeChild(tb[n]);if(/^\s/.test(arg))div.insertBefore(doc.createTextNode(arg.match(/^\s*/)[0]),div.firstChild);}arg=jQuery.makeArray(div.childNodes);}if(0===arg.length&&(!jQuery.nodeName(arg,"form")&&!jQuery.nodeName(arg,"select")))return;if(arg[0]==undefined||jQuery.nodeName(arg,"form")||arg.options)r.push(arg);else
-r=jQuery.merge(r,arg);});return r;},attr:function(elem,name,value){var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||""