diff --git a/README.md b/README.md index 2411182..ddc3e9e 100644 --- a/README.md +++ b/README.md @@ -9,4 +9,9 @@ python 2.7 tutorial中文版 **source** 文件夹下为 rst 格式的文档; -**html** 文件夹下为使用 Sphinx 生成的 html 格式的文档; \ No newline at end of file +**html** 文件夹下为使用 Sphinx 生成的 html 格式的文档; + +**docs** 文件夹为原始版中文翻译; + + +备注:因为平时工作比较忙,如果版本有更新的话,请直接提交 issues,谢谢! \ No newline at end of file diff --git a/Makefile b/docs/Makefile similarity index 98% rename from Makefile rename to docs/Makefile index 865835b..5e047a4 100644 --- a/Makefile +++ b/docs/Makefile @@ -54,6 +54,7 @@ html: @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @@ -175,3 +176,8 @@ pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +pdf: + $(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) $(BUILDDIR)/pdf + @echo + @echo "Build finished. The PDF files are in $(BUILDDIR)/PDF." diff --git a/html/.buildinfo b/docs/html/.buildinfo similarity index 82% rename from html/.buildinfo rename to docs/html/.buildinfo index 8888be0..aa3878f 100644 --- a/html/.buildinfo +++ b/docs/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 20452a38335dc2e85d5ce28954b3a0fb +config: 6b6fd4f38a1c30c8b73b481ab4344c83 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/html/_sources/appendix.txt b/docs/html/_sources/appendix.txt new file mode 100644 index 0000000..68f25fc --- /dev/null +++ b/docs/html/_sources/appendix.txt @@ -0,0 +1,82 @@ +.. _tut-appendix: + +******** +附录 +******** + + +.. _tut-interac: + +交互模式 +================ + +.. _tut-error: + +错误处理 +-------------- + +有错误发生时,解释器会打印一个错误信息和栈跟踪器。在交互模式下,它返回主提示符,如果从文件输入执行,它在打印栈跟踪器后以非零状态退出。(异常可以由 `try `_ 语句中的 `except `_ 子句来控制,这样就不会出现上文中的错误信息) 有一些非常致命的错误会导致非零状态下退出,这通常由内部矛盾和内存溢出造成。所有的错误信息都写入标准错误流;命令中执行的普通输出写入标准输出。 + +在主提示符或从属提示符中输入中断符 (通常是 Control-C 或者 DEL) 就会取消当前输入,回到主命令行。[#]_ 执行命令时输入一个中断符会抛出一个 `KeyboardInterrupt `_ 异常,它可以被 `try `_ 语句截获。 + + +.. _tut-scripts: + +执行 Python 脚本 +------------------------- + +BSD 类的 Unix 系统中,Python 脚本可以像 Shell 脚本那样直接执行。只要在脚本文件开头写一行命令,指定文件和模式:: + + #! /usr/bin/env python + +(首先要确认 Python 解释器在用户的 :envvar:`PATH` 中) ``#!`` 必须是文件的前两个字符,在某些平台上,第一行必须以 Unix 风格的行结束符 (``'\n'``)结束,不能用 Windows (``'\r\n'``) 的结束符。注意,``'#'`` 是 Python 中是行注释的起始符。 + +脚本可以通过 :program:`chmod` 命令指定执行模式和权限。 + +.. code-block:: bash + + $ chmod +x myscript.py + +Windows 系统上没有“执行模式”。Python 安装程序自动将 ``.py`` 文件关联到 ``python.exe`` ,所以在 Python 文件图标上双击,它就会作为脚本执行。同样 ``.pyw`` 也做了这样的关联,通常它执行时不会显示控制台窗口。 + + +.. _tut-startup: + +交互执行文件 +---------------------------- + +使用 Python 解释器的时候,我们可能需要在每次解释器启动时执行一些命令。你可以在一个文件中包含你想要执行的命令,设定一个名为 `PYTHONSTARTUP `_ 的环境变量来指定这个文件。这类似于 Unix shell 的 :file:`.profile` 文件。 + +这个文件在交互会话期是只读的,当 Python 从脚本中解读文件或以终端 :file:`/dev/tty` 做为外部命令源时则不会如此 (尽管它们的行为很像是处在交互会话期) 它与解释器执行的命令处在同一个命名空间,所以由它定义或引用的一切可以在解释器中不受限制地使用。你也可以在这个文件中改变 ``sys.ps1`` 和 ``sys.ps2`` 指令。 + +如果你想要在当前目录中执行附加的启动文件,可以在全局启动文件中加入类似以下的代码:``if os.path.isfile('.pythonrc.py'): execfile('.pythonrc.py')``。如果你想要在某个脚本中使用启动文件,必须要在脚本中写入这样的语句:: + + import os + filename = os.environ.get('PYTHONSTARTUP') + if filename and os.path.isfile(filename): + with open(filename) as fobj: + startup_file = fobj.read() + exec(startup_file) + + +.. _tut-customize: + +定制模块 +------------------------- + + +Python 提供了两个钩子 (方法) 来本地化: :mod:`sitecustomize` 和 +:mod:`usercustomize`。为了见识它们,你首先需要找到你的 site-packages 的目录。启动 python 执行下面的代码:: + + >>> import site + >>> site.getusersitepackages() + '/home/user/.local/lib/python2.7/site-packages' + +现在你可以在 site-packages 的目录下创建 :file:`usercustomize.py` 文件,内容就悉听尊便了。这个文件将会影响 python 的每次调用,除非启动的时候加入 `-s `_ 选项禁止自动导入。 + +:mod:`sitecustomize` 的工作方式一样,但是是由电脑的管理账户创建以及在 :mod:`usercustomize` 之前导入。具体可以参见 `site `_ 。 + + +.. rubric:: Footnotes + +.. [#] GNU Readline包的一个问题可能禁止此功能。 diff --git a/html/_sources/appetite.txt b/docs/html/_sources/appetite.txt similarity index 52% rename from html/_sources/appetite.txt rename to docs/html/_sources/appetite.txt index 75fcecb..f4af771 100644 --- a/html/_sources/appetite.txt +++ b/docs/html/_sources/appetite.txt @@ -6,19 +6,26 @@ 如果你要用计算机做很多工作,最后你会发现有一些任务你更希望用自动化的方式进行处理。 比如,你想要在大量的文本文件中执行查找/替换,或者以复杂的方式对大量的图片进行重命名和整理。 也许你想要编写一个小型的自定义数据库、一个特殊的 GUI 应用程序或一个简单的小游戏。 + 如果你是一名专业的软件开发者,可能你必须使用几种 C/C++/JAVA 类库,并且发现通常编写/编译/测试/重新编译的周期是如此漫长。 也许你正在为这些类库编写测试用例,但是发现这是一个让人烦躁的工作。 又或者你已经完成了一个可以使用扩展语言的程序,但你并不想为此重新设计并实现一套全新的语言。 + 那么 Python 正是你所需要的语言。 -虽然你能够通过编写 Unix shell 脚本或 Windows 批处理文件来处理其中的某些任务,但 Shell 脚本更适合移动文件或修改文本数据,并不适合编写 GUI 应用程序或游戏; 虽然你能够使用 C/C++/JAVA 编写程序,但即使编写一个简单的 first-draft 程序也有可能耗费大量的开发时间。 相比之下,Python 更易于使用,无论在 Windows、Mac OS X 或 Unix 操作系统上它都会帮助你更快地完成任务。 -虽然 Python 易于使用,但它却是一门完整的编程语言;与 Shell 脚本或批处理文件相比,它为编写大型程序提供了更多的结构和支持。 另一方面,Python 提供了比 C 更多的错误检查,并且作为一门 *高级语言* ,它内置支持高级的数据结构类型,例如:灵活的数组和字典。 因其具有更多的通用数据类型,同 Awk 甚至 Perl 相比较,Python 适用于更多领域,至少大多数事情在 Python 中与其他语言同样简单。 +虽然你能够通过编写 Unix shell 脚本或 Windows 批处理文件来处理其中的某些任务,但 Shell 脚本更适合移动文件或修改文本数据,并不适合编写 GUI 应用程序或游戏;虽然你能够使用 C/C++/JAVA 编写程序,但即使编写一个简单的 first-draft 程序也有可能耗费大量的开发时间。相比之下,Python 更易于使用,无论在 Windows、Mac OS X 或 Unix 操作系统上它都会帮助你更快地完成任务。 + + +虽然 Python 易于使用,但它却是一门完整的编程语言;与 Shell 脚本或批处理文件相比,它为编写大型程序提供了更多的结构和支持。另一方面,Python 提供了比 C 更多的错误检查,并且作为一门 *高级语言* ,它内置支持高级的数据结构类型,例如:灵活的数组和字典。因其具有更多的通用数据类型,同 Awk 甚至 Perl 相比较,Python 适用于更多领域,至少大多数事情在 Python 中与其他语言同样简单。 + + +Python 允许你将程序分割为不同的模块,以便在其他的 Python 程序中重用。Python 内置提供了大量的标准模块,你可以将其用作程序的基础,或者作为学习 Python 编程的示例。 这些模块提供了诸如文件 I/O、系统调用、Socket 支持,甚至类似 Tk 的用户图形界面(GUI)工具包接口。 -Python 允许你将程序分割为不同的模块,以便在其他的 Python 程序中重用。 Python 内置提供了大量的标准模块,你可以将其用作程序的基础,或者作为学习 Python 编程的示例。 这些模块提供了诸如文件 I/O、系统调用、Socket 支持,甚至类似 Tk 的用户图形界面(GUI)工具包接口。 -Python 是一门解释型语言,因为无需编译和链接,你可以在程序开发中节省宝贵的时间。 Python 解释器可以交互地使用,这使得试验语言的特性、编写临时程序或在自底向上的程序开发中测试方法非常容易。 你甚至还可以把它当做一个桌面计算器。 +Python 是一门解释型语言,因为无需编译和链接,你可以在程序开发中节省宝贵的时间。Python 解释器可以交互地使用,这使得试验语言的特性、编写临时程序或在自底向上的程序开发中测试方法非常容易。 你甚至还可以把它当做一个桌面计算器。 -Python 让程序编写的紧凑和可读。 用 Python 编写的程序通常比同样的 C、C++ 或 Java 程序更短小,这是因为以下几个原因: + +Python 让程序编写的紧凑和可读。用 Python 编写的程序通常比同样的 C、C++ 或 Java 程序更短小,这是因为以下几个原因: * 高级数据结构使你可以在一条语句中表达复杂的操作; @@ -26,13 +33,18 @@ Python 让程序编写的紧凑和可读。 用 Python 编写的程序通常比 * 变量或参数无需声明。 -Python 是 *可扩展* 的:如果你会 C 语言编程便可以轻易的为解释器添加内置函数或模块,或者为了对性能瓶颈作优化,或者将 Python 程序与只有二进制形式的库(比如某个专业的商业图形库)连接起来。 一旦你真正掌握了它,你可以将 Python 解释器集成进某个 C 应用程序,并把它当作那个程序的扩展或命令行语言。 -顺便说一句,这个语言的名字来自于 BBC 的 “Monty Python’s Flying Cirecus” 节目,和爬行类动物没有任何关系。 在文档中引用 Monty Python 的典故不仅可行,而且值得鼓励! +Python 是 *可扩展* 的:如果你会 C 语言编程便可以轻易的为解释器添加内置函数或模块,或者为了对性能瓶颈作优化,或者将 Python 程序与只有二进制形式的库(比如某个专业的商业图形库)连接起来。一旦你真正掌握了它,你可以将 Python 解释器集成进某个 C 应用程序,并把它当作那个程序的扩展或命令行语言。 + + +顺便说一句,这个语言的名字来自于 BBC 的 "Monty Python’s Flying Cirecus" 节目,和爬行类动物没有任何关系。在文档中引用 Monty Python 的典故不仅可行,而且值得鼓励! + 现在你已经为 Python 兴奋不已了吧,迫不及待地想要领略更多的细节! 学习一门语言最好的方法就是使用它,本指南推荐你边读边使用 Python 解释器练习。 -下一节中,我们将解释 Python 解释器的用法。 这是很简单的一件事情,但它有助于试验后面的例子。 + +下一节中,我们将解释 Python 解释器的用法。这是很简单的一件事情,但它有助于试验后面的例子。 + 本手册剩下的部分将通过示例介绍 Python 语言及系统的诸多特性,开始是简单的语法、数据类型和表达式,接着介绍函数与模块,最后涉及异常和自定义类这样的高级内容。 diff --git a/docs/html/_sources/classes.txt b/docs/html/_sources/classes.txt new file mode 100644 index 0000000..c31693c --- /dev/null +++ b/docs/html/_sources/classes.txt @@ -0,0 +1,579 @@ +.. _tut-classes: + +******* +类 +******* + +Python 的类机制通过最小的新语法和语义在语言中实现了类。它是 C++ 或者 Modula-3 语言中类机制的混合。就像模块一样,Python 的类并没有在用户和定义之间设立绝对的屏障,而是依赖于用户不去“强行闯入定义”的优雅。另一方面,类的大多数重要特性都被完整的保留下来:类继承机制允许多重继承,派生类可以覆盖(override)基类中的任何方法或类,可以使用相同的方法名称调用基类的方法。对象可以包含任意数量的私有数据。 + +用 C++ 术语来讲,所有的类成员(包括数据成员)都是公有( *public* )的,所有的成员函数都是虚( *virtual* )的。用 Modula-3 的术语来讲,在成员方法中没有简便的方式引用对象的成员:方法函数在定义时需要以引用的对象做为第一个参数,调用时则会隐式引用对象。像在 Smalltalk 中一个,类也是对象。这就提供了导入和重命名语义。不像 C++ 和 Modula-3 中那样,大多数带有特殊语法的内置操作符(算法运算符、下标等)都可以针对类的需要重新定义。 + +在讨论类时,没有足够的得到共识的术语,我会偶尔从 Smalltalk 和 C++ 借用一些。我比较喜欢用 Modula-3 的用语,因为比起 C++,Python 的面向对象语法更像它,但是我想很少有读者听过这个。 + + +.. _tut-object: + +术语相关 +============================== + +对象具有特性,并且多个名称(在多个作用域中)可以绑定在同一个对象上。这在其它语言中被称为别名。在对 Python 的第一印象中这通常会被忽略,并且当处理不可变基础类型(数字,字符串,元组)时可以被放心的忽略。 但是,在调用列表、字典这类可变对象,或者大多数程序外部类型(文件,窗体等)描述实体时,别名对 Python 代码的语义便具有(有意而为!)影响。这通常有助于程序的优化,因为在某些方面别名表现的就像是指针。 例如,你可以轻易的传递一个对象,因为通过继承只是传递一个指针。并且如果一个方法修改了一个作为参数传递的对象,调用者可以接收这一变化 —— 这消除了两种不同的参数传递机制的需要,像 Pascal 语言。 + + +.. _tut-scopes: + +Python 作用域和命名空间 +============================ + +在介绍类之前,我首先介绍一些有关 Python 作用域的规则。类的定义非常巧妙地运用了命名空间,要完全理解接下来的知识,需要先理解作用域和命名空间的工作原理。另外,这一切的知识对于任何高级 Python 程序员都非常有用。 + +让我们从一些定义说起。 + +*命名空间* 是从命名到对象的映射。当前命名空间主要是通过 Python 字典实现的,不过通常不关心具体的实现方式(除非出于性能考虑),以后也有可能会改变其实现方式。以下有一些命名空间的例子:内置命名(像 `abs() `_ 这样的函数,以及内置异常名)集,模块中的全局命名,函数调用中的局部命名。某种意义上讲对象的属性集也是一个命名空间。关于命名空间需要了解的一件很重要的事就是不同命名空间中的命名没有任何联系,例如两个不同的模块可能都会定义一个名为 ``maximize`` 的函数而不会发生混淆--用户必须以模块名为前缀来引用它们。 + +顺便提一句,我称 Python 中任何一个 “.” 之后的命名为 *属性* --例如,表达式 ``z.real`` 中的 ``real`` 是对象 ``z`` 的一个属性。严格来讲,从模块中引用命名是引用属性:表达式 ``modname.funcname`` 中,``modname`` 是一个模块对象,``funcname`` 是它的一个属性。因此,模块的属性和模块中的全局命名有直接的映射关系:它们共享同一命名空间![#]_ + +属性可以是只读或写的。后一种情况下,可以对属性赋值。你可以这样做:``modname.the_answer = 42``。可写的属性也可以用 `del `_ 语句删除。例如:``del modname.the_answer`` 会从 ``modname`` 对象中删除 ``the_answer`` 属性。 + +不同的命名空间在不同的时刻创建,有不同的生存期。包含内置命名的命名空间在 Python 解释器启动时创建,会一直保留,不被删除。模块的全局命名空间在模块定义被读入时创建,通常,模块命名空间也会一直保存到解释器退出。由解释器在最高层调用执行的语句,不管它是从脚本文件中读入还是来自交互式输入,都是 `__main__ `_ 模块的一部分,所以它们也拥有自己的命名空间(内置命名也同样被包含在一个模块中,它被称作 `__builtin__ `_ )。 + +当调用函数时,就会为它创建一个局部命名空间,并且在函数返回或抛出一个并没有在函数内部处理的异常时被删除(实际上,用遗忘来形容到底发生了什么更为贴切)。 当然,每个递归调用都有自己的局部命名空间。 + +*作用域* 就是一个 Python 程序可以直接访问命名空间的正文区域。这里的直接访问意思是一个对名称的错误引用会尝试在命名空间内查找。 + +尽管作用域是静态定义,在使用时他们都是动态的。每次执行时,至少有三个命名空间可以直接访问的作用域嵌套在一起: + +* 包含局部命名的使用域在最里面,首先被搜索;其次搜索的是中层的作用域,这里包含了同级的函数; + + 最后搜索最外面的作用域,它包含内置命名。 + +* 首先搜索最内层的作用域,它包含局部命名任意函数包含的作用域,是内层嵌套作用域搜索起点,包含非局部,但是也非全局的命名 + +* 接下来的作用域包含当前模块的全局命名 + +* 最外层的作用域(最后搜索)是包含内置命名的命名空间。 + +如果一个命名声明为全局的,那么所有的赋值和引用都直接针对包含模全局命名的中级作用域。另外,从外部访问到的所有内层作用域的变量都是只读的(试图写这样的变量只会在内部作用域创建一个 *新* 局部变量,外部标示命名的那个变量不会改变)。 + +通常,局部作用域引用当前函数的命名。在函数之外,局部作用域与全局使用域引用同一命名空间:模块命名空间。类定义也是局部作用域中的另一个命名空间。 + +重要的是作用域决定于源程序的意义:一个定义于某模块中的函数的全局作用域是该模块的命名空间,而不是该函数的别名被定义或调用的位置,了解这一点非常重要。另一方面,命名的实际搜索过程是动态的,在运行时确定的——然而,Python 语言也在不断发展,以后有可能会成为静态的“编译”时确定,所以不要依赖动态解析(事实上,局部变量已经是静态确定了。)! + +Python 的一个特别之处在于 —— 如果没有使用 `global `_ 语法 —— 其赋值操作总是在最里层的作用域。赋值不会复制数据 —— 只是将命名绑定到对象。删除也是如此:``del x`` 只是从局部作用域的命名空间中删除命名 ``x`` 。事实上,所有引入新命名的操作都作用于局部作用域。特别是 `import `_ 语句和函数定将模块名或函数绑定于局部作用域(可以使用 `global `_ 语句将变量引入到全局作用域。)。 + + +.. _tut-firstclasses: + +初识类 +======================= + +类引入了一些新语法:三种新的对象类型和一些新的语义。 + + +.. _tut-classdefinition: + +类定义语法 +----------------------- + +类定义最简单的形式如下:: + + class ClassName: + + . + . + . + + +类的定义就像函数定义( `def `_ 语句),要先执行才能生效(你当然可以把它放进 `if `_ 语句的某一分支,或者一个函数的内部。)。 + +习惯上,类定义语句的内容通常是函数定义,不过其它语句也可以,有时会很有用——后面我们再回过头来讨论。类中的函数定义通常包括了一个特殊形式的参数列表,用于方法调用约定——同样我们在后面讨论这些。 + +进入类定义部分后,会创建出一个新的命名空间,作为局部作用域——因此,所有的赋值成为这个新命名空间的局部变量。特别是函数定义在此绑定了新的命名。 + +类定义完成时(正常退出),就创建了一个 *类对象*。基本上它是对类定义创建的命名空间进行了一个包装;我们在下一节进一步学习类对象的知识。原始的局部作用域(类定义引入之前生效的那个)得到恢复,类对象在这里绑定到类定义头部的类名(例子中是 :class:`ClassName`)。 + + +.. _tut-classobjects: + +类对象 +------------- + +类对象支持两种操作:属性引用和实例化。 + +*属性引用* 使用和 Python 中所有的属性引用一样的标准语法:``obj.name``。类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:: + + class MyClass: + """A simple example class""" + i = 12345 + def f(self): + return 'hello world' + +那么 ``MyClass.i`` 和 ``MyClass.f`` 是有效的属性引用,分别返回一个整数和一个方法对象。也可以对类属性赋值,你可以通过给 ``MyClass.i`` 赋值来修改它。:attr:`__doc__` 也是一个有效的属性,返回类的文档字符串:``"A simple example class"``。 + +类的 *实例化* 使用函数符号。只要将类对象看作是一个返回新的类实例的无参数函数即可,例如(假设沿用前面的类):: + + x = MyClass() + +以上创建了一个新的类 *实例* 并将该对象赋给局部变量 ``x``。 + +这个实例化操作(“调用”一个类对象)来创建一个空的对象。很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 :meth:`__init__` 的特殊方法,像下面这样:: + + def __init__(self): + self.data = [] + +类定义了 `__init__() `_ 方法的话,类的实例化操作会自动为新创建的类实例调用 `__init__() `_ 方法。所以在下例中,可以这样创建一个新的实例:: + + x = MyClass() + +当然,出于弹性的需要,`__init__() `_ 方法可以有参数。事实上,参数通过 `__init__() `_ 传递到类的实例化操作上。例如:: + + >>> class Complex: + ... def __init__(self, realpart, imagpart): + ... self.r = realpart + ... self.i = imagpart + ... + >>> x = Complex(3.0, -4.5) + >>> x.r, x.i + (3.0, -4.5) + + +.. _tut-instanceobjects: + +实例对象 +---------------- + +现在我们可以用实例对象作什么?实例对象唯一可用的操作就是属性引用。有两种有效的属性名。 + +*数据属性* 相当于 Smalltalk 中的“实例变量”或 C++ 中的“数据成员”。和局部变量一样,数据属性不需要声明,第一次使用时它们就会生成。例如,如果 ``x`` 是前面创建的 :class:`MyClass` 实例,下面这段代码会打印出 16 而在堆栈中留下多余的东西:: + + x.counter = 1 + while x.counter < 10: + x.counter = x.counter * 2 + print x.counter + del x.counter + +另一种为实例对象所接受的引用属性是 *方法* 。方法是“属于”一个对象的函数(在 Python 中,方法不止是类实例所独有:其它类型的对象也可有方法。例如,链表对象有 append,insert,remove,sort 等等方法。然而,在后面的介绍中,除非特别说明,我们提到的方法特指类方法)。 + +.. index:: object: method + +实例对象的有效名称依赖于它的类。按照定义,类中所有(用户定义)的函数对象对应它的实例中的方法。所以在我们的例子中,``x.f`` 是一个有效的方法引用,因为 ``MyClass.f`` 是一个函数。但 ``x.i`` 不是,因为 ``MyClass.i`` 不是函数。不过 ``x.f`` 和 ``MyClass.f`` 不同,它是一个 *方法对象*,不是一个函数对象。 + + +.. _tut-methodobjects: + +方法对象 +-------------- + +通常,方法通过右绑定方式调用:: + + x.f() + +在 :class:`MyClass` 示例中,这会返回字符串 ``'hello world'``。然而,也不是一定要直接调用方法。``x.f`` 是一个方法对象,它可以存储起来以后调用。例如:: + + xf = x.f + while True: + print xf() + +会不断的打印 ``hello world``。 + +调用方法时发生了什么?你可能注意到调用 ``x.f()`` 时没有引用前面标出的变量,尽管在 :meth:`f` 的函数定义中指明了一个参数。这个参数怎么了?事实上如果函数调用中缺少参数,Python 会抛出异常,甚至这个参数实际上没什么用…… + +实际上,你可能已经猜到了答案:方法的特别之处在于实例对象作为函数的第一个参数传给了函数。在我们的例子中,调用 ``x.f()`` 相当于 ``MyClass.f(x)``。通常,以 *n* 个参数的列表去调用一个方法就相当于将方法的对象插入到参数列表的最前面后,以这个列表去调用相应的函数。 + +如果你还是不理解方法的工作原理,了解一下它的实现也许有帮助。引用非数据属性的实例属性时,会搜索它的类。如果这个命名确认为一个有效的函数对象类属性,就会将实例对象和函数对象封装进一个抽象对象:这就是方法对象。以一个参数列表调用方法对象时,它被重新拆 封,用实例对象和原始的参数列表构造一个新的参数列表,然后函数对象调用这个新的参数列表。 + + +.. _tut-class-and-instance-variables: + +类和实例变量 +---------------------------- + +一般来说,实例变量用于对每一个实例都是唯一的数据,类变量用于类的所有实例共享的属性和方法:: + + class Dog: + + kind = 'canine' # class variable shared by all instances + + def __init__(self, name): + self.name = name # instance variable unique to each instance + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.kind # shared by all dogs + 'canine' + >>> e.kind # shared by all dogs + 'canine' + >>> d.name # unique to d + 'Fido' + >>> e.name # unique to e + 'Buddy' + +正如在 :ref:`tut-object` 讨论的, `可变 `_ 对象,例如列表和字典,的共享数据可能带来意外的效果。例如,下面代码中的 *tricks* 列表不应该用作类变量,因为所有的 *Dog* 实例将共享同一个列表:: + + class Dog: + + tricks = [] # mistaken use of a class variable + + def __init__(self, name): + self.name = name + + def add_trick(self, trick): + self.tricks.append(trick) + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.add_trick('roll over') + >>> e.add_trick('play dead') + >>> d.tricks # unexpectedly shared by all dogs + ['roll over', 'play dead'] + +这个类的正确设计应该使用一个实例变量:: + + class Dog: + + def __init__(self, name): + self.name = name + self.tricks = [] # creates a new empty list for each dog + + def add_trick(self, trick): + self.tricks.append(trick) + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.add_trick('roll over') + >>> e.add_trick('play dead') + >>> d.tricks + ['roll over'] + >>> e.tricks + ['play dead'] + + +.. _tut-remarks: + +一些说明 +============== + +.. These should perhaps be placed more carefully... + +数据属性会覆盖同名的方法属性。为了避免意外的名称冲突,这在大型程序中是极难发现的 Bug,使用一些约定来减少冲突的机会是明智的。可能的约定包括:大写方法名称的首字母,使用一个唯一的小字符串(也许只是一个下划线)作为数据属性名称的前缀,或者方法使用动词而数据属性使用名词。 + +数据属性可以被方法引用,也可以由一个对象的普通用户(客户)使用。换句话说,类不能用来实现纯净的数据类型。事实上,Python 中不可能强制隐藏数据——一切基于约定(如果需要,使用 C 编写的 Python 实现可以完全隐藏实现细节并控制对象的访问。这可以用来通过 C 语言扩展 Python。)。 + +客户应该谨慎的使用数据属性,客户可能通过践踏他们的数据属性而使那些由方法维护的常量变得混乱。注意:只要能避免冲突,客户可以向一个实例对象添加他们自己的数据属性,而不会影响方法的正确性。再次强调,命名约定可以避免很多麻烦。 + +从方法内部引用数据属性(或其他方法)并没有快捷方式。我觉得这实际上增加了方法的可读性:当浏览一个方法时,在局部变量和实例变量之间不会出现令人费解的情况。 + +一般,方法的第一个参数被命名为 ``self``。这仅仅是一个约定:对 Python 而言,名称 ``self`` 绝对没有任何特殊含义(但是请注意:如果不遵循这个约定,对其他的 Python 程序员而言你的代码可读性就会变差,而且有些类查看器程序也可能是遵循此约定编写的。)。 + +类属性的任何函数对象都为那个类的实例定义了一个方法。函数定义代码不一定非得定义在类中:也可以将一个函数对象赋值给类中的一个局部变量。例如:: + + # Function defined outside the class + def f1(self, x, y): + return min(x, x+y) + + class C: + f = f1 + def g(self): + return 'hello world' + h = g + +现在 ``f``, ``g`` 和 ``h`` 都是类 :class:`C` 的属性,引用的都是函数对象,因此它们都是 :class:`C` 实例的方法,``h`` 严格等于 ``g`` 。要注意的是这种习惯通常只会迷惑程序的读者。 + +通过 ``self`` 参数的方法属性,方法可以调用其它的方法:: + + class Bag: + def __init__(self): + self.data = [] + def add(self, x): + self.data.append(x) + def addtwice(self, x): + self.add(x) + self.add(x) + +方法可以像引用普通的函数那样引用全局命名。与方法关联的全局作用域是包含类定义的模块(类本身永远不会做为全局作用域使用)。尽管很少有好的理由在方法中使用全局数据,全局作用域确有很多合法的用途:其一是方法可以调用导入全局作用域的函数和方法,也可以调用定义在其中的类和函数。通常,包含此方法的类也会定义在这个全局作用域,在下一节我们会了解为何一个方法要引用自己的类。 + +每个值都是一个对象,因此每个值都有一个 类( *class* ),也称为它的类型( *type* ),它存储为 ``object.__class__``。 + + +.. _tut-inheritance: + +继承 +=========== + +当然,如果一种语言不支持继承就,“类”就没有什么意义。派生类的定义如下所示:: + + class DerivedClassName(BaseClassName): + + . + . + . + + +命名 :class:`BaseClassName` (示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:: + + class DerivedClassName(modname.BaseClassName): + +派生类定义的执行过程和基类是一样的。构造派生类对象时,就记住了基类。这在解析属性引用的时候尤其有用:如果在类中找不到请求调用的属性,就搜索基类。如果基类是由别的类派生而来,这个规则会递归的应用上去。 + +派生类的实例化没有什么特殊之处: ``DerivedClassName()`` (示列中的派生类)创建一个新的类实例。方法引用按如下规则解析:搜索对应的类属性,必要时沿基类链逐级搜索,如果找到了函数对象这个方法引用就是合法的。 + +派生类可能会覆盖其基类的方法。因为方法调用同一个对象中的其它方法时没有特权,基类的方法调用同一个基类的方法时,可能实际上最终调用了派生类中的覆盖方法(对于 C++ 程序员来说,Python 中的所有方法本质上都是 ``虚`` 方法)。 + +派生类中的覆盖方法可能是想要扩充而不是简单的替代基类中的重名方法。有一个简单的方法可以直接调用基类方法,只要调用:``BaseClassName.methodname(self, arguments)``。有时这对于客户也很有用(要注意只有 ``BaseClassName`` 在同一全局作用域定义或导入时才能这样用)。 + +Python 有两个用于继承的函数: + +* 函数 `isinstance() `_ 用于检查实例类型:``isinstance(obj, int)`` 只有在 ``obj.__class__`` 是 `int `_ 或其它从 `int `_ 继承的类型 + +* 函数 `issubclass() `_ 用于检查类继承:``issubclass(bool, int)`` 为 ``True``,因为 `bool `_ 是 `int `_ 的子类。 + + 但是,``issubclass(unicode, str)`` 是 ``False``,因为 `unicode `_ 不是 `str `_ 的子类(它们只是共享一个通用祖先类 `basestring `_ )。 + + + +.. _tut-multiple: + +多继承 +-------------------- + +Python 同样有限的支持多继承形式。多继承的类定义形如下例:: + + class DerivedClassName(Base1, Base2, Base3): + + . + . + . + + +对于旧风格的类,唯一的规则是深度优先,从左到右。因此,如果在 :class:`DerivedClassName` 中找不到属性,它搜索 :class:`Base1`,然后(递归)基类中的 :class:`Base1`,只有没有找到,它才会搜索 :class:`Base2`,依此类推。 + +(对某些人,广度优先——在搜索 :class:`Base1` 的基类之前先搜索 :class:`Base2` 和 :class:`Base3` ——看起来更自然。然而,在你能弄明白与 :class:`Base2` 中的一个属性名称冲突的后果之前,你需要知道 :class:`Base1` 的某个特定属性实际上是定义在 :class:`Base1` 的还是在其某个基类中的。深度优先规则使 :class:`Base1` 的直接属性和继承的属性之间没有差别)。 + +对于 `新风格的类 `_,方法的解析顺序动态变化地支持合作对 `super() `_ 的调用。这种方法在某些其它多继承的语言中也有并叫做 call-next-method,它比单继承语言中的super调用更强大。 + +对于新风格的类,动态调整顺序是必要的,因为所有的多继承都会有一个或多个菱形关系(从最底部的类向上,至少会有一个父类可以通过多条路径访问到)。例如,所有新风格的类都继承自 `object `_,所以任何多继承都会有多条路径到达 `object `_。为了防止基类被重复访问,动态算法线性化搜索顺序,每个类都按从左到右的顺序特别指定了顺序,每个父类只调用一次,这是单调的(也就是说一个类被继承时不会影响它祖先的次序)。所有这些特性使得设计可靠并且可扩展的多继承类成为可能。有关详细信息,请参阅 `http://www.python.org/download/releases/2.3/mro/ `_。 + + +.. _tut-private: + +私有变量和类本地引用 +====================== + +只能从对像内部访问的“私有”实例变量,在 Python 中不存在。然而,也有一个变通的访问用于大多数 Python 代码:以一个下划线开头的命名(例如 ``_spam`` )会被处理为 API 的非公开部分(无论它是一个函数、方法或数据成员)。它会被视为一个实现细节,无需公开。 + +因为有一个正当的类私有成员用途(即避免子类里定义的命名与之冲突),Python 提供了对这种结构的有限支持,称为 :dfn:`name mangling` (命名编码) 。任何形如 ``__spam`` 的标识(前面至少两个下划线,后面至多一个),被替代为 ``_classname__spam`` ,去掉前导下划线的 ``classname`` 即当前的类名。此语法不关注标识的位置,只要求在类定义内。 + +名称重整是有助于子类重写方法,而不会打破组内的方法调用。例如:: + + class Mapping: + def __init__(self, iterable): + self.items_list = [] + self.__update(iterable) + + def update(self, iterable): + for item in iterable: + self.items_list.append(item) + + __update = update # private copy of original update() method + + class MappingSubclass(Mapping): + + def update(self, keys, values): + # provides new signature for update() + # but does not break __init__() + for item in zip(keys, values): + self.items_list.append(item) + +需要注意的是编码规则设计为尽可能的避免冲突,被认作为私有的变量仍然有可能被访问或修改。在特定的场合它也是有用的,比如调试的时候。 + +要注意的是代码传入 ``exec``, ``eval()`` 或 ``execfile()`` 时不考虑所调用的类的类名,视其为当前类,这类似于 ``global`` 语句的效应,已经按字节编译的部分也有同样的限制。这也同样作用于 ``getattr()``, ``setattr()`` 和 ``delattr()``,像直接引用 ``__dict__`` 一样。 + + +.. _tut-odds: + +补充 +============= + +有时类似于 Pascal 中“记录(record)”或 C 中“结构(struct)”的数据类型很有用,它将一组已命名的数据项绑定在一起。一个空的类定义可以很好的实现这它:: + + class Employee: + pass + + john = Employee() # Create an empty employee record + + # Fill the fields of the record + john.name = 'John Doe' + john.dept = 'computer lab' + john.salary = 1000 + +某一段 Python 代码需要一个特殊的抽象数据结构的话,通常可以传入一个类,事实上这模仿了该类的方法。例如,如果你有一个用于从文件对象中格式化数据的函数,你可以定义一个带有 :meth:`read` 和 :meth:`readline` 方法的类,以此从字符串缓冲读取数据,然后将该类的对象作为参数传入前述的函数。 + +实例方法对象也有属性:``m.im_self`` 是一个实例方法所属的对象,而 ``m.im_func`` 是这个方法对应的函数对象。 + + +.. _tut-exceptionclasses: + +异常也是类 +========================== + +用户自定义异常也可以是类。利用这个机制可以创建可扩展的异常体系。 + +以下是两种新的,有效的(语义上的)异常抛出形式,使用 `raise `_ 语句:: + + raise Class, instance + + raise instance + +第一种形式中,``instance`` 必须是 :class:`Class` 或其派生类的一个实例。第二种形式是以下形式的简写:: + + raise instance.__class__, instance + +发生的异常其类型如果是 `except `_ 子句中列出的类,或者是其派生类,那么它们就是相符的(反过来说--发生的异常其类型如果是异常子句中列出的类的基类,它们就不相符)。例如,以下代码会按顺序打印 B,C,D:: + + class B: + pass + class C(B): + pass + class D(C): + pass + + for c in [B, C, D]: + try: + raise c() + except D: + print "D" + except C: + print "C" + except B: + print "B" + +要注意的是如果异常子句的顺序颠倒过来( ``execpt B`` 在最前),它就会打印 B,B,B,第一个匹配的异常被触发。 + +打印一个异常类的错误信息时,先打印类名,然后是一个空格、一个冒号,然后是用内置函数 `str() `_ 将类转换得到的完整字符串。 + + +.. _tut-iterators: + +迭代器 +========= + +现在你可能注意到大多数容器对象都可以用 `for `_ 遍历:: + + for element in [1, 2, 3]: + print element + for element in (1, 2, 3): + print element + for key in {'one':1, 'two':2}: + print key + for char in "123": + print char + for line in open("myfile.txt"): + print line + +这种形式的访问清晰、简洁、方便。迭代器的用法在 Python 中普遍而且统一。在后台,`for `_ 语句在容器对象中调用 `iter() `_。 该函数返回一个定义了 `next() `_ 方法的迭代器对象,它在容器中逐一访问元素。没有后续的元素时,`next() `_ 抛出一个 `StopIteration `_ 异常通知 `for `_ 语句循环结束。以下是其工作原理的示例:: + + >>> s = 'abc' + >>> it = iter(s) + >>> it + + >>> next(it) + 'a' + >>> next(it) + 'b' + >>> next(it) + 'c' + >>> next(it) + Traceback (most recent call last): + File "", line 1, in ? + next(it) + StopIteration + +了解了迭代器协议的后台机制,就可以很容易的给自己的类添加迭代器行为。定义一个 `__iter__() `_ 方法,使其返回一个带有 `next() `_ 方法的对象。如果这个类已经定义了 `next() `_,那么 `__iter__() `_ 只需要返回 ``self``:: + + class Reverse: + """Iterator for looping over a sequence backwards.""" + def __init__(self, data): + self.data = data + self.index = len(data) + def __iter__(self): + return self + def __next__(self): + if self.index == 0: + raise StopIteration + self.index = self.index - 1 + return self.data[self.index] + +:: + + >>> rev = Reverse('spam') + >>> iter(rev) + <__main__.Reverse object at 0x00A1DB50> + >>> for char in rev: + ... print(char) + ... + m + a + p + s + + +.. _tut-generators: + +生成器 +========== + +`Generator `_ 是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,需要返回数据的时候使用 `yield `_ 语句。每次 `next() `_ 被调用时,生成器回复它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)。以下示例演示了生成器可以很简单的创建出来:: + + def reverse(data): + for index in range(len(data)-1, -1, -1): + yield data[index] + +:: + + >>> for char in reverse('golf'): + ... print char + ... + f + l + o + g + +前一节中描述了基于类的迭代器,它能作的每一件事生成器也能作到。因为自动创建了 `__iter__() `_ 和 `next() `_ 方法,生成器显得如此简洁。 + +另一个关键的功能在于两次执行之间,局部变量和执行状态都自动的保存下来。这使函数很容易写,而且比使用 ``self.index`` 和 ``self.data`` 之类的方式更清晰。 + +除了创建和保存程序状态的自动方法,当发生器终结时,还会自动抛出 `StopIteration `_ 异常。综上所述,这些功能使得编写一个正规函数成为创建迭代器的最简单方法。 + + +.. _tut-genexps: + +生成器表达式 +===================== + +有时简单的生成器可以用简洁的方式调用,就像不带中括号的链表推导式。这些表达式是为函数调用生成器而设计的。生成器表达式比完整的生成器定义更简洁,但是没有那么多变,而且通常比等价的链表推导式更容易记。 + +例如:: + + >>> sum(i*i for i in range(10)) # sum of squares + 285 + + >>> xvec = [10, 20, 30] + >>> yvec = [7, 5, 3] + >>> sum(x*y for x,y in zip(xvec, yvec)) # dot product + 260 + + >>> from math import pi, sin + >>> sine_table = {x: sin(x*pi/180) for x in range(0, 91)} + + >>> unique_words = set(word for line in page for word in line.split()) + + >>> valedictorian = max((student.gpa, student.name) for student in graduates) + + >>> data = 'golf' + >>> list(data[i] for i in range(len(data)-1, -1, -1)) + ['f', 'l', 'o', 'g'] + + + +.. rubric:: Footnotes + +.. [#] 有一个例外。模块对象有一个隐秘的只读对象,名为 :attr:`__dict__` ,它返回用于实现模块命名空间的字典,命名 :attr:`__dict__` 是一个属性而非全局命名。显然,使用它违反了命名空间实现的抽象原则,应该被严格限制于调试中。 \ No newline at end of file diff --git a/docs/html/_sources/controlflow.txt b/docs/html/_sources/controlflow.txt new file mode 100644 index 0000000..05edceb --- /dev/null +++ b/docs/html/_sources/controlflow.txt @@ -0,0 +1,556 @@ +.. _tut-morecontrol: + +*********************** +深入 Python 流程控制 +*********************** + +除了前面介绍的 `while `_ 语句,Python 还从其它语言借鉴了一些流程控制功能,并有所改变。 + + +.. _tut-if: + +`if `_ 语句 +========================================================================== + +也许最有名的是 `if `_ 语句。例如:: + + >>> x = int(raw_input("Please enter an integer: ")) + Please enter an integer: 42 + >>> if x < 0: + ... x = 0 + ... print 'Negative changed to zero' + ... elif x == 0: + ... print 'Zero' + ... elif x == 1: + ... print 'Single' + ... else: + ... print 'More' + ... + More + + +可能会有零到多个 `elif `_ 部分,`else `_ 是可选的。关键字 `elif `_ 是 "else if" 的缩写,这个可以有效避免过深的缩进。`if `_ ... `elif `_ ... `elif `_ ... 序列用于替代其它语言中的 ``switch`` 或 ``case`` 语句。 + + +.. _tut-for: + +`for `_ 语句 +============================================================================== + +.. index:: + statement: for + +Python 中的 `for `_ 语句和 C 或 Pascal 中的略有不同。通常的循环可能会依据一个等差数值步进过程(如 Pascal),或由用户来定义迭代步骤和中止条件(如 C ),Python 的 `for `_ 语句依据任意序列(链表或字符串)中的子项,按它们在序列中的顺序来进行迭代。例如(没有暗指):: + + >>> # Measure some strings: + ... words = ['cat', 'window', 'defenestrate'] + >>> for w in words: + ... print w, len(w) + ... + cat 3 + window 6 + defenestrate 12 + + +在迭代过程中修改迭代序列不安全(只有在使用链表这样的可变序列时才会有这样的情况)。如果你想要修改你迭代的序列(例如:复制选择项),你可以迭代它的复本。使用切割标识就可以很方便地做到这一点:: + + >>> for w in words[:]: # Loop over a slice copy of the entire list. + ... if len(w) > 6: + ... words.insert(0, w) + ... + >>> words + ['defenestrate', 'cat', 'window', 'defenestrate'] + + +.. _tut-range: + +`range() `_ 函数 +=========================================================================== + +如果你需要一个数值序列,内置函数 `range() `_ 会很方便,它生成一个等差级数链表:: + + >>> range(10) + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + +``range(10)`` 生成了一个包含 10 个值的链表,它用链表的索引值填充了这个长度为 10 的列表,所生成的链表中不包括范围中的结束值。也可以让 range 操作从另一个数值开始,或者可以指定一个不同的步进值(甚至是负数,有时这也被称为 "步长"):: + + >>> range(5, 10) + [5, 6, 7, 8, 9] + >>> range(0, 10, 3) + [0, 3, 6, 9] + >>> range(-10, -100, -30) + [-10, -40, -70] + + +需要迭代链表索引的话,如下所示结合使用 `range() `_ 和 `len() `_:: + + >>> a = ['Mary', 'had', 'a', 'little', 'lamb'] + >>> for i in range(len(a)): + ... print i, a[i] + ... + 0 Mary + 1 had + 2 a + 3 little + 4 lamb + + +不过,这种场合可以方便地使用 `enumerate() `_,请参见 :ref:`tut-loopidioms`。 + + +.. _tut-break: + +`break`_ 和 `continue`_ 语句, 以及循环中的 `else`_ 子句 +========================================================================================= + +.. _break: https://docs.python.org/2.7/reference/simple_stmts.html#break +.. _continue: https://docs.python.org/2.7/reference/simple_stmts.html#continue +.. _else: https://docs.python.org/2.7/reference/compound_stmts.html#else + + +`break `_ 语句和 C 中的类似,用于跳出最近的一级 `for `_ 或 `while `_ 循环。 + +循环可以有一个 ``else`` 子句;它在循环迭代完整个列表 (对于 `for `_) 后或执行条件为 false (对于 `while `_) 时执行,但循环被 `break `_ 中止的情况下不会执行。以下搜索素数的示例程序演示了这个子句:: + + >>> for n in range(2, 10): + ... for x in range(2, n): + ... if n % x == 0: + ... print n, 'equals', x, '*', n/x + ... break + ... else: + ... # loop fell through without finding a factor + ... print n, 'is a prime number' + ... + 2 is a prime number + 3 is a prime number + 4 equals 2 * 2 + 5 is a prime number + 6 equals 2 * 3 + 7 is a prime number + 8 equals 2 * 4 + 9 equals 3 * 3 + + +(Yes, 这是正确的代码。看仔细: ``else`` 语句是属于 `for `_ 循环之中, **不是** `if `_ 语句。) + +与循环一起使用时,``else`` 子句与 `try `_ 语句的 ``else`` 子句比与 `if `_ 语句的具有更多的共同点:`try `_ 语句的 ``else`` 子句在未出现异常时运行,循环的 ``else`` 子句在未出现 ``break`` 时运行。更多关于 `try `_ 语句和异常的内容,请参见 :ref:`tut-handling`。 + +`continue `_ 语句是从 C 中借鉴来的,它表示循环继续执行下一次迭代:: + + >>> for num in range(2, 10): + ... if num % 2 == 0: + ... print "Found an even number", num + ... continue + ... print "Found a number", num + Found an even number 2 + Found a number 3 + Found an even number 4 + Found a number 5 + Found an even number 6 + Found a number 7 + Found an even number 8 + Found a number 9 + + +.. _tut-pass: + +`pass `_ 语句 +============================================================================ + +`pass `_ 语句什么也不做。它用于那些语法上必须要有什么语句,但程序什么也不做的场合,例如:: + + >>> while True: + ... pass # Busy-wait for keyboard interrupt (Ctrl+C) + ... + + +这通常用于创建最小结构的类:: + + >>> class MyEmptyClass: + ... pass + ... + + +另一方面,`pass `_ 可以在创建新代码时用来做函数或控制体的占位符。可以让你在更抽象的级别上思考。`pass `_ 可以默默地被忽视:: + + >>> def initlog(*args): + ... pass # Remember to implement this! + ... + + +.. _tut-functions: + +定义函数 +================== + +我们可以定义一个函数用来生成任意上界的菲波那契数列:: + + >>> def fib(n): # write Fibonacci series up to n + ... """Print a Fibonacci series up to n.""" + ... a, b = 0, 1 + ... while a < n: + ... print a, + ... a, b = b, a+b + ... + >>> # Now call the function we just defined: + ... fib(2000) + 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 + +.. index:: + single: documentation strings + single: docstrings + single: strings, documentation + +关键字 `def `_ 引入了一个函数 *定义* 。在其后必须跟有函数名和包括形式参数的圆括号。函数体语句从下一行开始,必须是缩进的。 + +函数体的第一行语句可以是可选的字符串文本,这个字符串是函数的文档字符串,或者称为 :dfn:`docstring` 。(更多关于 docstrings 的信息请参考 :ref:`tut-docstrings` ) 有些工具通过 docstrings 自动生成在线的或可打印的文档,或者让用户通过代码交互浏览;在你的代码中包含 docstrings 是一个好的实践,让它成为习惯吧。 + +函数 *调用* 会为函数局部变量生成一个新的符号表。确切地说,所有函数中的变量赋值都是将值存储在局部符号表。变量引用首先在局部符号表中查找,然后是包含函数的局部符号表,然后是全局符号表,最后是内置名字表。因此,全局变量不能在函数中直接赋值 (除非用 `global `_ 语句命名),尽管他们可以被引用。 + +函数引用的实际参数在函数调用时引入局部符号表,因此,实参总是 *传值调用* (这里的 *值* 总是一个对象引用,而不是该对象的值)。[#]_ 一个函数被另一个函数调用时,一个新的局部符号表在调用过程中被创建。 + +一个函数定义会在当前符号表内引入函数名。函数名指代的值(即函数体)存在一个被 Python 解释器认定为 *用户自定义函数* 的类型。这个值可以赋予其他的名字(即变量名),然后它也可以被当做函数使用。这可以作为通用的重命名机制:: + + >>> fib + + >>> f = fib + >>> f(100) + 0 1 1 2 3 5 8 13 21 34 55 89 + + +如果你使用过其他语言,你可能会反对说:``fib`` 不是一个函数,而是一个方法,因为它并不返回任何值。事实上,没有 `return `_ 语句的函数确实会返回一个值,虽然是一个相当令人厌烦的值(指 None )。这个值被称为 ``None`` (这是一个内建名称)。如果 ``None`` 值是唯一被书写的值,那么在写的时候通常会被解释器忽略(即不输出任何内容)。如果你确实想看到这个值的输出内容,请使用 `print `_:: + + >>> fib(0) + >>> print fib(0) + None + + +以下示例演示了如何从函数中返回一个包含菲波那契数列的数值链表,而不是打印它:: + + >>> def fib2(n): # return Fibonacci series up to n + ... """Return a list containing the Fibonacci series up to n.""" + ... result = [] + ... a, b = 0, 1 + ... while a < n: + ... result.append(a) # see below + ... a, b = b, a+b + ... return result + ... + >>> f100 = fib2(100) # call it + >>> f100 # write the result + [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] + + +和以前一样,这个例子演示了一些新的 Python 功能: + +* `return `_ 语句从函数中返回一个值。 + + 不带表达式的 `return `_ 返回 ``None`` 。过程结束后也会返回 ``None`` 。 + +* 语句 ``result.append(b)`` 称为链表对象 ``result`` 的一个 *方法* (method)。 + + 方法是一个“属于”某个对象的函数,它被命名为 ``obj.methodename``,这里的 ``obj`` 是某个对象(可能是一个表达式),``methodename`` 是某个在该对象类型定义中的方法的命名。不同的类型定义不同的方法。不同类型可能有同样名字的方法,但不会混淆(当你定义自己的对象类型和方法时,可能会出现这种情况,*class* 的定义方法详见 :ref:`tut-classes` )。示例中演示的 :meth:`append` 方法由链表对象定义,它向链表中加入一个新元素。在示例中它等同于 ``result = result + [b]`` ,不过效率更高。 + + +.. _tut-defining: + +深入 Python 函数定义 +========================== + +在 Python 中,你也可以定义包含若干参数的函数。这里有三种可用的形式,也可以混合使用。 + + +.. _tut-defaultargs: + +默认参数值 +----------------------- + +最常用的一种形式是为一个或多个参数指定默认值。这会创建一个可以使用比定义时允许的参数更少的参数调用的函数,例如:: + + def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): + while True: + ok = raw_input(prompt) + if ok in ('y', 'ye', 'yes'): + return True + if ok in ('n', 'no', 'nop', 'nope'): + return False + retries = retries - 1 + if retries < 0: + raise IOError('refusenik user') + print complaint + + +这个函数可以通过几种不同的方式调用: + +* 只给出必要的参数: + + ``ask_ok('Do you really want to quit?')`` + +* 给出一个可选的参数: + + ``ask_ok('OK to overwrite the file?', 2)`` + +* 或者给出所有的参数: + + ``ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')`` + +这个例子还介绍了 `in `_ 关键字。它测定序列中是否包含某个确定的值。 + +默认值在函数 *定义* 作用域被解析,如下所示:: + + i = 5 + + def f(arg=i): + print arg + + i = 6 + f() + + +将会输出 ``5``。 + +**重要警告:** 默认值只被赋值一次。这使得当默认值是可变对象时会有所不同,比如列表、字典或者大多数类的实例。例如,下面的函数在后续调用过程中会累积(前面)传给它的参数:: + + def f(a, L=[]): + L.append(a) + return L + + print f(1) + print f(2) + print f(3) + + +这将会打印:: + + [1] + [1, 2] + [1, 2, 3] + + +如果你不想在随后的调用中共享默认值,可以像这样写函数:: + + def f(a, L=None): + if L is None: + L = [] + L.append(a) + return L + + +.. _tut-keywordargs: + +关键字参数 +----------------- + +函数可以通过 `关键字参数 `_ 的形式来调用,形如 ``keyword = value``。例如,以下的函数:: + + def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): + print "-- This parrot wouldn't", action, + print "if you put", voltage, "volts through it." + print "-- Lovely plumage, the", type + print "-- It's", state, "!" + + +接受一个必选参数( ``voltage`` )以及三个可选参数( ``state``, ``action``, 和 ``type`` )。可以用以下的任一方法调用:: + + parrot(1000) # 1 positional argument + parrot(voltage=1000) # 1 keyword argument + parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments + parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments + parrot('a million', 'bereft of life', 'jump') # 3 positional arguments + parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword + + +不过以下几种调用是无效的:: + + parrot() # required argument missing + parrot(voltage=5.0, 'dead') # non-keyword argument after a keyword argument + parrot(110, voltage=220) # duplicate value for the same argument + parrot(actor='John Cleese') # unknown keyword argument + +在函数调用中,关键字的参数必须跟随在位置参数的后面。传递的所有关键字参数必须与函数接受的某个参数相匹配(例如 ``actor`` 不是 ``parrot`` 函数的有效参数),它们的顺序并不重要。这也包括非可选参数(例如 ``parrot(voltage=1000)`` 也是有效的)。任何参数都不可以多次赋值。下面的示例由于这种限制将失败:: + + >>> def function(a): + ... pass + ... + >>> function(0, a=0) + Traceback (most recent call last): + File "", line 1, in ? + TypeError: function() got multiple values for keyword argument 'a' + + +引入一个形如 ``**name`` 的参数时,它接收一个字典(参见 `Mapping Types — dict `_ ),该字典包含了所有未出现在形式参数列表中的关键字参数。这里可能还会组合使用一个形如 ``*name`` (下一小节详细介绍)的形式参数,它接收一个元组(下一节中会详细介绍),包含了所有没有出现在形式参数列表中的参数值。( ``*name`` 必须在 ``**name`` 之前出现)例如,我们这样定义一个函数:: + + def cheeseshop(kind, *arguments, **keywords): + print "-- Do you have any", kind, "?" + print "-- I'm sorry, we're all out of", kind + for arg in arguments: + print arg + print "-" * 40 + keys = sorted(keywords.keys()) + for kw in keys: + print kw, ":", keywords[kw] + + +它可以像这样调用:: + + cheeseshop("Limburger", "It's very runny, sir.", + "It's really very, VERY runny, sir.", + shopkeeper='Michael Palin', + client="John Cleese", + sketch="Cheese Shop Sketch") + + +当然它会按如下内容打印:: + + -- Do you have any Limburger ? + -- I'm sorry, we're all out of Limburger + It's very runny, sir. + It's really very, VERY runny, sir. + ---------------------------------------- + client : John Cleese + shopkeeper : Michael Palin + sketch : Cheese Shop Sketch + +注意在打印关键字参数之前,通过对关键字字典 ``keys()`` 方法的结果进行排序,生成了关键字参数名的列表;如果不这样做,打印出来的参数的顺序是未定义的。 + +.. _tut-arbitraryargs: + +可变参数列表 +------------------------ + +.. index:: + statement: * + +最后,一个最不常用的选择是可以让函数调用可变个数的参数。这些参数被包装进一个元组(参见 :ref:`tut-tuples` )。在这些可变个数的参数之前,可以有零到多个普通的参数:: + + def write_multiple_items(file, separator, *args): + file.write(separator.join(args)) + + +.. _tut-unpacking-arguments: + +参数列表的分拆 +------------------------ + +另有一种相反的情况: 当你要传递的参数已经是一个列表,但要调用的函数却接受分开一个个的参数值。这时候你要把已有的列表拆开来。例如内建函数 `range() `_ 需要独立的 *start* ,*stop* 参数。 你可以在调用函数时加一个 ``*`` 操作符来自动把参数列表拆开:: + + >>> list(range(3, 6)) # normal call with separate arguments + [3, 4, 5] + >>> args = [3, 6] + >>> list(range(*args)) # call with arguments unpacked from a list + [3, 4, 5] + +.. index:: + statement: ** + +以同样的方式,可以使用 ``**`` 操作符分拆关键字参数为字典:: + + >>> def parrot(voltage, state='a stiff', action='voom'): + ... print "-- This parrot wouldn't", action, + ... print "if you put", voltage, "volts through it.", + ... print "E's", state, "!" + ... + >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} + >>> parrot(**d) + -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised ! + + +.. _tut-lambda: + +Lambda 形式 +------------ + +出于实际需要,有几种通常在函数式编程语言例如 Lisp 中出现的功能加入到了 Python 中。通过 `lambda `_ 关键字,可以创建短小的匿名函数。这里有一个函数返回它的两个参数的和:``lambda a, b: a+b``。Lambda 形式可以用于任何需要的函数对象。出于语法限制,它们只能有一个单独的表达式。语义上讲,它们只是普通函数定义中的一个语法技巧。类似于嵌套函数定义,lambda 形式可以从外部作用域引用变量:: + + >>> def make_incrementor(n): + ... return lambda x: x + n + ... + >>> f = make_incrementor(42) + >>> f(0) + 42 + >>> f(1) + 43 + +上面的示例使用 lambda 表达式返回一个函数。另一个用途是将一个小函数作为参数传递:: + + >>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] + >>> pairs.sort(key=lambda pair: pair[1]) + >>> pairs + [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')] + + +.. _tut-docstrings: + +文档字符串 +--------------------- + +.. index:: + single: docstrings + single: documentation strings + single: strings, documentation + +这里介绍的文档字符串的概念和格式。 + +第一行应该是关于对象用途的简介。简短起见,不用明确的陈述对象名或类型,因为它们可以从别的途径了解到(除非这个名字碰巧就是描述这个函数操作的动词)。这一行应该以大写字母开头,以句号结尾。 + +如果文档字符串有多行,第二行应该空出来,与接下来的详细描述明确分隔。接下来的文档应该有一或多段描述对象的调用约定、边界效应等。 + +Python 的解释器不会从多行的文档字符串中去除缩进,所以必要的时候应当自己清除缩进。这符合通常的习惯。第一行之后的第一个非空行决定了整个文档的缩进格式。(我们不用第一行是因为它通常紧靠着起始的引号,缩进格式显示的不清楚)留白"相当于"是字符串的起始缩进。每一行都不应该有缩进,如果有缩进的话,所有的留白都应该清除掉。留白的长度应当等于扩展制表符的宽度(通常是8个空格)。 + +以下是一个多行文档字符串的示例:: + + >>> def my_function(): + ... """Do nothing, but document it. + ... + ... No, really, it doesn't do anything. + ... """ + ... pass + ... + >>> print my_function.__doc__ + Do nothing, but document it. + + No, really, it doesn't do anything. + + +.. _tut-codingstyle: + +插曲:编码风格 +======================== + +.. sectionauthor:: Georg Brandl +.. index:: pair: coding; style + +此时你已经可以写一个更长更复杂的 Python 程序,是时候讨论一下 *编码风格* 了。大多数语言可以写 (或者更明白地说,*格式化* ) 作几种不同的风格。有些比其它的更好读。让你的代码对别人更易读是个好想法,养成良好的编码风格对此很有帮助。 + +对于 Python, :pep:`8` 引入了大多数项目遵循的风格指导。它给出了一个高度可读,视觉友好的编码风格。每个 Python 开发者都应该读一下,大多数要点都会对你有帮助: + +* 使用 4 空格缩进,而非 TAB。 + + 在小缩进(可以嵌套更深)和大缩进(更易读)之间,4 空格是一个很好的折中。TAB 引发了一些混乱,最好弃用。 + +* 折行以确保其不会超过 79 个字符。 + + 这有助于小显示器用户阅读,也可以让大显示器能并排显示几个代码文件。 + +* 使用空行分隔函数和类,以及函数中的大块代码。 + +* 可能的话,注释独占一行 + +* 使用文档字符串 + +* 把空格放到操作符两边,以及逗号后面,但是括号里侧不加空格:``a = f(1, 2) + g(3, 4)``。 + +* 统一函数和类命名。 + + 推荐类名用 ``驼峰命名``,函数和方法名用 ``小写_和_下划线``。总是用 ``self`` 作为方法的第一个参数(关于类和方法的知识详见 :ref:`tut-firstclasses`)。 + +* 不要使用花哨的编码,如果你的代码的目的是要在国际化 + 环境。Python 的默认情况下,UTF-8,甚至普通的 ASCII 总是工作的最好。 + +* 同样,也不要使用非 ASCII 字符的标识符,除非是不同语种的会阅读或者维护代码。 + + +.. rubric:: Footnotes + +.. [#] 实际上,*引用对象调用* 描述的更为准确。如果传入一个可变对像,调用者会看到调用操作带来的任何变化(如子项插入到列表中)。 + diff --git a/html/_sources/datastructures.txt b/docs/html/_sources/datastructures.txt similarity index 54% rename from html/_sources/datastructures.txt rename to docs/html/_sources/datastructures.txt index 290e4e0..6a09315 100644 --- a/html/_sources/datastructures.txt +++ b/docs/html/_sources/datastructures.txt @@ -11,25 +11,25 @@ 关于列表更多的内容 =================== -Python 的列表数据类型包含更多的方法。 这里是所有的列表对象方法: +Python 的列表数据类型包含更多的方法。这里是所有的列表对象方法: .. method:: list.append(x) :noindex: - 把一个元素添加到链表的结尾,相当于 ``a[len(a):] = [x]`` 。 + 把一个元素添加到链表的结尾,相当于 ``a[len(a):] = [x]``。 .. method:: list.extend(L) :noindex: - 将一个给定列表中的所有元素都添加到另一个列表中,相当于 ``a[len(a):] = L`` 。 + 将一个给定列表中的所有元素都添加到另一个列表中,相当于 ``a[len(a):] = L``。 .. method:: list.insert(i, x) :noindex: - 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 ``a.insert(0, x)`` 会插入到整个链表之前,而 ``a.insert(len(a), x)`` 相当于 ``a.append(x)`` 。 + 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 ``a.insert(0, x)`` 会插入到整个链表之前,而 ``a.insert(len(a), x)`` 相当于 ``a.append(x)``。 .. method:: list.remove(x) @@ -41,7 +41,7 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 .. method:: list.pop([i]) :noindex: - 从链表的指定位置删除元素,并将其返回。如果没有指定索引, ``a.pop()`` 返回最后一个元素。元素随即从链表中被删除。(方法中 *i* 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。) + 从链表的指定位置删除元素,并将其返回。如果没有指定索引,``a.pop()`` 返回最后一个元素。元素随即从链表中被删除。(方法中 *i* 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。) .. method:: list.index(x) @@ -56,10 +56,10 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 返回 *x* 在链表中出现的次数。 -.. method:: list.sort() +.. method:: list.sort(cmp=None, key=None, reverse=False) :noindex: - 对链表中的元素就地进行排序。 + 对链表中的元素就地进行排序(参数可以用来自定义排序方法,参考 `sorted() `_ 的更详细的解释)。 .. method:: list.reverse() @@ -87,8 +87,12 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 >>> a.sort() >>> a [-1, 1, 66.25, 333, 333, 1234.5] + >>> a.pop() + 1234.5 + >>> a + [-1, 1, 66.25, 333, 333] -也许大家会发现像 ``insert``, ``remove`` 或者 ``sort`` 这些修改列表的方法没有打印返回值--它们返回 ``None`` 。 在 python 中对所有可变的数据类型这是统一的设计原则。 +也许大家会发现像 ``insert``, ``remove`` 或者 ``sort`` 这些修改列表的方法没有打印返回值 --它们返回 ``None``。[1]_ 在 python 中对所有可变的数据类型这是统一的设计原则。 .. _tut-lists-as-stacks: @@ -99,7 +103,7 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 .. sectionauthor:: Ka-Ping Yee -链表方法使得链表可以很方便的做为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 :meth:`append` 方法可以把一个元素添加到堆栈顶。用不指定索引的 :meth:`pop` 方法可以把一个元素从堆栈顶释放出来。例如:: +链表方法使得链表可以很方便的做为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 :meth:`append` 方法可以把一个元素添加到堆栈顶。用不指定索引的 :meth:`pop` 方法可以把一个元素从堆栈顶释放出来。例如:: >>> stack = [3, 4, 5] >>> stack.append(6) @@ -125,9 +129,9 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 .. sectionauthor:: Ka-Ping Yee -你也可以把链表当做队列使用,队列作为特定的数据结构,最先进入的元素最先释放(先进先出)。不过,列表这样用效率不高。相对来说从列表末尾添加和弹出很快;在头部插入和弹出很慢(因为,为了一个元素,要移动整个列表中的所有元素)。 +你也可以把链表当做队列使用,队列作为特定的数据结构,最先进入的元素最先释放(先进先出)。不过,列表这样用效率不高。相对来说从列表末尾添加和弹出很快;在头部插入和弹出很慢(因为为了一个元素,要移动整个列表中的所有元素)。 -要实现队列,使用 :class:`collections.deque` ,它为在首尾两端快速插入和删除而设计。例如:: +要实现队列,使用 `collections.deque `_,它为在首尾两端快速插入和删除而设计。例如:: >>> from collections import deque >>> queue = deque(["Eric", "John", "Michael"]) @@ -146,14 +150,14 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 函数式编程工具 ---------------------------- -对于链表来讲,有三个内置函数非常有用: :func:`filter`, :func:`map`, 以及 :func:`reduce`。 +对于链表来讲,有三个内置函数非常有用: `filter() `_,`map() `_ 以及 `reduce() `_。 -``filter(function, sequence)`` 返回一个 sequence(序列),包括了给定序列中所有调用 ``function(item)`` 后返回值为 true 的元素。(如果可能的话,会返回相同的类型)。如果该 *序列* (sequence) 是一个 :class:`string` (字符串)或者 :class:`tuple` (元组),返回值必定是同一类型,否则,它总是 :class:`list` 。例如,以下程序可以计算部分素数:: +``filter(function, sequence)`` 返回一个 sequence(序列),包括了给定序列中所有调用 ``function(item)`` 后返回值为 true 的元素(如果可能的话,会返回相同的类型)。如果该 *序列* (sequence)是一个 `str `_, `unicode `_ 或者 `tuple `_,返回值必定是同一类型,否则,它总是 `list `_。例如,以下程序可以计算一个被 3 或者 5 整除的序列:: - >>> def f(x): return x % 2 != 0 and x % 3 != 0 + >>> def f(x): return x % 3 == 0 or x % 5 == 0 ... >>> filter(f, range(2, 25)) - [5, 7, 11, 13, 17, 19, 23] + [3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24] ``map(function, sequence)`` 为每一个元素依次调用 ``function(item)`` 并将返回值组成一个链表返回。例如,以下程序计算立方:: @@ -162,7 +166,7 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] -可以传入多个序列,函数也必须要有对应数量的参数,执行时会依次用各序列上对应的元素来调用函数(如果某些序列比其它的短,就用 ``None`` 来代替)。如果把 ``None`` 做为一个函数传入,则直接返回参数做为替代。例如:: +可以传入多个序列,函数也必须要有对应数量的参数,执行时会依次用各序列上对应的元素来调用函数(如果某些序列比其它的短,就用 ``None`` 来代替)。如果把 ``None`` 做为一个函数传入,则直接返回参数做为替代。例如:: >>> seq = range(8) >>> def add(x, y): return x+y @@ -190,7 +194,7 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 >>> sum([]) 0 -不要像示例中这样定义 :func:`sum` :因为合计数值是一个通用的需求,早已有内置的 ``sum(sequence)`` 函数,非常好用。 +不要像示例中这样定义 `sum() `_:因为合计数值是一个通用的需求,早已有内置的 ``sum(sequence)`` 函数,非常好用。 .. _tut-listcomps: @@ -198,9 +202,9 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 列表推导式 ------------------- -列表推导式为从序列中创建列表提供了一个简单的方法。 普通的应用程序通过将一些操作应用于序列的每个成员并通过返回的元素创建列表,或者通过满足特定条件的元素创建子序列。 +列表推导式为从序列中创建列表提供了一个简单的方法。普通的应用程序通过将一些操作应用于序列的每个成员并通过返回的元素创建列表,或者通过满足特定条件的元素创建子序列。 -例如, 假设我们创建一个 squares 列表, 可以像下面方式:: +例如,假设我们创建一个 squares 列表,可以像下面方式:: >>> squares = [] >>> for x in range(10): @@ -213,10 +217,9 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 squares = [x**2 for x in range(10)] -这也相当于 ``squares = map(lambda x: x**2, range(10))``, -但是上面的方式显得简洁以及具有可读性. +这也相当于 ``squares = map(lambda x: x**2, range(10))``,但是上面的方式显得简洁以及具有可读性。 -列表推导式由包含一个表达式的括号组成,表达式后面跟随一个 :keyword:`for` 子句,之后可以有零或多个 :keyword:`for` 或 :keyword:`if` 子句。 结果是一个列表,由表达式依据其后面的 :keyword:`for` 和 :keyword:`if` 子句上下文计算而来的结果构成。 +列表推导式由包含一个表达式的括号组成,表达式后面跟随一个 `for `_ 子句,之后可以有零或多个 `for `_ 或 `if `_ 子句。结果是一个列表,由表达式依据其后面的 `for `_ 和 `if `_ 子句上下文计算而来的结果构成。 例如,如下的列表推导式结合两个列表的元素,如果元素之间不相等的话:: @@ -234,9 +237,9 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 >>> combs [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] -值得注意的是在上面两个方法中的 :keyword:`for` 和 :keyword:`if` 语句的顺序。 +值得注意的是在上面两个方法中的 `for `_ 和 `if `_ 语句的顺序。 -如果想要得到一个元组,必须要加上括号:: +如果想要得到一个元组 (例如,上面例子中的 ``(x, y)``),必须要加上括号:: >>> vec = [-4, -2, 0, 2, 4] >>> # create a new list with the values doubled @@ -278,7 +281,7 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 列表推导式可以嵌套。 -考虑以下的 3x4 矩阵, 一个列表中包含三个长度为4的列表:: +考虑以下的 3x4 矩阵,一个列表中包含三个长度为4的列表:: >>> matrix = [ ... [1, 2, 3, 4], @@ -291,7 +294,7 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 >>> [[row[i] for row in matrix] for i in range(4)] [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] -像前面看到的,嵌套的列表推导式是对 :keyword:`for` 后面的内容进行求值,所以上例就等价于:: +像前面看到的,嵌套的列表推导式是对 `for `_ 后面的内容进行求值,所以上例就等价于:: >>> transposed = [] >>> for i in range(4): @@ -313,7 +316,7 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 >>> transposed [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] -在实际中,你应该更喜欢使用内置函数组成复杂流程语句。 对此种情况 :func:`zip` 函数将会做的更好:: +在实际中,你应该更喜欢使用内置函数组成复杂流程语句。对此种情况 `zip() `_ 函数将会做的更好:: >>> list(zip(*matrix)) [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)] @@ -322,10 +325,10 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 .. _tut-del: -:keyword:`del` 语句 -============================ +`del `_ 语句 +================================================================================== -有个方法可以从列表中按给定的索引而不是值来删除一个子项: :keyword:`del` 语句。它不同于有返回值的 :meth:`pop` 方法。语句 :keyword:`del` 还可以从列表中删除切片或清空整个列表(我们以前介绍过一个方法是将空列表赋值给列表的切片)。例如:: +有个方法可以从列表中按给定的索引而不是值来删除一个子项:`del `_ 语句。它不同于有返回值的 :meth:`pop` 方法。语句 `del `_ 还可以从列表中删除切片或清空整个列表(我们以前介绍过一个方法是将空列表赋值给列表的切片)。例如:: >>> a = [-1, 1, 66.25, 333, 333, 1234.5] >>> del a[0] @@ -338,11 +341,11 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 >>> a [] -:keyword:`del` 也可以删除整个变量:: +`del `_ 也可以删除整个变量:: >>> del a -此后再引用命名 ``a`` 会引发错误(直到另一个值赋给它为止)。我们在后面的内容中可以看到 :keyword:`del` 的其它用法。 +此后再引用命名 ``a`` 会引发错误(直到另一个值赋给它为止)。我们在后面的内容中可以看到 `del `_ 的其它用法。 .. _tut-tuples: @@ -350,7 +353,7 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 元组和序列 ==================== -我们知道链表和字符串有很多通用的属性,例如索引和切割操作。它们是 序列 类型(参见 :ref:`typesseq` )中的两种。因为 Python 是一个在不断进化的语言,也可能会加入其它的序列类型,这里介绍另一种标准序列类型: *元组* 。 +我们知道链表和字符串有很多通用的属性,例如索引和切割操作。它们是序列类型(参见 `Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange `_ )中的两种。因为 Python 是一个在不断进化的语言,也可能会加入其它的序列类型,这里介绍另一种标准序列类型:*元组*。 一个元组由数个逗号分隔的值组成,例如:: @@ -374,11 +377,11 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 ([1, 2, 3], [3, 2, 1]) -如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可以有或没有括号,不过经常括号都是必须的(如果元组是一个更大的表达式的一部分)。不能给元组的一个独立的元素赋值(尽管你可以通过联接和切割来模拟)。还可以创建包含可变对象的元组,例如链表。 +如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可以有或没有括号,不过经常括号都是必须的(如果元组是一个更大的表达式的一部分)。不能给元组的一个独立的元素赋值(尽管你可以通过联接和切割来模拟)。还可以创建包含可变对象的元组,例如链表。 -虽然元组和列表很类似,它们经常被用来在不同的情况和不同的用途。元组有很多用途。例如 (x, y) 坐标对,数据库中的员工记录等等。元组就像字符串,不可改变。 +虽然元组看起来类似于列表,它们经常用于不同的场景和不同的目的。元组是 `不可变的 `_,通常包含不同种类的元素并通过分拆(参阅本节后面的内容)或索引访问(如果是 `namedtuples `_,甚至可以通过属性)。列表是 `可变的 `_,它们的元素通常是相同的类型并通过迭代访问。 -一个特殊的问题是构造包含零个或一个元素的元组:为了适应这种情况,语法上有一些额外的改变。一对空的括号可以创建空元组;要创建一个单元素元组可以在值后面跟一个逗号(在括号中放入一个单值不够明确)。丑陋,但是有效。例如:: +一个特殊的问题是构造包含零个或一个元素的元组:为了适应这种情况,语法上有一些额外的改变。一对空的括号可以创建空元组;要创建一个单元素元组可以在值后面跟一个逗号(在括号中放入一个单值不够明确)。丑陋,但是有效。例如:: >>> empty = () >>> singleton = 'hello', # <-- note trailing comma @@ -389,11 +392,11 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 >>> singleton ('hello',) -语句 ``t = 12345, 54321, 'hello!'`` 是 *元组封装* (tuple packing)的一个例子:值 ``12345`` , ``54321`` 和 ``'hello!'`` 被封装进元组。其逆操作可能是这样:: +语句 ``t = 12345, 54321, 'hello!'`` 是 *元组封装* (tuple packing)的一个例子:值 ``12345`` , ``54321`` 和 ``'hello!'`` 被封装进元组。其逆操作可能是这样:: >>> x, y, z = t -这个调用等号右边可以是任何线性序列,称之为 *序列拆封* 非常恰当。序列拆封要求左侧的变量数目与序列的元素个数相同。要注意的是可变参数(multiple assignment )其实只是元组封装和序列拆封的一个结合。 +这个调用等号右边可以是任何线性序列,称之为 *序列拆封* 非常恰当。序列拆封要求左侧的变量数目与序列的元素个数相同。要注意的是可变参数(multiple assignment)其实只是元组封装和序列拆封的一个结合。 .. _tut-sets: @@ -401,9 +404,9 @@ Python 的列表数据类型包含更多的方法。 这里是所有的列表对 集合 ==== -Python 还包含了一个数据类型 *set* (集合) 。集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。集合对象还支持 union(联合),intersection(交),difference(差)和 sysmmetric difference(对称差集)等数学运算。 +Python 还包含了一个数据类型 *set* (集合)。集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。集合对象还支持 union(联合),intersection(交),difference(差)和 sysmmetric difference(对称差集)等数学运算。 -大括号或 :func:`set` 函数可以用来创建集合。 注意:想要创建空集合,你必须使用 ``set()`` 而不是 ``{}`` 。后者用于创建空字典,我们在下一节中介绍的一种数据结构。 +大括号或 `set() `_ 函数可以用来创建集合。注意:想要创建空集合,你必须使用 ``set()`` 而不是 ``{}``。后者用于创建空字典,我们在下一节中介绍的一种数据结构。 以下是一个简单的演示:: @@ -431,7 +434,7 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 >>> a ^ b # letters in a or b but not both set(['r', 'd', 'b', 'm', 'z', 'l']) -类似 :ref:`for lists ` ,这里有一种集合推导式语法:: +类似 :ref:`列表推导式 `,这里有一种集合推导式语法:: >>> a = {x for x in 'abracadabra' if x not in 'abc'} >>> a @@ -444,13 +447,13 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 字典 ============ -另一个非常有用的 Python 内建数据类型是 *字典* (参见 :ref:`typesmapping` )。字典在某些语言中可能称为 联合内存 ( associative memories )或 联合数组 ( associative arrays )。序列是以连续的整数为索引,与此不同的是,字典以 *关键字* 为索引,关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字符串和数字,它可以作为关键字,如果它直接或间接地包含了可变对象,就不能当做关键字。不能用链表做关键字,因为链表可以用索引、切割或者 :meth:`append` 和 :meth:`extend` 等方法改变。 +另一个非常有用的 Python 内建数据类型是 *字典* (参见 `Mapping Types — dict `_ )。字典在某些语言中可能称为 联合内存 (associative memories) 或 联合数组 (associative arrays)。序列是以连续的整数为索引,与此不同的是,字典以 *关键字* 为索引,关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字符串和数字,它可以作为关键字,如果它直接或间接地包含了可变对象,就不能当做关键字。不能用链表做关键字,因为链表可以用索引、切割或者 :meth:`append` 和 :meth:`extend` 等方法改变。 -理解字典的最佳方式是把它看做无序的键: *值对* (key:value pairs)集合,键必须是互不相同的(在同一个字典之内)。一对大括号创建一个空的字典: ``{}`` 。初始化链表时,在大括号内放置一组逗号分隔的键:值对,这也是字典输出的方式。 +理解字典的最佳方式是把它看做无序的键:*值对* (key:value 对)集合,键必须是互不相同的(在同一个字典之内)。一对大括号创建一个空的字典:``{}``。初始化链表时,在大括号内放置一组逗号分隔的键:值对,这也是字典输出的方式。 -字典的主要操作是依据键来存储和析取值。也可以用 ``del`` 来删除键:值对(key:value)。如果你用一个已经存在的关键字存储值,以前为该关键字分配的值就会被遗忘。试图从一个不存在的键中取值会导致错误。 +字典的主要操作是依据键来存储和析取值。也可以用 ``del`` 来删除键:值对(key:value)。如果你用一个已经存在的关键字存储值,以前为该关键字分配的值就会被遗忘。试图从一个不存在的键中取值会导致错误。 -对一个字典执行 :meth:`keys` 将返回一个字典中所有关键字组成的无序列表(如果你想要排序,只需使用 :func:`sorted`)。使用 :keyword:`in` 关键字(指 Python 语法)可以检查字典中是否存在某个关键字(指字典)。 +对一个字典执行 :meth:`keys` 将返回一个字典中所有关键字组成的无序列表(如果你想要排序,只需使用 `sorted() `_)。使用 `in `_ 关键字(指 Python 语法)可以检查字典中是否存在某个关键字(指字典)。 这里是使用字典的一个小示例:: @@ -469,7 +472,7 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 >>> 'guido' in tel True -:func:`dict` 构造函数可以直接从 key-value 对中创建字典:: +`dict() `_ 构造函数可以直接从 key-value 对中创建字典:: >>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'jack': 4098, 'guido': 4127} @@ -490,7 +493,7 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 循环技巧 ================== -在序列中循环时,索引位置和对应值可以使用 :func:`enumerate` 函数同时得到:: +在序列中循环时,索引位置和对应值可以使用 `enumerate() `_ 函数同时得到:: >>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print(i, v) @@ -499,7 +502,7 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 1 tac 2 toe -同时循环两个或更多的序列,可以使用 :func:`zip` 整体打包:: +同时循环两个或更多的序列,可以使用 `zip() `_ 整体打包:: >>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] @@ -510,7 +513,7 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 What is your quest? It is the holy grail. What is your favorite color? It is blue. -需要逆向循环序列的话,先正向定位序列,然后调用 :func:`reversed` 函数:: +需要逆向循环序列的话,先正向定位序列,然后调用 `reversed() `_ 函数:: >>> for i in reversed(xrange(1, 10, 2)): ... print(i) @@ -521,7 +524,7 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 3 1 -要按排序后的顺序循环序列的话,使用 :func:`sorted` 函数,它不改动原序列,而是生成一个新的已排序的序列:: +要按排序后的顺序循环序列的话,使用 `sorted() `_ 函数,它不改动原序列,而是生成一个新的已排序的序列:: >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for f in sorted(set(basket)): @@ -532,6 +535,25 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 orange pear +遍历字典时,使用 ``iteritems()`` 方法可以同时得到键和对应的值。:: + + >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} + >>> for k, v in knights.iteritems(): + ... print k, v + ... + gallahad the pure + robin the brave + +若要在循环内部修改正在遍历的序列(例如复制某些元素),建议您首先制作副本。在序列上循环不会隐式地创建副本。切片表示法使这尤其方便:: + + >>> words = ['cat', 'window', 'defenestrate'] + >>> for w in words[:]: # Loop over a slice copy of the entire list. + ... if len(w) > 6: + ... words.insert(0, w) + ... + >>> words + ['defenestrate', 'cat', 'window', 'defenestrate'] + .. _tut-conditions: @@ -544,11 +566,11 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 比较操作可以传递。例如 ``a < b == c`` 判断是否 ``a`` 小于 ``b`` 并且 ``b`` 等于 ``c`` 。 -比较操作可以通过逻辑操作符 ``and`` 和 ``or`` 组合,比较的结果可以用 ``not`` 来取反义。这些操作符的优先级又低于比较操作符,在它们之中,``not`` 具有最高的优先级, ``or`` 优先级最低,所以 ``A and not B or C`` 等于 ``(A and (notB)) or C`` 。当然,括号也可以用于比较表达式。 +比较操作可以通过逻辑操作符 ``and`` 和 ``or`` 组合,比较的结果可以用 ``not`` 来取反义。这些操作符的优先级又低于比较操作符,在它们之中,``not`` 具有最高的优先级,``or`` 优先级最低,所以 ``A and not B or C`` 等于 ``(A and (notB)) or C``。当然,括号也可以用于比较表达式。 -逻辑操作符 ``and`` 和 ``or`` 也称作 短路操作符 :它们的参数从左向右解析,一旦结果可以确定就停止。例如,如果 ``A`` 和 ``C`` 为真而 ``B`` 为假, ``A and B and C`` 不会解析 ``C`` 。作用于一个普通的非逻辑值时,短路操作符的返回值通常是最后一个变量。 +逻辑操作符 ``and`` 和 ``or`` 也称作 短路操作符:它们的参数从左向右解析,一旦结果可以确定就停止。例如,如果 ``A`` 和 ``C`` 为真而 ``B`` 为假,``A and B and C`` 不会解析 ``C``。作用于一个普通的非逻辑值时,短路操作符的返回值通常是最后一个变量。 -可以把比较或其它逻辑表达式的返回值赋给一个变量,例如, :: +可以把比较或其它逻辑表达式的返回值赋给一个变量,例如:: >>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance' >>> non_null = string1 or string2 or string3 @@ -563,7 +585,7 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 比较序列和其它类型 =================================== -序列对象可以与相同类型的其它对象比较。比较操作按 *字典序* 进行:首先比较前两个元素,如果不同,就决定了比较的结果;如果相同,就比较后两个元素,依此类推,直到所有序列都完成比较。如果两个元素本身就是同样类 型的序列,就递归字典序比较。如果两个序列的所有子项都相等,就认为序列相等。如果一个序列是另一个序列的初始子序列,较短的一个序列就小于另一个。字符 串的字典序按照单字符的 ASCII 顺序。下面是同类型序列之间比较的一些例子:: +序列对象可以与相同类型的其它对象比较。比较操作按 *字典序* 进行:首先比较前两个元素,如果不同,就决定了比较的结果;如果相同,就比较后两个元素,依此类推,直到所有序列都完成比较。如果两个元素本身就是同样类型的序列,就递归字典序比较。如果两个序列的所有子项都相等,就认为序列相等。如果一个序列是另一个序列的初始子序列,较短的一个序列就小于另一个。字符串的字典序按照单字符的 ASCII 顺序。下面是同类型序列之间比较的一些例子:: (1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] @@ -573,4 +595,9 @@ Python 还包含了一个数据类型 *set* (集合) 。集合是一个无 (1, 2, 3) == (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) -需要注意的是如果通过 ``<`` 或者 ``>`` 比较的对象只要具有合适的比较方法就是合法的。 比如,混合数值类型是通过它们的数值就行比较的,所以0是等于0.0。 否则解释器将会触发一个 :exc:`TypeError` 异常,而不是提供一个随意的结果。 \ No newline at end of file +注意比较不同类型的对象也是合法的。比较的结果已经确定但是不一定合理: 类型按其名称进行排序。因此,列表始终小于字符串,字符串总是小于元组,等等。[#]_ 不同数值类型按照它们的值比较,所以 0 等于 0.0,等等。 + + +.. rubric:: Footnotes + +.. [#] 不应该依赖不同类型对象的比较规则;它们在Python未来版本中可能发生变化。 \ No newline at end of file diff --git a/docs/html/_sources/errors.txt b/docs/html/_sources/errors.txt new file mode 100644 index 0000000..3913120 --- /dev/null +++ b/docs/html/_sources/errors.txt @@ -0,0 +1,317 @@ +.. _tut-errors: + +********************* +错误和异常 +********************* + +至今为止还没有进一步的谈论过错误信息,不过在你已经试验过的那些例子中,可能已经遇到过一些。Python 中(至少)有两种错误:语法错误和异常( *syntax errors* 和 *exceptions* )。 + + +.. _tut-syntaxerrors: + +语法错误 +============= + +语法错误,也被称作解析错误,也许是你学习 Python 过程中最常见抱怨:: + + >>> while True print 'Hello world' + File "", line 1, in ? + while True print 'Hello world' + ^ + SyntaxError: invalid syntax + +语法分析器指出错误行,并且在检测到错误的位置前面显示一个小“箭头”。错误是由箭头 *前面* 的标记引起的(或者至少是这么检测的):这个例子中,关键字 `print `_ 被发现存在错误,因为它前面少了一个冒号( ``':'`` )。错误会输出文件名和行号,所以如果是从脚本输入的你就知道去哪里检查错误了。 + + +.. _tut-exceptions: + +异常 +========== + +即使一条语句或表达式在语法上是正确的,当试图执行它时也可能会引发错误。运行期检测到的错误称为 *异常*,并且程序不会无条件的崩溃:很快,你将学到如何在 Python 程序中处理它们。然而,大多数异常都不会被程序处理,像这里展示的一样最终会产生一个错误信息:: + + >>> 10 * (1/0) + Traceback (most recent call last): + File "", line 1, in ? + ZeroDivisionError: integer division or modulo by zero + >>> 4 + spam*3 + Traceback (most recent call last): + File "", line 1, in ? + NameError: name 'spam' is not defined + >>> '2' + 2 + Traceback (most recent call last): + File "", line 1, in ? + TypeError: cannot concatenate 'str' and 'int' objects + +错误信息的最后一行指出发生了什么错误。异常也有不同的类型,异常类型做为错误信息的一部分显示出来:示例中的异常分别为 除错误( `ZeroDivisionError `_ ),命名错误( `NameError `_ )和类型错误( `TypeError `_ )。打印错误信息时,异常的类型作为异常的内置名显示。对于所有的内置异常都是如此,不过用户自定义异常就不一定了(尽管这是一个很有用的约定)。标准异常名是内置的标识(没有保留关键字)。 + +这一行后一部分是关于该异常类型的详细说明,这意味着它的内容依赖于异常类型。 + +错误信息的前半部分以堆栈的形式列出异常发生的位置。通常在堆栈中列出了源代码行,然而,来自标准输入的源码不会显示出来。 + +`Built-in Exceptions `_ 列出了内置异常和它们的含义。 + + +.. _tut-handling: + +异常处理 +=================== + +通过编程处理选择的异常是可行的。看一下下面的例子:它会一直要求用户输入,直到输入一个合法的整数为止,但允许用户中断这个程序(使用 :kbd:`Control-C` 或系统支持的任何方法)。注意:用户产生的中断会引发一个 `KeyboardInterrupt `_ 异常:: + + >>> while True: + ... try: + ... x = int(raw_input("Please enter a number: ")) + ... break + ... except ValueError: + ... print "Oops! That was no valid number. Try again..." + ... + +`try `_ 语句按如下方式工作: + +* 首先,执行 *try* 子句(在 `try `_ 和 `except `_ 关键字之间的部分)。 + +* 如果没有异常发生,*except* 子句在 `try `_ 语句执行完毕后就被忽略了。 + +* 如果在 try 子句执行过程中发生了异常,那么该子句其余的部分就会被忽略。 + + 如果异常匹配于 `except `_ 关键字后面指定的异常类型, + + 就执行对应的 `except `_ 子句。 + + 然后继续执行 `try `_ 语句之后的代码。 + +* 如果发生了一个异常,在 `except `_ 子句中没有与之匹配的分支, + + 它就会传递到上一级 `try `_ 语句中。 + + 如果最终仍找不到对应的处理语句,它就成为一个 *未处理异常*,终止程序运行,显示提示信息。 + +一个 `try `_ 语句可能包含多个 except 子句,分别指定处理不同的异常。至多只会有一个分支被执行。异常处理程序只会处理对应的 try 子句中发生的异常,在同一个 `try `_ 语句中,其他子句中发生的异常则不作处理。一个 except 子句可以在括号中列出多个异常的名字,例如:: + + ... except (RuntimeError, TypeError, NameError): + ... pass + +注意,此元组周围的括号是必需的,因为 ``except ValueError, e:`` 是旧式的写法,在现代 Python 中通常写成 ``except ValueError, e:`` (如下所述)。为了保持向后兼容性,旧式语法仍然是支持的。这意味着 ``except RuntimeError, TypeError`` 不等同于 ``except (RuntimeError, TypeError):`` 而等同于 ``except RuntimeError as +TypeError:`` , 这应该不是你想要的。 + +最后一个 except 子句可以省略异常名称,以作为通配符使用。你需要慎用此法,因为它会轻易隐藏一个实际的程序错误!可以使用这种方法打印一条错误信息,然后重新抛出异常(允许调用者处理这个异常):: + + import sys + + try: + f = open('myfile.txt') + s = f.readline() + i = int(s.strip()) + except IOError as e: + print "I/O error({0}): {1}".format(e.errno, e.strerror) + except ValueError: + print "Could not convert data to an integer." + except: + print "Unexpected error:", sys.exc_info()[0] + raise + +`try `_ ... `except `_ 语句可以带有一个 *else子句* ,该子句只能出现在所有 except 子句之后。当 try 语句没有抛出异常时,需要执行一些代码,可以使用这个子句。例如 :: + + for arg in sys.argv[1:]: + try: + f = open(arg, 'r') + except IOError: + print 'cannot open', arg + else: + print arg, 'has', len(f.readlines()), 'lines' + f.close() + +使用 `else `_ 子句比在 `try `_ 子句中附加代码要好,因为这样可以避免 `try `_ ... `except `_ 意外的截获本来不属于它们保护的那些代码抛出的异常。 + +发生异常时,可能会有一个附属值,作为异常的 *参数* 存在。这个参数是否存在、是什么类型,依赖于异常的类型。 + +在异常名(列表)之后,也可以为 except 子句指定一个变量。这个变量绑定于一个异常实例,它存储在 ``instance.args`` 的参数中。为了方便起见,异常实例定义了 `__str__() `_ ,这样就可以直接访问过打印参数而不必引用 ``.args``。这种做法不受鼓励。相反,更好的做法是给异常传递一个参数(如果要传递多个参数,可以传递一个元组),把它绑定到 message 属性。一旦异常发生,它会在抛出前绑定所有指定的属性:: + + >>> try: + ... raise Exception('spam', 'eggs') + ... except Exception as inst: + ... print type(inst) # the exception instance + ... print inst.args # arguments stored in .args + ... print inst # __str__ allows args to be printed directly + ... x, y = inst.args + ... print 'x =', x + ... print 'y =', y + ... + + ('spam', 'eggs') + ('spam', 'eggs') + x = spam + y = eggs + +对于那些未处理的异常,如果一个它们带有参数,那么就会被作为异常信息的最后部分(“详情”)打印出来。 + +异常处理器不仅仅处理那些在 try 子句中立刻发生的异常,也会处理那些 try 子句中调用的函数内部发生的异常。例如:: + + >>> def this_fails(): + ... x = 1/0 + ... + >>> try: + ... this_fails() + ... except ZeroDivisionError as detail: + ... print 'Handling run-time error:', detail + ... + Handling run-time error: int division or modulo by zero + + +.. _tut-raising: + +抛出异常 +================== + +`raise `_ 语句允许程序员强制抛出一个指定的异常。例如:: + + >>> raise NameError('HiThere') + Traceback (most recent call last): + File "", line 1, in ? + NameError: HiThere + +要抛出的异常由 `raise `_ 的唯一参数标识。它必需是一个异常实例或异常类(继承自 :class:`Exception` 的类)。 + +如果你需要明确一个异常是否抛出,但不想处理它,`raise `_ 语句可以让你很简单的重新抛出该异常:: + + >>> try: + ... raise NameError('HiThere') + ... except NameError: + ... print 'An exception flew by!' + ... raise + ... + An exception flew by! + Traceback (most recent call last): + File "", line 2, in ? + NameError: HiThere + + +.. _tut-userexceptions: + +用户自定义异常 +======================= + +在程序中可以通过创建新的异常类型来命名自己的异常(Python 类的内容请参见 :ref:`tut-classes` )。异常类通常应该直接或间接的从 `Exception `_ 类派生,例如:: + + >>> class MyError(Exception): + ... def __init__(self, value): + ... self.value = value + ... def __str__(self): + ... return repr(self.value) + ... + >>> try: + ... raise MyError(2*2) + ... except MyError as e: + ... print 'My exception occurred, value:', e.value + ... + My exception occurred, value: 4 + >>> raise MyError('oops!') + Traceback (most recent call last): + File "", line 1, in ? + __main__.MyError: 'oops!' + +在这个例子中,:class:`Exception` 默认的 `__init__() `_ 被覆盖。新的方式简单的创建 *value* 属性。这就替换了原来创建 *args* 属性的方式。 + +异常类中可以定义任何其它类中可以定义的东西,但是通常为了保持简单,只在其中加入几个属性信息,以供异常处理句柄提取。如果一个新创建的模块中需要抛出几种不同的错误时,一个通常的作法是为该模块定义一个异常基类,然后针对不同的错误类型派生出对应的异常子类:: + + class Error(Exception): + """Base class for exceptions in this module.""" + pass + + class InputError(Error): + """Exception raised for errors in the input. + + Attributes: + expr -- input expression in which the error occurred + msg -- explanation of the error + """ + + def __init__(self, expr, msg): + self.expr = expr + self.msg = msg + + class TransitionError(Error): + """Raised when an operation attempts a state transition that's not + allowed. + + Attributes: + prev -- state at beginning of transition + next -- attempted new state + msg -- explanation of why the specific transition is not allowed + """ + + def __init__(self, prev, next, msg): + self.prev = prev + self.next = next + self.msg = msg + +与标准异常相似,大多数异常的命名都以 “Error” 结尾。 + +很多标准模块中都定义了自己的异常,用以报告在他们所定义的函数中可能发生的错误。关于类的进一步信息请参见 :ref:`tut-classes` 一章。 + + +.. _tut-cleanup: + +定义清理行为 +========================= + +`try `_ 语句还有另一个可选的子句,目的在于定义在任何情况下都一定要执行的功能。例如:: + + >>> try: + ... raise KeyboardInterrupt + ... finally: + ... print 'Goodbye, world!' + ... + Goodbye, world! + Traceback (most recent call last): + File "", line 2, in ? + KeyboardInterrupt + +不管有没有发生异常,*finally子句* 在程序离开 `try `_ 后都一定会被执行。当 `try `_ 语句中发生了未被 `except `_ 捕获的异常(或者它发生在 `except `_ 或 `else `_ 子句中),在 `finally `_ 子句执行完后它会被重新抛出。`try `_ 语句经由 `break `_,`continue `_ 或 `return `_ 语句退出也一样会执行 `finally `_ 子句。以下是一个更复杂些的例子(在同 一个 `try `_ 语句中的 `except `_ 和 `finally `_ 子句的工作方式与 Python 2.5 一样):: + + >>> def divide(x, y): + ... try: + ... result = x / y + ... except ZeroDivisionError: + ... print "division by zero!" + ... else: + ... print "result is", result + ... finally: + ... print "executing finally clause" + ... + >>> divide(2, 1) + result is 2 + executing finally clause + >>> divide(2, 0) + division by zero! + executing finally clause + >>> divide("2", "1") + executing finally clause + Traceback (most recent call last): + File "", line 1, in ? + File "", line 3, in divide + TypeError: unsupported operand type(s) for /: 'str' and 'str' + +如你所见,`finally `_ 子句在任何情况下都会执行。`TypeError `_ 在两个字符串相除的时候抛出,未被 except 子句捕获,因此在 `finally `_ 子句执行完毕后重新抛出。 + +在真实场景的应用程序中,`finally `_ 子句用于释放外部资源(文件或网络连接之类的),无论它们的使用过程中是否出错。 + + +.. _tut-cleanup-with: + +预定义清理行为 +=========================== + +有些对象定义了标准的清理行为,无论对象操作是否成功,不再需要该对象的时候就会起作用。以下示例尝试打开文件并把内容打印到屏幕上:: + + for line in open("myfile.txt"): + print line + +这段代码的问题在于在代码执行完后没有立即关闭打开的文件。这在简单的脚本里没什么,但是大型应用程序就会出问题。`with `_ 语句使得文件之类的对象可以确保总能及时准确地进行清理:: + + with open("myfile.txt") as f: + for line in f: + print line + +语句执行后,文件 *f* 总会被关闭,即使是在处理文件中的数据时出错也一样。其它对象是否提供了预定义的清理行为要查看它们的文档。 \ No newline at end of file diff --git a/docs/html/_sources/floatingpoint.txt b/docs/html/_sources/floatingpoint.txt new file mode 100644 index 0000000..8044ab3 --- /dev/null +++ b/docs/html/_sources/floatingpoint.txt @@ -0,0 +1,155 @@ +.. _tut-fp-issues: + +************************************************** +浮点数算法:争议和限制 +************************************************** + +.. sectionauthor:: Tim Peters + + +浮点数在计算机中表达为二进制(binary)小数。例如:十进制小数:: + + 0.125 + +是 1/10 + 2/100 + 5/1000 的值,同样二进制小数:: + + 0.001 + +是 0/2 + 0/4 + 1/8。这两个数值相同。唯一的实质区别是第一个写为十进制小数记法,第二个是二进制。 + +遗憾的是,大多数十进制小数不能精确的表达二进制小数。 + +这个问题更早的时候首先在十进制中发现。考虑小数形式的 1/3,你可以来个十进制的近似值:: + + 0.3 + +或者更进一步的:: + + 0.33 + +或者更进一步的:: + + 0.333 + +诸如此类。如果你写多少位,这个结果永远不是精确的 1/3,但是可以无限接近 1/3。 + +同样,无论在二进制中写多少位,十进制数 0.1 都不能精确表达为二进制小数。二进制来表达 1/10 是一个无限循环小数:: + + 0.0001100110011001100110011001100110011001100110011... + +在任意无限位数值中中止,你可以得到一个近似值。 + +在一个典型的机器上运行 Python,一共有 53 位的精度来表示一个浮点数,所以当你输入十进制的 ``0.1`` 的时候,看到是一个二进制的小数:: + + 0.00011001100110011001100110011001100110011001100110011010 + +非常接近,但是不完全等于, 1/10. + +这是很容易忘记,存储的值是一个近似的原小数,由于浮体的方式,显示在提示符的解释。Python 中只打印一个小数近似的真实机器所存储的二进制近似的十进制值。如果 Python +要打印存储的二进制近似真实的十进制值 0.1,那就要显示:: + + >>> 0.1 + 0.1000000000000000055511151231257827021181583404541015625 + +这么多位的数字对大多数人是没有用的,所以 Python 显示一个舍入的值:: + + >>> 0.1 + 0.1 + +认识到这个幻觉的真相很重要:机器不能精确表达 1/10,你可以简单的截断显示真正的机器值。这里还有另一个惊奇之处。例如,下面:: + + >>> 0.1 + 0.2 + 0.30000000000000004 + +需要注意的是这在二进制浮点数是非常自然的:它不是 Python 的 bug,也不是你的代码的 bug。你会看到只要你的硬件支持浮点数算法,所有的语言都会有这个现象(尽管有些语言可能默认或完全不 *显示* 这个差异)。 + +还有其它意想不到的。例如,如果你舍入2.675到两位小数,你得到的是:: + + >>> round(2.675, 2) + 2.67 + +内置 `round() `_ 函数的文档说它舍入到最接近的值。因为小数 2.675 正好是 2.67 和 2.68 的中间,你可能期望这里的结果是(二进制近似为) 2.68。但是不是的,因为当十进制字符串 2.675 转换为一个二进制浮点数时,它仍然被替换为一个二进制的近似值,其确切的值是:: + + 2.67499999999999982236431605997495353221893310546875 + +因为这个近似值稍微接近 2.67 而不是 2.68,所以向下舍入。 + +如果你的情况需要考虑十进制的中位数是如何被舍入的,你应该考虑使用 `decimal `_ 模块。顺便说一下,`decimal `_ 模块还提供了很好的方式可以“看到”任何 Python 浮点数的精确值:: + + >>> from decimal import Decimal + >>> Decimal(2.675) + Decimal('2.67499999999999982236431605997495353221893310546875') + +这个问题在于存储 “0.1” 的浮点值已经达到 1/10 的最佳精度了,所以尝试截断它不能改善:它已经尽可能的好了。另一个影响是因为 0.1 不能精确的表达 1/10,对 10 个 0.1 的值求和不能精确的得到 1.0,即:: + + >>> sum = 0.0 + >>> for i in range(10): + ... sum += 0.1 + ... + >>> sum + 0.9999999999999999 + +浮点数据算法产生了很多诸如此类的怪异现象。在 “表现错误” 一节中,这个 “0.1” 问题详细表达了精度问题。更完整的其它常见的怪异现象请参见 `浮点数危害 `_ 。 最后我要说,“没有简单的答案”。还是不要过度的敌视浮点数! + +Python 浮点数操作的错误来自于浮点数硬件,大多数机器上同类的问题每次计算误差不超过 2\*\*53 分之一。对于大多数任务这已经足够让人满意了。但是你要在心中记住这不是十进制算法,每个浮点数计算可能会带来一个新的精度错误。 + +问题已经存在了,对于大多数偶发的浮点数错误,你应该比对最终显示结果是否符合你的期待。`str() `_ 通常够用了,完全的控制参见 `字符串格式化 `_ 中 `str.format `_ 方法的格式化方式。 + + +.. _tut-fp-error: + +表达错误 +==================== + +这一节详细说明 “0.1” 示例,教你怎样自己去精确地分析此类案例。假设这里你已经对浮点数表示有基本的了解。 + +:dfn:`Representation error` 提及事实上有些(实际是大多数)十进制小数不能精确的表示为二进制小数。这是 Python (或 Perl,C,C++,Java,Fortran 以及其它很多)语言往往不能按你期待的样子显示十进制数值的根本原因:: + + >>> 0.1 + 0.2 + 0.30000000000000004 + +这 是为什么?1/10 不能精确的表示为二进制小数。大多数今天的机器(2000 年十一月)使用 IEEE-754 浮点数算法,大多数平台上 Python 将浮点数映射为 IEEE-754 “双精度浮点数”。754 双精度包含 53 位精度,所以计算机努力将输入的 0.1 转为 J/2**N 最接近的二进制小数。*J* 是一个 53 位的整数。改写:: + + 1 / 10 ~= J / (2**N) + +为:: + + J ~= 2**N / 10 + +*J* 重现时正是 53 位(是 ``>= 2**52`` 而非 ``< 2**53``),*N* 的最佳值是 56:: + + >>> 2**52 + 4503599627370496 + >>> 2**53 + 9007199254740992 + >>> 2**56/10 + 7205759403792793 + +因此,56 是保持 J 精度的唯一 *N* 值。*J* 最好的近似值是整除的商:: + + >>> q, r = divmod(2**56, 10) + >>> r + 6 + +因为余数大于 10 的一半,最好的近似是取上界:: + + >>> q+1 + 7205759403792794 + +因此在 754 双精度中 1/10 最好的近似值是是 2\*\*56,或:: + + 7205759403792794 / 72057594037927936 + +要注意因为我们向上舍入,它其实比 1/10 稍大一点点。如果我们没有向上舍入,它会比 1/10 稍小一点。但是没办法让它恰好是 1/10! + +所以计算机永远也不 “知道” 1/10:它遇到上面这个小数,给出它所能得到的最佳的 754 双精度实数:: + + >>> .1 * 2**56 + 7205759403792794.0 + +如果我们用 10**30 除这个小数,会看到它最大30位(截断后的)的十进制值:: + + >>> 7205759403792794 * 10**30 // 2**56 + 100000000000000005551115123125L + +这表示存储在计算机中的实际值近似等于十进制值 0.100000000000000005551115123125。Python 显示时取 17 位精度为 0。10000000000000001(是的,在任何符合 754 的平台上,都会由其C库转换为这个最佳近似——你的可能不一样!)。 \ No newline at end of file diff --git a/docs/html/_sources/index.txt b/docs/html/_sources/index.txt new file mode 100644 index 0000000..f3b0bfd --- /dev/null +++ b/docs/html/_sources/index.txt @@ -0,0 +1,43 @@ +.. _tutorial-index: + +###################### +Python 入门指南 +###################### + +:Release: |version| +:Date: |today| + +Python 是一门简单易学且功能强大的编程语言。它拥有高效的高级数据结构,并且能够用简单而又高效的方式进行面向对象编程。Python 优雅的语法和动态类型,再结合它的解释性,使其在大多数平台的许多领域中成为编写脚本或开发应用程序的理想语言。 + +你可以自由的从 Python 官方点: http://www.python.org,以源代码或二进制形式获取 Python 解释器及其标准扩展库,并可以自由的分发。此站点同时也提供了大量的第三方 Python 模块、程序和工具,及其附加文档。 + +你可以很容易的使用 C 或 C++(其它可以通过 C 调用的语言)为 Python 解释器扩展新函数和数据类型。 Python 还可以被用作定制应用程序的一门扩展语言。 + +本手册非正式的向读者介绍了 Python 语言及其体系相关的基本知识与概念。在学习实践中结合使用 Python 解释器是很有帮助的,不过所有的例子都是完整的,所以本手册亦可离线阅读。 + +如果需要了解相关标准库或对象的详细介绍,请查阅 `Python 参考文档 `_ 。`Python 参考手册 `_ 提供了更多语言相关的正式说明。如果想要使用 C 或 C++ 编写扩展,请查阅 `Python 解释器扩展和集成章节 `_ 和 `C API 参考手册 `_ 。当然也可阅读一些深入介绍 Python 知识的书籍。 + +本手册不会尝试涵盖 Python 的全部知识和每个特性,甚至不会涵盖所有常用的特性。相反的,它介绍了 Python 中许多最引人瞩目的特性,并且会给你一个关于语言特色和风格的认识。 读完之后,你将能够阅读和编写 Python 模块或程序,并为以后使用 +`Python 参考手册 `_ 继续学习诸多 Python 模块库做好准备。 + + +`词汇表 `_ 也值得浏览一下。 + +.. toctree:: + :numbered: + + appetite.rst + interpreter.rst + introduction.rst + controlflow.rst + datastructures.rst + modules.rst + inputoutput.rst + errors.rst + classes.rst + stdlib.rst + stdlib2.rst + whatnow.rst + interactive.rst + floatingpoint.rst + appendix.rst diff --git a/docs/html/_sources/inputoutput.txt b/docs/html/_sources/inputoutput.txt new file mode 100644 index 0000000..b8cc296 --- /dev/null +++ b/docs/html/_sources/inputoutput.txt @@ -0,0 +1,310 @@ +.. _tut-io: + +**************** +输入和输出 +**************** + +一个程序可以有几种输出方式:以人类可读的方式打印数据,或者写入一个文件供以后使用。本章将讨论几种可能性。 + + +.. _tut-formatting: + +格式化输出 +========================= + +我们有两种大相径庭的输出值方法:表达式语句和 `print `_ 语句。(第三种方法是使用文件对象的 :meth:`write` 方法,标准文件输出可以参考 ``sys.stdout``,详细内容参见库参考手册。) + +通常,你想要对输出做更多的格式控制,而不是简单的打印使用空格分隔的值。有两种方法可以格式化你的输出:第一种方法是由你自己处理整个字符串,通过使用字符串切割和连接操作可以创建任何你想要的输出形式。string 类型包含一些将字符串填充到指定列宽度的有用操作,随后就会讨论这些。第二种方法是使用 `str.format() `_ 方法。 + +标准模块 `string `_ 包括了一些操作,将字符串填充入给定列时,这些操作很有用。随后我们会讨论这部分内容。第二种方法是使用 `Template `_ 方法。 + +当然,还有一个问题,如何将值转化为字符串?很幸运,Python 有办法将任意值转为字符串:将它传入 `repr() `_ 或 `str() `_ 函数。 + +函数 `str() `_ 用于将值转化为适于人阅读的形式,而 `repr() `_ 转化为供解释器读取的形式(如果没有等价的语法,则会发生 `SyntaxError `_ 异常)某对象没有适于人阅读的解释形式的话,`str() `_ 会返回与 `repr() `_ 等同的值。很多类型,诸如数值或链表、字典这样的结构,针对各函数都有着统一的解读方式。字符串和浮点数,有着独特的解读方式。 + +下面有些例子:: + + >>> s = 'Hello, world.' + >>> str(s) + 'Hello, world.' + >>> repr(s) + "'Hello, world.'" + >>> str(1/7) + '0.14285714285714285' + >>> x = 10 * 3.25 + >>> y = 200 * 200 + >>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...' + >>> print s + The value of x is 32.5, and y is 40000... + >>> # The repr() of a string adds string quotes and backslashes: + ... hello = 'hello, world\n' + >>> hellos = repr(hello) + >>> print hellos + 'hello, world\n' + >>> # The argument to repr() may be any Python object: + ... repr((x, y, ('spam', 'eggs'))) + "(32.5, 40000, ('spam', 'eggs'))" + +有两种方式可以写平方和立方表:: + + >>> for x in range(1, 11): + ... print repr(x).rjust(2), repr(x*x).rjust(3) + ... # Note use of 'end' on previous line + ... print repr(x*x*x).rjust(4) + ... + 1 1 1 + 2 4 8 + 3 9 27 + 4 16 64 + 5 25 125 + 6 36 216 + 7 49 343 + 8 64 512 + 9 81 729 + 10 100 1000 + + >>> for x in range(1, 11): + ... print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x) + ... + 1 1 1 + 2 4 8 + 3 9 27 + 4 16 64 + 5 25 125 + 6 36 216 + 7 49 343 + 8 64 512 + 9 81 729 + 10 100 1000 + +(注意第一个例子,`print `_ 在每列之间加了一个空格,它总是在参数间加入空格。) + +以上是一个 `str.rjust() `_ 方法的演示,它把字符串输出到一列,并通过向左侧填充空格来使其右对齐。类似的方法还有 `str.ljust() `_ 和 `str.center() `_。这些函数只是输出新的字符串,并不改变什么。如果输出的字符串太长,它们也不会截断它,而是原样输出,这会使你的输出格式变得混乱,不过总强过另一种选择(截断字符串),因为那样会产生错误的输出值(如果你确实需要截断它,可以使用切割操作,例如:``x.ljust(n)[:n]``)。 + +还有另一个方法,`str.zfill() `_ 它用于向数值的字符串表达左侧填充 0。该函数可以正确理解正负号:: + + >>> '12'.zfill(5) + '00012' + >>> '-3.14'.zfill(7) + '-003.14' + >>> '3.14159265359'.zfill(5) + '3.14159265359' + +方法 `str.format() `_ 的基本用法如下:: + + >>> print 'We are the {} who say "{}!"'.format('knights', 'Ni') + We are the knights who say "Ni!" + +大括号和其中的字符会被替换成传入 `str.format() `_ 的参数。大括号中的数值指明使用传入 `str.format() `_ 方法的对象中的哪一个:: + + >>> print '{0} and {1}'.format('spam', 'eggs') + spam and eggs + >>> print '{1} and {0}'.format('spam', 'eggs') + eggs and spam + +如果在 `str.format() `_ 调用时使用关键字参数,可以通过参数名来引用值:: + + >>> print 'This {food} is {adjective}.'.format( + ... food='spam', adjective='absolutely horrible') + This spam is absolutely horrible. + +定位和关键字参数可以组合使用:: + + >>> print 'The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', + other='Georg') + The story of Bill, Manfred, and Georg. + +``'!s'`` (应用 `str() `_ )和 ``'!r'`` (应用 `repr() `_)可以在格式化之前转换值:: + + >>> import math + >>> print 'The value of PI is approximately {}.'.format(math.pi) + The value of PI is approximately 3.14159265359. + >>> print 'The value of PI is approximately {!r}.'.format(math.pi) + The value of PI is approximately 3.141592653589793. + +字段名后允许可选的 ``':'`` 和格式指令。这允许对值的格式化加以更深入的控制。下例将 Pi 转为三位精度。 + + >>> import math + >>> print('The value of PI is approximately {0:.3f}.'.format(math.pi)) + The value of PI is approximately 3.142. + +在字段后的 ``':'`` 后面加一个整数会限定该字段的最小宽度,这在美化表格时很有用:: + + >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} + >>> for name, phone in table.items(): + ... print '{0:10} ==> {1:10d}'.format(name, phone) + ... + Jack ==> 4098 + Dcab ==> 7678 + Sjoerd ==> 4127 + +如果你有个实在是很长的格式化字符串,不想分割它。如果你可以用命名来引用被格式化的变量而不是位置就好了。有个简单的方法,可以传入一个字典,用中括号( ``'[]'`` )访问它的键:: + + >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} + >>> print 'Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; ' + 'Dcab: {0[Dcab]:d}'.format(table) + Jack: 4098; Sjoerd: 4127; Dcab: 8637678 + +也可以用 ‘**’ 标志将这个字典以关键字参数的方式传入:: + + >>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678} + >>> print 'Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table) + Jack: 4098; Sjoerd: 4127; Dcab: 8637678 + +这种方式与新的内置函数 `vars() `_ 组合使用非常有效。该函数返回包含所有局部变量的字典。 + +要进一步了解字符串格式化方法 `str.format() `_,参见 `Format String Syntax `_。 + + +旧式的字符串格式化 +--------------------- + +操作符 ``%`` 也可以用于字符串格式化。它以类似 :c:func:`sprintf`\ -style 的方式解析左参数,将右参数应用于此,得到格式化操作生成的字符串,例如:: + + >>> import math + >>> print 'The value of PI is approximately %5.3f.' % math.pi + The value of PI is approximately 3.142. + + +进一步的信息可以参见 `String Formatting Operations `_ 一节。 + + +.. _tut-files: + +文件读写 +========================= + +.. index:: + builtin: open + object: file + +函数 `open() `_ 返回文件对象,通常的用法需要两个参数:``open(filename, mode)``。 + +:: + + >>> f = open('workfile', 'w') + >>> print f + + +第一个参数是一个标识文件名的字符串。第二个参数是由有限的字母组成的字符串,描述了文件将会被如何使用。可选的 *模式* 有:``'r'``,此选项使文件只读;``'w'``,此选项使文件只写(对于同名文件,该操作使原有文件被覆盖);``'a'``,此选项以追加方式打开文件;``'r+'``,此选项以读写方式打开文件;模式参数是可选的。如果没有指定,默认为 ``'r'`` 模式。 + +在 Windows 平台上,``'b'`` 模式以二进制方式打开文件,所以可能会有类似于 ``'rb'``, ``'wb'``, ``'r+b'`` 等等模式组合。Windows 平台上文本文件与二进制文件是有区别的,读写文本文件时,行尾会自动添加行结束符。这种后台操作方式对 ASCII 文本文件没有什么问题,但是操作 :file:`JPEG` 或 :file:`EXE` 这样的二进制文件时就会产生破坏。在操作这些文件时一定要记得以二进制模式打开。在 Unix 上,加一个 ``'b'`` 模式也一样是无害的,所以你可以一切二进制文件处理中平台无关的使用它。 + + +.. _tut-filemethods: + +文件对象方法 +----------------------- + +本节中的示例都默认文件对象 ``f`` 已经创建。 + +要读取文件内容,需要调用 ``f.read(size)``,该方法读取若干数量的数据并以字符串形式返回其内容,*size* 是可选的数值,指定字符串长度。如果没有指定 *size* 或者指定为负数,就会读取并返回整个文件。当文件大小为当前机器内存两倍时,就会产生问题。反之,会尽可能按比较大的 *size* 读取和返回数据。如果到了文件末尾,``f.read()`` 会返回一个空字符串( ``”“`` ):: + + >>> f.read() + 'This is the entire file.\n' + >>> f.read() + '' + +``f.readline()`` 从文件中读取单独一行,字符串结尾会自动加上一个换行符( ``\n`` ),只有当文件最后一行没有以换行符结尾时,这一操作才会被忽略。这样返回值就不会有混淆,如果如果 ``f.readline()`` 返回一个空字符串,那就表示到达了文件末尾,如果是一个空行,就会描述为 ``'\n'``,一个只包含换行符的字符串:: + + >>> f.readline() + 'This is the first line of the file.\n' + >>> f.readline() + 'Second line of the file\n' + >>> f.readline() + '' + +``f.readlines()`` 返回一个列表,其中包含了文件中所有的数据行。如果给定了 *sizehint* 参数,就会读入多于一行的比特数,从中返回多行文本。这个功能通常用于高效读取大型行文件,避免了将整个文件读入内存。这种操作只返回完整的行。 +:: + + >>> f.readlines() + ['This is the first line of the file.\n', 'Second line of the file\n'] + +一种替代的方法是通过遍历文件对象来读取文件行。这是一种内存高效、快速,并且代码简洁的方式:: + + >>> for line in f: + ... print(line, end='') + ... + This is the first line of the file. + Second line of the file + +虽然这种替代方法更简单,但并不具备细节控制能力。因为这两种方法处理行缓存的方式不同,千万不能搞混。 + +``f.write(string)`` 方法将 string 的内容写入文件,并返回写入字符的长度:: + + >>> f.write('This is a test\n') + 15 + +想要写入其他非字符串内容,首先要将它转换为字符串:: + + >>> value = ('the answer', 42) + >>> s = str(value) + >>> f.write(s) + 18 + +``f.tell()`` 返回一个整数,代表文件对象在文件中的指针位置,该数值计量了自文件开头到指针处的比特数。需要改变文件对象指针话话,使用 ``f.seek(offset,from_what)``。指针在该操作中从指定的引用位置移动 *offset* 比特,引用位置由 *from_what* 参数指定。 *from_what* 值为 0 表示自文件起始处开始,1 表示自当前文件指针位置开始,2 表示自文件末尾开始。*from_what* 可以忽略,其默认值为零,此时从文件头开始:: + + >>> f = open('workfile', 'r+') + >>> f.write('0123456789abcdef') + >>> f.seek(5) # Go to the 6th byte in the file + >>> f.read(1) + '5' + >>> f.seek(-3, 2) # Go to the 3rd byte before the end + >>> f.read(1) + 'd' + +在文本文件中(那些没有使用 ``b`` 模式选项打开的文件),只允许从文件头开始计算相对位置(使用 ``seek(0, 2)`` 从文件尾计算时就会引发异常)。 + +当你使用完一个文件时,调用 ``f.close()`` 方法就可以关闭它并释放其占用的所有系统资源。在调用 ``f.close()`` 方法后,试图再次使用文件对象将会自动失败:: + + >>> f.close() + >>> f.read() + Traceback (most recent call last): + File "", line 1, in ? + ValueError: I/O operation on closed file + +用关键字 `with `_ 处理文件对象是个好习惯。它的先进之处在于文件用完后会自动关闭,就算发生异常也没关系。它是 `try `_\ -\ `finally `_ 块的简写:: + + >>> with open('/tmp/workfile', 'r') as f: + ... read_data = f.read() + >>> f.closed + True + +文件对象还有一些不太常用的附加方法,比如 `isatty() `_ 和 `truncate() `_ 在库参考手册中有文件对象的完整指南。 + + +.. _tut-json: + +使用 `json `_ 存储结构化数据 +------------------------------------------------------------------------------------------ + +.. index:: module: json + + +从文件中读写字符串很容易。数值就要多费点儿周折,因为 :meth:`read` 方法只会返回字符串,应将其传入 `int() `_ 这样的函数,就可以将 ``'123'`` 这样的字符串转换为对应的数值 123。当你想要保存更为复杂的数据类型,例如嵌套的列表和字典,手工解析和序列化它们将变得更复杂。 + +好在用户不是非得自己编写和调试保存复杂数据类型的代码,Python 允许你使用常用的数据交换格式 `JSON(JavaScript Object Notation) `_。标准模块 `json `_ 可以接受 Python 数据结构,并将它们转换为字符串表示形式;此过程称为 **序列化**。从字符串表示形式重新构建数据结构称为 **反序列化**。序列化和反序列化的过程中,表示该对象的字符串可以存储在文件或数据中,也可以通过网络连接传送给远程的机器。 + +.. note:: + JSON 格式经常用于现代应用程序中进行数据交换。许多程序员都已经熟悉它了,使它成为相互协作的一个不错的选择。 + +如果你有一个对象 ``x``,你可以用简单的一行代码查看其 JSON 字符串表示形式:: + + >>> json.dumps([1, 'simple', 'list']) + '[1, "simple", "list"]' + +`dumps() `_ 函数的另外一个变体 `dump() `_,直接将对象序列化到一个文件。所以如果 ``f`` 是为写入而打开的一个 `文件对象 `_,我们可以这样做:: + + json.dump(x, f) + +为了重新解码对象,如果f是为读取而打开的 `文件对象 `_:: + + x = json.load(f) + +这种简单的序列化技术可以处理列表和字典,但序列化任意类实例为 JSON 需要一点额外的努力。 `json `_ 模块的手册对此有详细的解释。 + +.. seealso:: + + `pickle `_ - pickle 模块 + + 与 :ref:`JSON ` 不同,*pickle* 是一个协议,它允许任意复杂的 Python 对象的序列化。因此,它只能用于 Python 而不能用来与其他语言编写的应用程序进行通信。默认情况下它也是不安全的:如果数据由熟练的攻击者精心设计, 反序列化来自一个不受信任源的 pickle 数据可以执行任意代码。 diff --git a/html/_sources/interactive.txt b/docs/html/_sources/interactive.txt similarity index 61% rename from html/_sources/interactive.txt rename to docs/html/_sources/interactive.txt index 2053555..bb835c0 100644 --- a/html/_sources/interactive.txt +++ b/docs/html/_sources/interactive.txt @@ -5,9 +5,9 @@ 交互式输入行编辑历史回溯 ************************************************** -有些版本的 Python 解释器支持输入行编辑和历史回溯,类似 Korn shell 和 GNU bash shell 的功能。这是通过 `GNU Readline`_ 库实现的。它支持 Emacs 风格和 vi 风格的编辑。这个库有它自己的文档,在此不重复了。不过,基本的东西很容易演示。交互式编辑和历史查阅在 Unix 和 Cygwin 版中是可选项。 +有些版本的 Python 解释器支持输入行编辑和历史回溯,类似 Korn shell 和 GNU bash shell 的功能。这是通过 `GNU Readline `_ 库实现的。它支持 Emacs 风格和 vi 风格的编辑。这个库有它自己的文档,在此不重复了。不过,基本的东西很容易演示。交互式编辑和历史查阅在 Unix 和 Cygwin 版中是可选项。 -本章 *不是* 马克哈密尔顿的 PythonWin 包和随 Python 发布的基于 TK 的 IDLE 环境的文档。 NT 系统和其它 DOS、Windows 系统上的 DOS 窗中的命令行历史回调,属于另一个话题。 +本章 *不是* 马克哈密尔顿的 PythonWin 包和随 Python 发布的基于 TK 的 IDLE 环境的文档。NT 系统和其它 DOS、Windows 系统上的 DOS 窗中的命令行历史回调,属于另一个话题。 .. _tut-lineediting: @@ -15,7 +15,7 @@ 行编辑 ============ -如果支持,无论解释器打印主提示符或从属提示符,行编辑都会激活。当前行可以用 Emacs 风格的快捷键编辑。其中最重要的是: :kbd:`C-A` (Control-A)将光标移动到行首, :kbd:`C-E` 移动到行尾, :kbd:`C-B` 向左移一个字符, :kbd:`C-F` 向右移一位。退格向左删除一个符串, :kbd:`C-D` 向右删除一个字符。 :kbd:`C-K` 删掉光标右边直到行尾的所有字符, :kbd:`C-Y` 将最后一次删除的字符串粘贴到光标位置。 :kbd:`C-underscore` (underscores 即下划线,译注)撤销最后一次修改,它可以因积累作用重复。 +如果支持,无论解释器打印主提示符或从属提示符,行编辑都会激活。当前行可以用 Emacs 风格的快捷键编辑。其中最重要的是::kbd:`C-A` (Control-A)将光标移动到行首,:kbd:`C-E` 移动到行尾,:kbd:`C-B` 向左移一个字符,:kbd:`C-F` 向右移一位。退格向左删除一个符串,:kbd:`C-D` 向右删除一个字符。:kbd:`C-K` 删掉光标右边直到行尾的所有字符,:kbd:`C-Y` 将最后一次删除的字符串粘贴到光标位置。:kbd:`C-underscore` (underscores 即下划线,译注)撤销最后一次修改,它可以因积累作用重复。 .. _tut-history: @@ -23,7 +23,7 @@ 历史回溯 ==================== -历史代替可以工作。所有非空的输入行都被保存在历史缓存中,获得一个新的提示符的时候,你处于这个缓存的最底的空行。 :kbd:`C-P` 在历史缓存中上溯一行, :kbd:`C-N` 向下移一行。历史缓存中的任一行都可以编辑;按下 :kbd:`Return` 键时将当前行传入解释器。 :kbd:`C-R` 开始一个增量向前搜索;:kbd:`C-S` 开始一个向后搜索。 +历史代替可以工作。所有非空的输入行都被保存在历史缓存中,获得一个新的提示符的时候,你处于这个缓存的最底的空行。:kbd:`C-P` 在历史缓存中上溯一行,:kbd:`C-N` 向下移一行。历史缓存中的任一行都可以编辑;按下 :kbd:`Return` 键时将当前行传入解释器。:kbd:`C-R` 开始一个增量向前搜索;:kbd:`C-S` 开始一个向后搜索。 .. _tut-keybindings: @@ -31,7 +31,7 @@ 快捷键绑定 ============ -Readline 库的快捷键绑定和其它一些参数可以通过名为 :file:`~/.inputrc` 的初始化文件的替换命名来定制。快捷键绑定如下形式:: +Readline 库的快捷键绑定和其它一些参数可以通过名为 :file:`~/.inputrc` 的初始化文件的替换命名来定制。快捷键绑定如下形式:: key-name: function-name @@ -60,7 +60,7 @@ Readline 库的快捷键绑定和其它一些参数可以通过名为 :file:`~/. Tab: complete -到你的 :file:`~/.inputrc` 中来覆盖它。(当然,如果你真的把 :kbd:`Tab` 设置成这样,就很难在后继行中插入缩进。) +到你的 :file:`~/.inputrc` 中来覆盖它(当然,如果你真的把 :kbd:`Tab` 设置成这样,就很难在后继行中插入缩进。)。 .. index:: module: rlcompleter @@ -71,9 +71,9 @@ Readline 库的快捷键绑定和其它一些参数可以通过名为 :file:`~/. import rlcompleter, readline readline.parse_and_bind('tab: complete') -这个操作将 :kbd:`Tab` 绑定到完成函数,故按 Tab 键两次会给出建议的完成内容;它查找 Python 命名、当前的局部变量、有效的模块名。对于类似 ``string.a`` 这样的文件名,它会解析 ``'.'`` 相关的表达式,从返回的结果对象中获取属性,以提供完成建议。需要注意的是,如果对象的 :meth:`__getattr__` 方法是此表达式的一部分,这可能会执行应用程序定义代码。 +这个操作将 :kbd:`Tab` 绑定到完成函数,故按 Tab 键两次会给出建议的完成内容;它查找 Python 命名、当前的局部变量、有效的模块名。对于类似 ``string.a`` 这样的文件名,它会解析 ``'.'`` 相关的表达式,从返回的结果对象中获取属性,以提供完成建议。需要注意的是,如果对象的 `__getattr__() `_ 方法是此表达式的一部分,这可能会执行应用程序定义代码。 -更有用的初始化文件可能是下面这个例子这样的。要注意一旦创建的名字没用了,它会删掉它们;因为初始化文件作为解释命令与之在同一个命名空间执行,在交互环境中删除命名带来了边际效应。可能你发现了它体贴的保留了一些导入模块,类似 :mod:`os` ,在解释器的大多数使用场合中都会用到它们。 :: +更有用的初始化文件可能是下面这个例子这样的。要注意一旦创建的名字没用了,它会删掉它们;因为初始化文件作为解释命令与之在同一个命名空间执行,在交互环境中删除命名带来了边际效应。可能你发现了它体贴的保留了一些导入模块,类似 `os `_ ,在解释器的大多数使用场合中都会用到它们:: # Add auto-completion and a stored history file of commands to your Python # interactive interpreter. Requires Python 2.0+, readline. Autocomplete is @@ -105,15 +105,14 @@ Readline 库的快捷键绑定和其它一些参数可以通过名为 :file:`~/. 其它交互式解释器 =========================================== -跟早先版本的解释器比,现在已经有了很大的进步。不过,还是有些期待没有完成:它应该在后继行中优美的提供缩进(解释器知道下一行是否需要缩进)建议。完成机制可以使用解释器的符号表。命名检查(或进一步建议)匹配括号、引号等等。 +跟早先版本的解释器比,现在已经有了很大的进步。不过,还是有些期待没有完成:它应该在后继行中优美的提供缩进(解释器知道下一行是否需要缩进)建议。完成机制可以使用解释器的符号表。命名检查(或进一步建议)匹配括号、引号等等。 另有一个强化交互式解释器已经存在一段时间了,它就是 IPython_,它支持 tab 完成,对象浏览和高级历史管理。它也可以完全定制或嵌入到其它应用程序中。另一个类似的强化交互环境是 bpython_ 。 .. rubric:: Footnotes -.. [#] 启动交互解释器时,Python 可以执行 :envvar:`PYTHONSTARTUP` 环境变量所指定的文件内容。 +.. [#] 启动交互解释器时,Python 可以执行 `PYTHONSTARTUP `_ 环境变量所指定的文件内容。若还要定制化非交互式的 Python,请参阅 `定制化模块 `_。 -.. _GNU Readline: http://tiswww.case.edu/php/chet/readline/rltop.html .. _IPython: http://ipython.scipy.org/ .. _bpython: http://www.bpython-interpreter.org/ \ No newline at end of file diff --git a/docs/html/_sources/interpreter.txt b/docs/html/_sources/interpreter.txt new file mode 100644 index 0000000..ab3853d --- /dev/null +++ b/docs/html/_sources/interpreter.txt @@ -0,0 +1,101 @@ +.. _tut-using: + +**************************** +使用 Python 解释器 +**************************** + + +.. _tut-invoking: + +调用 Python 解释器 +======================== + +Python 解释器通常被安装在目标机器的 :file:`/usr/local/bin/python` 目录下。将 :file:`/usr/local/bin` 目录包含进 Unix shell 的搜索路径里,以确保可以通过输入:: + + python + +命令来启动它。由于 Python 解释器的安装路径是可选的,这也可能是其他路径,你可以联系安装 Python 的用户或系统管理员确认。(例如,:file:`/usr/local/python` 就是一个常见的选择) + +在 Windows 机器上,Python 通常安装在 :file:`C:\\Python27` 位置,当然你可以在运行安装向导时修改此值。要想把此目录添加到你的 PATH 环境变量中,你可以在 DOS 窗口中输入以下命令:: + + set path=%path%;C:\python27 + +通常你可以在主窗口输入一个文件结束符( Unix 系统是 :kbd:`Control-D`,Windows 系统是 :kbd:`Control-Z` )让解释器以 0 状态码退出。如果它不起作用,你可以通过输入 ``quit()`` 命令退出解释器。 + +Python 解释器具有简单的行编辑功能。在 Unix 系统上,任何 Python 解释器都可能已经添加了 GNU readline 库支持,这样就具备了精巧的交互编辑和历史记录等功能。在 Python 主窗口中输入 Control-P 可能是检查是否支持命令行编辑的最简单的方法。如果发出嘟嘟声(计算机扬声器),则说明你可以使用命令行编辑功能;更多快捷键的介绍请参考 :ref:`tut-interacting`。 如果没有任何声音,或者显示 ``^P`` 字符,则说明命令行编辑功能不可用;你只能通过退格键从当前行删除已键入的字符并重新输入。 + +Python 解释器有些操作类似 Unix shell:当使用终端设备(tty)作为标准输入调用时,它交互地解释并执行命令;当使用文件名参数或以文件作为标准输入调用时,它读取文件并将文件作为 *脚本* 执行。 + +第二种启动 Python 解释器的方法是 ``python -c command [arg] ...``,这种方法可以在 *命令行* 执行 Python 语句,类似于 shell 中的 :option:`-c` 选项。由于 Python 语句通常会包含空格或其他特殊 shell 字符,一般建议将 *命令* 用单引号包裹起来。 + +有一些 Python 模块也可以当作脚本使用。你可以使用 ``python -m module [arg] ...`` 命令来调用它们,这类似在命令行中键入完整的路径名执行 *模块* 源文件一样。 + +使用脚本文件时,经常会运行脚本然后进入交互模式。这也可以通过在脚本之前加上 :option:`-i` 参数来实现。 + +所有的命令行参数详细描述在 `命令行和环境 `_ 。 + +.. _tut-argpassing: + +参数传递 +---------------- + +调用解释器时,脚本名和附加参数传入一个名为 ``sys.argv`` 的字符串列表。你能够通过执行 ``import sys`` 来获取这个列表,列表的长度大于等于1;没有给定脚本和参数时,它至少也有一个元素:``sys.argv[0]`` 此时为空字符串。 + +脚本名指定为 ``'-'`` (表示标准输入)时,``sys.argv[0]`` 被设定为 ``'-'`` ,使用 :option:`-c` *指令* 时,``sys.argv[0]`` 被设定为 ``'-c'``。 + +使用 :option:`-m` *模块* 参数时,``sys.argv[0]`` 被设定为指定模块的全名。:option:`-c` *指令* 或者 :option:`-m` *模块* 之后的参数不会被 Python 解释器的选项处理机制所截获,而是留在 ``sys.argv`` 中,供脚本命令操作。 + + +.. _tut-interactive: + +交互模式 +---------------- + +从 tty 读取命令时,我们称解释器工作于 *交互模式*。这种模式下它根据 *主提示符* 来执行,主提示符通常标识为三个大于号 (``>>>``);继续的部分被称为 *从属提示符*,由三个点标识 (``...``)。在第一行之前,解释器打印欢迎信息、版本号和授权提示:: + + python + Python 2.7 (#1, Feb 28 2010, 00:02:06) + Type "help", "copyright", "credits" or "license" for more information. + >>> + +.. XXX update for new releases + +输入多行结构时需要从属提示符了,例如,下面这个 `if `_ 语句:: + + >>> the_world_is_flat = 1 + >>> if the_world_is_flat: + ... print "Be careful not to fall off!" + ... + Be careful not to fall off! + +关于交互魔术更多的信息,请见 :ref:`tut-interacting`。 + + +.. _tut-interp: + +解释器及其环境 +=================================== + + +.. _tut-source-encoding: + +源程序编码 +-------------------- + +在Python源文件中可以使用非 ASCII 编码。最好的方法是在 ``#!`` 行的后面再增加一行特殊的注释来定义源文件的编码:: + + # -*- coding: encoding -*- + + +通过此声明,源文件中所有的东西都会被当做用 *encoding* 指代的 UTF-8 编码对待。在 Python 库参考手册 `codecs `_ 一节中你可以找到一张可用的编码列表。 + +例如,若要写入包含欧元货币符号的 Unicode 字面量,可以使用 ISO-8859-15 编码,其欧元符号的值为 164 。此脚本中,以 ISO-8859-15 编码,保存时将打印的值 8364 (Unicode 代码点相应的欧元符号),然后退出:: + + # -*- coding: iso-8859-15 -*- + + currency = u"€" + print ord(currency) + +如果你的编辑器支持保存为带有 ``UTF-8`` *字节顺序标记* (也叫做 BOM ) 的 UTF-8 格式的文件,你可以使用这种功能而不用编码声明。IDLE 如果设置了 ``Options/General/Default Source Encoding/UTF-8`` 也支持此功能。注意,这种标记方法在旧的 Python 版本中(2.2 及更早)是不能识别的,同样也不能被能够处理 ``#!`` (只在 Unix 系统上使用)行的操作系统识别。 + +通过使用 UTF-8 编码(无论是BOM方式或者是编码声明方式),世界上大多数语言的字符可以在字符串字面量和注释中同时使用。在标识符中使用非 ASCII 字符是不支持的。若要正确显示所有这些字符,您的编辑器必须认识该文件是 UTF-8 编码,并且它必须使用支持文件中所有字符的字体。 \ No newline at end of file diff --git a/docs/html/_sources/introduction.txt b/docs/html/_sources/introduction.txt new file mode 100644 index 0000000..d143595 --- /dev/null +++ b/docs/html/_sources/introduction.txt @@ -0,0 +1,540 @@ +.. _tut-informal: + +********************************** +Python 简介 +********************************** + +下面的例子中,输入和输出分别由大于号和句号提示符 ( ``>>>`` 和 ``...`` ) 标注:如果想重现这些例子,就要在解释器的提示符后,输入 (提示符后面的) 那些不包含提示符的代码行。需要注意的是在练习中遇到的从属提示符表示你需要在最后多输入一个空行,解释器才能知道这是一个多行命令的结束。 + +本手册中的很多示例 (包括那些带有交互提示符的) 都含有注释。Python 中的注释以 ``#`` 字符起始,直至实际的行尾 (译注:这里原作者用了 physical line 以表示实际的换行而非编辑器的自动换行)。注释可以从行首开始,也可以在空白或代码之后,但是不出现在字符串中。文本字符串中的 ``#`` 字符仅仅表示 ``#``。代码中的注释不会被 Python 解释,录入示例的时候可以忽略它们。 + +如下示例:: + + # this is the first comment + SPAM = 1 # and this is the second comment + # ... and now a third! + STRING = "# This is not a comment." + + +.. _tut-calculator: + +将 Python 当做计算器 +============================ + +我们来尝试一些简单的 Python 命令。启动解释器然后等待主提示符 ``>>>`` 出现。(不需要很久) + + +.. _tut-numbers: + +数字 +------- + +解释器表现得就像一个简单的计算器:可以向其录入一些表达式,它会给出返回值。表达式语法很直白:运算符 ``+``,``-``,``*`` 和 ``/`` 与其它语言一样(例如:Pascal 或 C);括号 (``()``) 用于分组。例如:: + + >>> 2 + 2 + 4 + >>> 50 - 5*6 + 20 + >>> (50 - 5.0*6) / 4 + 5.0 + >>> 8 / 5.0 + 1.6 + +整数(例如,``2``, ``4``, ``20`` )的类型是 `int `_,带有小数部分的数字(例如,``5.0``, ``1.6``)的类型是 `float `_。在本教程的后面我们会看到更多关于数字类型的内容。 + +除法 (``/``) 返回的类型取决于它的操作数。如果两个操作数都是 `int `_,将采用 `floor division `_ 除法(floor division)并返回一个 `int `_。如果两个操作数中有一个是 `float `_,将采用传统的除法并返回一个 `float `_。还提供 ``//`` 运算符用于 floor division 而无论操作数是什么类型。余数可以用 ``%`` 操作符计算:: + + >>> 17 / 3 # int / int -> int + 5 + >>> 17 / 3.0 # int / float -> float + 5.666666666666667 + >>> 17 // 3.0 # explicit floor division discards the fractional part + 5.0 + >>> 17 % 3 # the % operator returns the remainder of the division + 2 + >>> 5 * 3 + 2 # result * divisor + remainder + 17 + +通过 Python,还可以使用 ``**`` 运算符计算幂乘方 [#]_:: + + >>> 5 ** 2 # 5 squared + 25 + >>> 2 ** 7 # 2 to the power of 7 + 128 + +等号( ``'='`` )用于给变量赋值。赋值之后,在下一个提示符之前不会有任何结果显示:: + + >>> width = 20 + >>> height = 5*9 + >>> width * height + 900 + +变量在使用前必须 "定义"(赋值),否则会出错:: + + >>> # try to access an undefined variable + ... n + Traceback (most recent call last): + File "", line 1, in + NameError: name 'n' is not defined + +浮点数有完整的支持;与整型混合计算时会自动转为浮点数:: + + >>> 3 * 3.75 / 1.5 + 7.5 + >>> 7.0 / 2 + 3.5 + +交互模式中,最近一个表达式的值赋给变量 ``_``。这样我们就可以把它当作一个桌面计算器,很方便的用于连续计算,例如:: + + >>> tax = 12.5 / 100 + >>> price = 100.50 + >>> price * tax + 12.5625 + >>> price + _ + 113.0625 + >>> round(_, 2) + 113.06 + +此变量对于用户是只读的。不要尝试给它赋值 —— 你只会创建一个独立的同名局部变量,它屏蔽了系统内置变量的魔术效果。 + +除了 `int `_ 和 `float `_,Python 还支持其它数字类型,例如 `Decimal `_ 和 `Fraction `_。Python 还内建支持 `复数 `_ ,使用后缀 ``j`` 或 ``J`` 表示虚数部分(例如,``3+5j``)。 + + +**编者注:下面这一部分的内容在这一版本中已经删除,但是为了让大家更加清楚的了解复数,暂时保留在这里。** + +复数也得到支持;带有后缀 ``j`` 或 ``J`` 就被视为虚数。带有非零实部的复数写为 ``(real+imagj)`` ,或者可以用 ``complex(real, imag)`` 函数创建。 +:: + + >>> 1j * 1J + (-1+0j) + >>> 1j * complex(0, 1) + (-1+0j) + >>> 3+1j*3 + (3+3j) + >>> (3+1j)*3 + (9+3j) + >>> (1+2j)/(1+1j) + (1.5+0.5j) + +复数的实部和虚部总是记为两个浮点数。要从复数 z 中提取实部和虚部,使用 ``z.real`` 和 ``z.imag``:: + + >>> a=1.5+0.5j + >>> a.real + 1.5 + >>> a.imag + 0.5 + +浮点数和整数之间的转换函数 (`float `_ 和 `int `_ 以及 `long `_) 不能用于复数。没有什么正确方法可以把一个复数转成一个实数。函数 ``abs(z)`` 用于获取其模(浮点数)或 ``z.real`` 获取其实部:: + + >>> a=3.0+4.0j + >>> float(a) + Traceback (most recent call last): + File "", line 1, in ? + TypeError: can't convert complex to float; use abs(z) + >>> a.real + 3.0 + >>> a.imag + 4.0 + >>> abs(a) # sqrt(a.real**2 + a.imag**2) + 5.0 + +.. _tut-strings: + +字符串 +------- + +相比数值,Python 也提供了可以通过几种不同方式表示的字符串。它们可以用单引号 (``'...'``) 或双引号 (``"..."``) 标识 [#]_。``\`` 可以用来转义引号:: + + >>> 'spam eggs' # single quotes + 'spam eggs' + >>> 'doesn\'t' # use \' to escape the single quote... + "doesn't" + >>> "doesn't" # ...or use double quotes instead + "doesn't" + >>> '"Yes," he said.' + '"Yes," he said.' + >>> "\"Yes,\" he said." + '"Yes," he said.' + >>> '"Isn\'t," she said.' + '"Isn\'t," she said.' + +在交互式解释器中,输出的字符串会用引号引起来,特殊字符会用反斜杠 (\\) 转义。虽然可能和输入看上去不太一样,但是两个字符串是相等的。如果字符串中只有单引号而没有双引号,就用双引号引用,否则用单引号引用。再强调一下,`print `_ 语句可以生成可读性更好的输出:: + + >>> '"Isn\'t," she said.' + '"Isn\'t," she said.' + >>> print '"Isn\'t," she said.' + "Isn't," she said. + >>> s = 'First line.\nSecond line.' # \n means newline + >>> s # without print, \n is included in the output + 'First line.\nSecond line.' + >>> print s # with print, \n produces a new line + First line. + Second line. + +如果你前面带有 ``\`` 的字符被当作特殊字符,你可以使用 *原始字符串*,方法是在第一个引号前面加上一个 ``r``:: + + >>> print 'C:\some\name' # here \n means newline! + C:\some + ame + >>> print r'C:\some\name' # note the r before the quote + C:\some\name + +字符串文本能够分成多行。一种方法是使用三引号:``"""..."""`` 或者 ``'''...'''``。行尾换行符会被自动包含到字符串中,但是可以在行尾加上 ``\`` 来避免这个行为。下面的示例: +可以使用反斜杠为行结尾的连续字符串,它表示下一行在逻辑上是本行的后续内容:: + + print """\ + Usage: thingy [OPTIONS] + -h Display this usage message + -H hostname Hostname to connect to + """ + +将生成以下输出(注意,没有开始的第一行): + +.. code-block:: text + + Usage: thingy [OPTIONS] + -h Display this usage message + -H hostname Hostname to connect to + +字符串可以由 ``+`` 操作符连接(粘到一起),可以由 ``*`` 表示重复:: + + >>> # 3 times 'un', followed by 'ium' + >>> 3 * 'un' + 'ium' + 'unununium' + +相邻的两个字符串文本自动连接在一起。:: + + >>> 'Py' 'thon' + 'Python' + +它只用于两个字符串文本,不能用于字符串表达式:: + + >>> prefix = 'Py' + >>> prefix 'thon' # can't concatenate a variable and a string literal + ... + SyntaxError: invalid syntax + >>> ('un' * 3) 'ium' + ... + SyntaxError: invalid syntax + +如果你想连接多个变量或者连接一个变量和一个字符串文本,使用 ``+``:: + + >>> prefix + 'thon' + 'Python' + +这个功能在你想切分很长的字符串的时候特别有用:: + + >>> text = ('Put several strings within parentheses ' + 'to have them joined together.') + >>> text + 'Put several strings within parentheses to have them joined together.' + +字符串也可以被截取(检索)。类似于 C ,字符串的第一个字符索引为 0 。Python没有单独的字符类型;一个字符就是一个简单的长度为1的字符串。:: + + >>> word = 'Python' + >>> word[0] # character in position 0 + 'P' + >>> word[5] # character in position 5 + 'n' + +索引也可以是负数,这将导致从右边开始计算。例如:: + + >>> word[-1] # last character + 'n' + >>> word[-2] # second-last character + 'o' + >>> word[-6] + 'P' + +请注意 -0 实际上就是 0,所以它不会导致从右边开始计算。 + +除了索引,还支持 *切片*。索引用于获得单个字符,*切片* 让你获得一个子字符串:: + + >>> word[0:2] # characters from position 0 (included) to 2 (excluded) + 'Py' + >>> word[2:5] # characters from position 2 (included) to 5 (excluded) + 'tho' + +注意,包含起始的字符,不包含末尾的字符。这使得 ``s[:i] + s[i:]`` 永远等于 ``s``:: + + >>> word[:2] + word[2:] + 'Python' + >>> word[:4] + word[4:] + 'Python' + +切片的索引有非常有用的默认值;省略的第一个索引默认为零,省略的第二个索引默认为切片的字符串的大小。:: + + >>> word[:2] # character from the beginning to position 2 (excluded) + 'Py' + >>> word[4:] # characters from position 4 (included) to the end + 'on' + >>> word[-2:] # characters from the second-last (included) to the end + 'on' + +有个办法可以很容易地记住切片的工作方式:切片时的索引是在两个字符 *之间* 。左边第一个字符的索引为 0,而长度为 *n* 的字符串其最后一个字符的右界索引为 *n*。例如:: + + +---+---+---+---+---+---+ + | P | y | t | h | o | n | + +---+---+---+---+---+---+ + 0 1 2 3 4 5 6 + -6 -5 -4 -3 -2 -1 + +文本中的第一行数字给出字符串中的索引点 0...6。第二行给出相应的负索引。切片是从 *i* 到 *j* 两个数值标示的边界之间的所有字符。 + +对于非负索引,如果上下都在边界内,切片长度就是两个索引之差。例如,``word[1:3]`` 是 2 。 + +试图使用太大的索引会导致错误:: + + >>> word[42] # the word only has 6 characters + Traceback (most recent call last): + File "", line 1, in + IndexError: string index out of range + +Python 能够优雅地处理那些没有意义的切片索引:一个过大的索引值(即下标值大于字符串实际长度)将被字符串实际长度所代替,当上边界比下边界大时(即切片左值大于右值)就返回空字符串:: + + >>> word[4:42] + 'on' + >>> word[42:] + '' + +Python字符串不可以被更改 --- 它们是 **不可变** 的。因此,赋值给字符串索引的位置会导致错误:: + + >>> word[0] = 'J' + ... + TypeError: 'str' object does not support item assignment + >>> word[2:] = 'py' + ... + TypeError: 'str' object does not support item assignment + +如果你需要一个不同的字符串,你应该创建一个新的:: + + >>> 'J' + word[1:] + 'Jython' + >>> word[:2] + 'py' + 'Pypy' + +内置函数 `len() `_ 返回字符串长度:: + + >>> s = 'supercalifragilisticexpialidocious' + >>> len(s) + 34 + + +.. seealso:: + + `Sequence Types — str, unicode, list, tuple, bytearray, buffer, xrange `_ + 字符串和下节描述的Unicode字符串是 **序列类型** 的例子,它们支持这种类型共同的操作。 + + `String Methods `_ + 字符串和Unicode字符串都支持大量的方法用于基本的转换和查找。 + + `String Formatting `_ + 这里描述了使用 `str.format() `_ 进行字符串格式化的信息。 + + `String Formatting Operations `_ + 这里描述了旧式的字符串格式化操作,它们在字符串和Unicode字符串是 ``%`` 操作符的左操作数时调用。 + + + +.. _tut-unicodestrings: + +关于 Unicode +------------- + +.. sectionauthor:: Marc-André Lemburg + +从 Python2.0 起,程序员们有了一个新的用来存储文本数据的类型:Unicode 对象。它可以用于存储和维护 Unicode 数据 (参见 http://www.unicode.org/),并且与现有的字符串对象有良好的集成,必要时提供自动转换。 + +Unicode 的先进之处在于为每一种现代或古代使用的文字系统中出现的每一个字符都提供了统一的序列号。之前,文字系统中的字符只能有 256 种可能的顺序。通过代码页分界映射。文本绑定到映射文字系统的代码页。这在软件国际化的时候尤其麻烦(通常写作 ``i18n`` —— ``'i'`` + 18 个字符 + ``'n'``)。Unicode 解决了为所有的文字系统设置一个独立代码页的难题。 + +在 Python 中创建 Unicode 字符串和创建普通的字符串一样简单:: + + >>> u'Hello World !' + u'Hello World !' + +引号前的 ``'u'`` 表示这会创建一个 Unicode 字符串。如果想要在字符串中包含特殊字符,可以使用 Python 的 *Unicode-Escape*。请看下面的例子:: + + >>> u'Hello\u0020World !' + u'Hello World !' + +转码序列 ``\u0020`` 表示在指定位置插入编码为 0x0020 的 Unicode 字符(空格)。 + +其他字符就像 Unicode 编码一样被直接解释为对应的编码值。如果你有在许多西方国家使用的标准 Latin-1 编码的字符串,你会发现编码小于 256 的 Unicode 字符和在 Latin-1 编码中的一样。 + +特别的,和普通字符串一样,Unicode 字符串也有原始模式。可以在引号前加 "ur",Python 会采用 *Raw-Unicode-Escape* 编码(译者:原始 Unicode 转义)。如果有前缀为 'u' 的数值,它也只会显示为 ``uXXXX``:: + + >>> ur'Hello\u0020World !' + u'Hello World !' + >>> ur'Hello\\u0020World !' + u'Hello\\\\u0020World !' + +如果你需要大量输入反斜杠,原始模式非常有用,这在正则表达式中几乎是必须的。 + +作为这些编码标准的一部分,Python 提供了基于已知编码来创建 Unicode 字符串的整套方法。 + + +.. index:: builtin: unicode + +内置函数 `unicode() `_ 可以使用所有注册的 Unicode 编码(COders 和 DECoders)。众所周知,*Latin-1* ,*ASCII* ,*UTF-8* 和 *UTF-16* 之类的编码可以互相转换(译者:Latin-1 表示一个很小的拉丁语言符号集,与 ASCII 基本一致,其实不能用来表示庞大的东方语言字符集)。后两个是变长编码,将每一个 Unicode 字符存储为一到多个字节。通常默认编码为 ASCII,此编码接受 0 到 127 这个范围的编码,否则报错。将一个 Unicode 字符串打印或写入到文件中,或者使用 `str() `_ 转换时,转换操作以此为默认编码:: + + >>> u"abc" + u'abc' + >>> str(u"abc") + 'abc' + >>> u"盲枚眉" + u'\xe4\xf6\xfc' + >>> str(u"盲枚眉") + Traceback (most recent call last): + File "", line 1, in ? + UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128) + +为了将一个 Unicode 字符串转换为一个使用特定编码的 8 位字符串,Unicode 对象提供一个 :func:`encode` 方法,它接受编码名作为参数。编码名应该小写。:: + + >>> u"盲枚眉".encode('utf-8') + '\xc3\xa4\xc3\xb6\xc3\xbc' + +如果有一个其它编码的数据,希望可以从中生成一个 Unicode 字符串,你可以使用 `unicode `_ 函数,它接受编码名作为第二参数:: + + >>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8') + u'\xe4\xf6\xfc' + + +.. _tut-lists: + +列表 +----- + +Python 有几个 *复合* 数据类型,用于表示其它的值。最通用的是 *list* (列表) ,它可以写作中括号之间的一列逗号分隔的值。列表的元素不必是同一类型:: + + >>> squares = [1, 4, 9, 16, 25] + >>> squares + [1, 4, 9, 16, 25] + + >>> a = ['spam', 'eggs', 100, 1234] + >>> a + ['spam', 'eggs', 100, 1234] + +就像字符串一样,列表可以被索引和切片:: + + >>> squares[0] # indexing returns the item + 1 + >>> squares[-1] + 25 + >>> squares[-3:] # slicing returns a new list + [9, 16, 25] + +所有的切片操作都会返回一个包含请求的元素的新列表。这意味着下面的切片操作返回列表一个新的(浅)拷贝副本:: + + >>> squares[:] + [1, 4, 9, 16, 25] + +列表也支持连接这样的操作:: + + >>> squares + [36, 49, 64, 81, 100] + [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] + +不像 *不可变的* 字符串,列表允许修改元素:: + + >>> cubes = [1, 8, 27, 65, 125] # something's wrong here + >>> 4 ** 3 # the cube of 4 is 64, not 65! + 64 + >>> cubes[3] = 64 # replace the wrong value + >>> cubes + [1, 8, 27, 64, 125] + +你还可以使用 ``append()`` 方法(后面我们会看到更多关于列表的方法的内容)在列表的末尾添加新的元素:: + + >>> cubes.append(216) # add the cube of 6 + >>> cubes.append(7 ** 3) # and the cube of 7 + >>> cubes + [1, 8, 27, 64, 125, 216, 343] + +也可以对切片赋值,此操作可以改变列表的尺寸,或清空它:: + + >>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + >>> letters + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + >>> # replace some values + >>> letters[2:5] = ['C', 'D', 'E'] + >>> letters + ['a', 'b', 'C', 'D', 'E', 'f', 'g'] + >>> # now remove them + >>> letters[2:5] = [] + >>> letters + ['a', 'b', 'f', 'g'] + >>> # clear the list by replacing all the elements with an empty list + >>> letters[:] = [] + >>> letters + [] + +内置函数 `len() `_ 同样适用于列表:: + + >>> a = ['a', 'b', 'c', 'd'] + >>> len(a) + 4 + +允许嵌套列表(创建一个包含其它列表的列表),例如:: + + >>> a = ['a', 'b', 'c'] + >>> n = [1, 2, 3] + >>> x = [a, n] + >>> x + [['a', 'b', 'c'], [1, 2, 3]] + >>> x[0] + ['a', 'b', 'c'] + >>> x[0][1] + 'b' + + +.. _tut-firststeps: + +编程的第一步 +=============================== + +当然,我们可以使用 Python 完成比二加二更复杂的任务。例如,我们可以写一个生成 *菲波那契* 子序列的程序,如下所示:: + + >>> # Fibonacci series: + ... # the sum of two elements defines the next + ... a, b = 0, 1 + >>> while b < 10: + ... print b + ... a, b = b, a+b + ... + 1 + 1 + 2 + 3 + 5 + 8 + +这个例子介绍了几个新功能。 + +* 第一行包括了一个 *多重赋值* :变量 ``a`` 和 ``b`` 同时获得了新的值 0 和 1,最后一行又使用了一次。在这个演示中,变量赋值前,右边首先完成计算。右边的表达式从左到右计算。 + +* 条件(这里是 ``b < 10``)为 true 时,`while `_ 循环执行。在 Python 中,类似于 C,任何非零整数都是 true;0 是 false。判断条件也可以是字符串或列表,实际上可以是任何序列;所有长度不为零的是 true,空序列是 false。示例中的测试是一个简单的比较。标准比较操作符与 C 相同:<、>、==、<=、>= 和 !=。 + +* 循环 *体* 是 *缩进* 的:缩进是 Python 组织語句的方法。Python 不提供集成的行编辑功能,所以你要为每一个缩进行输入 TAB 或空格。实践中建议你找个文本编辑来录入复杂的 Python 程序,大多数文本编辑器提供自动缩进。交互式录入复合语句时,必须在最后输入一个空行来标识结束(因为解释器没办法猜测你输入的哪一行是最后一行),需要注意的是同一个语句块中的每一行必须缩进同样数量的空白。 + +* 关键字 `print `_ 语句输出给定表达式的值。它控制多个表达式和字符串输出为你想要字符串(就像我们在前面计算器的例子中那样)。字符串打印时不用引号包围,每两个子项之间插入空间,所以你可以把格式弄得很漂亮,像这样:: + + >>> i = 256*256 + >>> print 'The value of i is', i + The value of i is 65536 + + 用一个逗号结尾就可以禁止输出换行:: + + >>> a, b = 0, 1 + >>> while b < 1000: + ... print b, + ... a, b = b, a+b + ... + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 + + 注意,如果最后一行没有结束,解释器会插入一个新行(在打印下一个提示符之前)。 + +.. rubric:: Footnotes + +.. [#] 因为 ``**`` 的优先级高于 ``-``,所以 ``-3**2`` 将解释为 ``-(3**2)`` 且结果为 ``-9``。为了避免这点并得到 ``9``,你可以使用 ``(-3)**2``。 + + +.. [#] 与其它语言不同,特殊字符例如 ``\n`` 在单引号(``'...'``)和双引号(``"..."``)中具有相同的含义。两者唯一的区别是在单引号中,你不需要转义 ``"`` (但你必须转义 ``\'`` ),反之亦然。 diff --git a/docs/html/_sources/modules.txt b/docs/html/_sources/modules.txt new file mode 100644 index 0000000..8d7c051 --- /dev/null +++ b/docs/html/_sources/modules.txt @@ -0,0 +1,377 @@ +.. _tut-modules: + +******* +模块 +******* + +如果你退出 Python 解释器并重新进入,你做的任何定义(变量和方法)都会丢失。因此,如果你想要编写一些更大的程序,为准备解释器输入使用一个文本编辑器会更好,并以那个文件替代作为输入执行。这就是传说中的 *脚本*。 随着你的程序变得越来越长,你可能想要将它分割成几个更易于维护的文件。你也可能想在不同的程序中使用顺手的函数,而不是把代码在它们之间中拷来拷去。 + +为了满足这些需要,Python 提供了一个方法可以从文件中获取定义,在脚本或者解释器的一个交互式实例中使用。这样的文件被称为 *模块*;模块中的定义可以 *导入* 到另一个模块或 *主模块* 中(在脚本执行时可以调用的变量集位于最高级,并且处于计算器模式)。 + +模块是包括 Python 定义和声明的文件。文件名就是模块名加上 :file:`.py` 后缀。模块的模块名(做为一个字符串)可以由全局变量 ``__name__`` 得到。例如,你可以用自己惯用的文件编辑器在当前目录下创建一个叫 :file:`fibo.py` 的文件,录入如下内容:: + + # Fibonacci numbers module + + def fib(n): # write Fibonacci series up to n + a, b = 0, 1 + while b < n: + print b + a, b = b, a+b + + + def fib2(n): # return Fibonacci series up to n + result = [] + a, b = 0, 1 + while b < n: + result.append(b) + a, b = b, a+b + return result + +现在进入 Python 解释器并使用以下命令导入这个模块:: + + >>> import fibo + +这样做不会直接把 ``fibo`` 中的函数导入当前的语义表;它只是引入了模块名 ``fibo``。你可以通过模块名按如下方式访问这个函数:: + + >>> fibo.fib(1000) + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 + >>> fibo.fib2(100) + [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] + >>> fibo.__name__ + 'fibo' + +如果打算频繁使用一个函数,你可以将它赋予一个本地变量:: + + >>> fib = fibo.fib + >>> fib(500) + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 + + +.. _tut-moremodules: + +深入模块 +=============== + +除了包含函数定义外,模块也可以包含可执行语句。这些语句一般用来初始化模块。它们仅在 *第一次* 被导入的地方执行一次。[#]_ + +每个模块都有自己私有的符号表,被模块内所有的函数定义作为全局符号表使用。因此,模块的作者可以在模块内部使用全局变量,而无需担心它与某个用户的全局变量意外冲突。从另一个方面讲,如果你确切的知道自己在做什么,你可以使用引用模块函数的表示法访问模块的全局变量,``modname.itemname``。 + +模块可以导入其他的模块。一个(好的)习惯是将所有的 `import `_ 语句放在模块的开始(或者是脚本),这并非强制。被导入的模块名会放入当前模块的全局符号表中。 + +`import `_ 语句的一个变体直接从被导入的模块中导入命名到本模块的语义表中。例如:: + + >>> from fibo import fib, fib2 + >>> fib(500) + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 + +这样不会从局域语义表中导入模块名(如上所示,``fibo`` 没有定义)。 + +甚至有种方式可以导入模块中的所有定义:: + + >>> from fibo import * + >>> fib(500) + 1 1 2 3 5 8 13 21 34 55 89 144 233 377 + +这样可以导入所有除了以下划线( ``_`` )开头的命名。 + +需要注意的是在实践中往往不鼓励从一个模块或包中使用 ``*`` 导入所有,因为这样会让代码变得很难读。不过,在交互式会话中这样用很方便省力。 + +.. note:: + + 出于性能考虑,每个模块在每个解释器会话中只导入一遍。因此,如果你修改了你的模块,需要重启解释器或者如果你就是想交互式的测试这么一个模块,可以用 `reload() `_ 重新加载,例如 ``reload(modulename)``。 + + +.. _tut-modulesasscripts: + +作为脚本来执行模块 +---------------------------- + +当你使用以下方式运行 Python 模块时,模块中的代码便会被执行:: + + python fibo.py + +模块中的代码会被执行,就像导入它一样,不过此时 ``__name__`` 被设置为 ``"__main__"``。这相当于,如果你在模块后加入如下代码:: + + if __name__ == "__main__": + import sys + fib(int(sys.argv[1])) + +就可以让此文件像作为模块导入时一样作为脚本执行。此代码只有在模块作为 “main” 文件执行时才被调用:: + + $ python fibo.py 50 + 1 1 2 3 5 8 13 21 34 + +如果模块被导入,不会执行这段代码:: + + >>> import fibo + >>> + +这通常用来为模块提供一个便于测试的用户接口(将模块作为脚本执行测试需求)。 + + +.. _tut-searchpath: + +模块的搜索路径 +---------------------- + +.. index:: triple: module; search; path + +导入一个叫 :mod:`spam` 的模块时,解释器先在当前目录中搜索名为 :file:`spam.py` 的文件。如果没有找到的话,接着会到 `sys.path `_ 变量中给出的目录列表中查找。`sys.path `_ 变量的初始值来自如下: + +* 输入脚本的目录(当前目录)。 + +* 环境变量 `PYTHONPATH `_ 表示的目录列表中搜索 + + (这和 shell 变量 :envvar:`PATH` 具有一样的语法,即一系列目录名的列表)。 + +* Python 默认安装路径中搜索。 + + +实际上,解释器由 `sys.path `_ 变量指定的路径目录搜索模块,该变量初始化时默认包含了输入脚本(或者当前目录),`PYTHONPATH `_ 和安装目录。这样就允许 Python 程序了解如何修改或替换模块搜索目录。需要注意的是由于这些目录中包含有搜索路径中运行的脚本,所以这些脚本不应该和标准模块重名,否则在导入模块时 Python 会尝试把这些脚本当作模块来加载。这通常会引发错误。请参见 :ref:`tut-standardmodules` 以了解更多的信息。 + + + +“编译的” Python 文件 +----------------------- + +对于引用了大量标准模块的短程序,有一个提高启动速度的重要方法,如果在 :file:`spam.py` 所在的目录下存在一个名为 :file:`spam.pyc` 的文件,它会被视为 :mod:`spam` 模块的预“编译”( ``byte-compiled``,二进制编译)版本。用于创建 :file:`spam.pyc` 的这一版 :file:`spam.py` 的修改时间记录在 :file:`spam.pyc` 文件中,如果两者不匹配,:file:`.pyc` 文件就被忽略。 + +通常你不需要为创建 :file:`spam.pyc` 文件做任何工作。一旦 :file:`spam.py` 成功编译,就会尝试生成对应版本的 :file:`spam.pyc` 。如果有任何原因导致写入不成功,生成的 :file:`spam.pyc` 文件就会视为无效,随后即被忽略。:file:`spam.pyc` 文件的内容是平台独立的,所以 Python 模块目录可以在不同架构的机器之间共享。 + +部分高级技巧: + +* 以 `-O `_ 参数调用 Python 解释器时,会生成优化代码并保存在 :file:`.pyo` 文件中。现在的优化器没有太多帮助;它只是删除了断言( `assert `_)语句。使用 `-O `_ 参数,*所有* 的字节码(`bytecode `_)都会被优化;``.pyc`` 文件被忽略,``.py`` 文件被编译为优化代码。 + +* 向 Python 解释器传递两个 `-O `_ 参数(`-OO `_)会执行完全优化的二进制优化编译,这偶尔会生成错误的程序。现在的优化器,只是从字节码中删除了 ``__doc__`` 符串,生成更为紧凑的 :file:`.pyo` 文件。因为某些程序依赖于这些变量的可用性,你应该只在确定无误的场合使用这一选项。 + +* 来自 :file:`.pyc` 文件或 :file:`.pyo` 文件中的程序不会比来自 :file:`.py` 文件的运行更快;:file:`.pyc` 或 :file:`.pyo` 文件只是在它们加载的时候更快一些。 + +* 通过脚本名在命令行运行脚本时,不会将为该脚本创建的二进制代码写入 :file:`.pyc` 或 :file:`.pyo` 文件。当然,把脚本的主要代码移进一个模块里,然后用一个小的启动脚本导入这个模块,就可以提高脚本的启动速度。也可以直接在命令行中指定一个 :file:`.pyc` 或 :file:`.pyo` 文件。 + +* 对于同一个模块(译者:这里指例程 spam.py),可以只有 :file:`spam.pyc` 文件(或者 :file:`spam.pyo`,在使用 `-O `_ 参数时)而没有 :file:`spam.py` 文件。这样可以打包发布比较难于逆向工程的 Python 代码库。 + + .. index:: module: compileall + +* `compileall `_ 模块可以为指定目录中的所有模块创建 :file:`.pyc` 文件(或者使用 `-O `_ 参数创建 :file:`.pyo` 文件)。 + + +.. _tut-standardmodules: + +标准模块 +================ + +.. index:: module: sys + +Python 带有一个标准模块库,并发布有独立的文档,名为 Python 库参考手册(此后称其为“库参考手册”)。有一些模块内置于解释器之中,这些操作的访问接口不是语言内核的一部分,但是已经内置于解释器了。这既是为了提高效率,也是为了给系统调用等操作系统原生访问提供接口。这类模块集合是一个依赖于底层平台的配置选项。例如,:mod:`winreg` 模块只提供在 Windows 系统上才有。有一个具体的模块值得注意:`sys `_,这个模块内置于所有的 Python 解释器。变量 ``sys.ps1`` 和 ``sys.ps2`` 定义了主提示符和辅助提示符字符串:: + + >>> import sys + >>> sys.ps1 + '>>> ' + >>> sys.ps2 + '... ' + >>> sys.ps1 = 'C> ' + C> print 'Yuck!' + Yuck! + C> + + +这两个变量只在解释器的交互模式下有意义。 + +变量 ``sys.path`` 是解释器模块搜索路径的字符串列表。它由环境变量 `PYTHONPATH `_ 初始化,如果没有设定 `PYTHONPATH `_ ,就由内置的默认值初始化。你可以用标准的列表操作修改它:: + + >>> import sys + >>> sys.path.append('/ufs/guido/lib/python') + + +.. _tut-dir: + +`dir() `_ 函数 +====================================================================== + +内置函数 `dir() `_ 用于按模块名搜索模块定义,它返回一个排好序的字符串类型的存储列表:: + + >>> import fibo, sys + >>> dir(fibo) + ['__name__', 'fib', 'fib2'] + >>> dir(sys) # doctest: +NORMALIZE_WHITESPACE + ['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__', + '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', + '_current_frames', '_getframe', '_mercurial', 'api_version', 'argv', + 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', + 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_clear', 'exc_info', + 'exc_traceback', 'exc_type', 'exc_value', 'excepthook', 'exec_prefix', + 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', + 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', + 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', + 'getrefcount', 'getsizeof', 'gettotalrefcount', 'gettrace', 'hexversion', + 'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules', + 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', + 'py3kwarning', 'setcheckinterval', 'setdlopenflags', 'setprofile', + 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', + 'version', 'version_info', 'warnoptions'] + +无参数调用时,`dir() `_ 函数返回当前定义的命名列表:: + + >>> a = [1, 2, 3, 4, 5] + >>> import fibo + >>> fib = fibo.fib + >>> dir() + ['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib', 'fibo', 'sys'] + +注意该列表列出了所有类型的名称:变量,模块,函数,等等。 + +.. index:: module: builtins + +`dir() `_ 不会列出内置函数和变量名。如果你想列出这些内容,它们在标准模块 `__builtin__ `_ 中定义:: + + >>> import __builtin__ + >>> dir(__builtin__) # doctest: +NORMALIZE_WHITESPACE + ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', + 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', + 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', + 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', + 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', + 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', + 'NotImplementedError', 'OSError', 'OverflowError', + 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', + 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', + 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', + 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', + 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', + 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', + 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', + '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', + 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', + 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', + 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', + 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', + 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', + 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', + 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', + 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', + 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', + 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', + 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip'] + +.. _tut-packages: + +包 +======== + +包通常是使用用“圆点模块名”的结构化模块命名空间。例如,名为 :mod:`A.B` 的模块表示了名为 ``A`` 的包中名为 ``B`` 的子模块。正如同用模块来保存不同的模块架构可以避免全局变量之间的相互冲突,使用圆点模块名保存像 NumPy 或 Python Imaging Library 之类的不同类库架构可以避免模块之间的命名冲突。 + +假设你现在想要设计一个模块集(一个“包”)来统一处理声音文件和声音数据。存在几种不同的声音格式(通常由它们的扩展名来标识,例如::file:`.wav`, +:file:`.aiff`, :file:`.au`),于是,为了在不同类型的文件格式之间转换,你需要维护一个不断增长的包集合。可能你还想要对声音数据做很多不同的操作(例如混音,添加回声,应用平衡功能,创建一个人造效果),所以你要加入一个无限流模块来执行这些操作。你的包可能会是这个样子(通过分级的文件体系来进行分组): + +.. code-block:: text + + sound/ Top-level package + __init__.py Initialize the sound package + formats/ Subpackage for file format conversions + __init__.py + wavread.py + wavwrite.py + aiffread.py + aiffwrite.py + auread.py + auwrite.py + ... + effects/ Subpackage for sound effects + __init__.py + echo.py + surround.py + reverse.py + ... + filters/ Subpackage for filters + __init__.py + equalizer.py + vocoder.py + karaoke.py + ... + +当导入这个包时,Python通过 ``sys.path`` 搜索路径查找包含这个包的子目录。 + +为了让 Python 将目录当做内容包,目录中必须包含 :file:`__init__.py` 文件。这是为了避免一个含有烂俗名字的目录无意中隐藏了稍后在模块搜索路径中出现的有效模块,比如 string。最简单的情况下,只需要一个空的 :file:`__init__.py` 文件即可。当然它也可以执行包的初始化代码,或者定义稍后介绍的 ``__all__`` 变量。 + +用户可以每次只导入包里的特定模块,例如:: + + import sound.effects.echo + +这样就导入了 :mod:`sound.effects.echo` 子模块。它必需通过完整的名称来引用:: + + sound.effects.echo.echofilter(input, output, delay=0.7, atten=4) + +导入包时有一个可以选择的方式:: + + from sound.effects import echo + +这样就加载了 :mod:`echo` 子模块,并且使得它在没有包前缀的情况下也可以使用,所以它可以如下方式调用:: + + echo.echofilter(input, output, delay=0.7, atten=4) + +还有另一种变体用于直接导入函数或变量:: + + from sound.effects.echo import echofilter + +这样就又一次加载了 :mod:`echo` 子模块,但这样就可以直接调用它的 :func:`echofilter` 函数:: + + echofilter(input, output, delay=0.7, atten=4) + +需要注意的是使用 ``from package import item`` 方式导入包时,这个子项(item)既可以是包中的一个子模块(或一个子包),也可以是包中定义的其它命名,像函数、类或变量。``import`` 语句首先核对是否包中有这个子项,如果没有,它假定这是一个模块,并尝试加载它。如果没有找到它,会引发一个 `ImportError `_ 异常。 + +相反,使用类似 ``import item.subitem.subsubitem`` 这样的语法时,这些子项必须是包,最后的子项可以是包或模块,但不能是前面子项中定义的类、函数或变量。 + + +.. _tut-pkg-import-star: + +从 \* 导入包 +--------------------------- + +.. index:: single: __all__ + +那么当用户写下 ``from sound.effects import *`` 时会发生什么事?理想中,总是希望在文件系统中找出包中所有的子模块,然后导入它们。这可能会花掉很长时间,并且出现期待之外的边界效应,导出了希望只能显式导入的包。 + +对于包的作者来说唯一的解决方案就是给提供一个明确的包索引。`import `_ 语句按如下条件进行转换:执行 ``from package import *`` 时,如果包中的 :file:`__init__.py` 代码定义了一个名为 ``__all__`` 的列表,就会按照列表中给出的模块名进行导入。新版本的包发布时作者可以任意更新这个列表。如果包作者不想 import \* 的时候导入他们的包中所有模块,那么也可能会决定不支持它(import \*)。例如,:file:`sounds/effects/__init__.py` 这个文件可能包括如下代码:: + + __all__ = ["echo", "surround", "reverse"] + +这意味着 ``from sound.effects import *`` 语句会从 :mod:`sound` 包中导入以上三个已命名的子模块。 + +如果没有定义 ``__all__``,``from sound.effects import *`` 语句 *不会* 从 :mod:`sound.effects` 包中导入所有的子模块。无论包中定义多少命名,只能确定的是导入了 :mod:`sound.effects` 包(可能会运行 :file:`__init__.py` 中的初始化代码)以及包中定义的所有命名会随之导入。这样就从 :file:`__init__.py` 中导入了每一个命名(以及明确导入的子模块)。同样也包括了前述的 `import `_ 语句从包中明确导入的子模块,考虑以下代码:: + + import sound.effects.echo + import sound.effects.surround + from sound.effects import * + +在这个例子中, :mod:`echo` 和 :mod:`surround` 模块导入了当前的命名空间,这是因为执行 ``from...import`` 语句时它们已经定义在 :mod:`sound.effects` 包中了(定义了 ``__all__`` 时也会同样工作)。 + +尽管某些模块设计为使用 ``import *`` 时它只导出符全某种模式的命名,仍然不建议在生产代码中使用这种写法。 + +记住,``from Package import specific_submodule`` 没有错误!事实上,除非导入的模块需要使用其它包中的同名子模块,否则这是推荐的写法。 + + +包内引用 +------------------------ + +如果包中使用了子包结构(就像示例中的 :mod:`sound` 包),可以按绝对位置从相邻的包中引入子模块。例如,如果 :mod:`sound.filters.vocoder` 包需要使用 :mod:`sound.effects` 包中的 :mod:`echo` 模块,它可以 ``from sound.effects import echo``。 + +你可以用这样的形式 ``from module import name`` 来写显式的相对位置导入。那些显式相对导入用点号标明关联导入当前和上级包。以 :mod:`surround` 模块为例,你可以这样用:: + + from . import echo + from .. import formats + from ..filters import equalizer + +需要注意的是显式或隐式相对位置导入都基于当前模块的命名。因为主模块的名字总是 ``"__main__"``,Python 应用程序的主模块应该总是用绝对导入。 + + +多重目录中的包 +-------------------------------- + +包支持一个更为特殊的特性,:attr:`__path__`。在包的 :file:`__init__.py` 文件代码执行之前,该变量初始化一个目录名列表。该变量可以修改,它作用于包中的子包和模块的搜索功能。 + +这个功能可以用于扩展包中的模块集,不过它不常用。 + + +.. rubric:: Footnotes + +.. [#] 事实上函数定义既是“声明”又是“可执行体”;执行体由函数在模块全局语义表中的命名导入。 \ No newline at end of file diff --git a/docs/html/_sources/stdlib.txt b/docs/html/_sources/stdlib.txt new file mode 100644 index 0000000..ed657d6 --- /dev/null +++ b/docs/html/_sources/stdlib.txt @@ -0,0 +1,268 @@ +.. _tut-brieftour: + +********************************** +Python 标准库概览 +********************************** + + +.. _tut-os-interface: + +操作系统接口 +========================== + +`os `_ 模块提供了很多与操作系统交互的函数:: + + >>> import os + >>> os.getcwd() # Return the current working directory + 'C:\\Python27' + >>> os.chdir('/server/accesslogs') # Change current working directory + >>> os.system('mkdir today') # Run the command mkdir in the system shell + 0 + +应该用 ``import os`` 风格而非 ``from os import *``。这样可以保证随操作系统不同而有所变化的 `os.open() `_ 不会覆盖内置函数 `open() `_ + +.. index:: builtin: help + +在使用一些像 `os `_ 这样的大型模块时内置的 `dir() `_ 和 `help() `_ 函数非常有用:: + + >>> import os + >>> dir(os) + + >>> help(os) + + +针对日常的文件和目录管理任务,`shutil `_ 模块提供了一个易于使用的高级接口:: + + >>> import shutil + >>> shutil.copyfile('data.db', 'archive.db') + >>> shutil.move('/build/executables', 'installdir') + + +.. _tut-file-wildcards: + +文件通配符 +============== + +`glob `_ 模块提供了一个函数用于从目录通配符搜索中生成文件列表:: + + >>> import glob + >>> glob.glob('*.py') + ['primes.py', 'random.py', 'quote.py'] + + +.. _tut-command-line-arguments: + +命令行参数 +====================== + +通用工具脚本经常调用命令行参数。这些命令行参数以链表形式存储于 `sys `_ 模块的 *argv* 变量。例如在命令行中执行 ``python demo.py one two three`` 后可以得到以下输出结果:: + + >>> import sys + >>> print sys.argv + ['demo.py', 'one', 'two', 'three'] + +`getopt `_ 模块使用 Unix `getopt() `_ 函数处理 *sys.argv*。更多的复杂命令行处理由 `argparse `_ 模块提供。 + + +.. _tut-stderr: + +错误输出重定向和程序终止 +================================================ + +`sys `_ 还有 *stdin*, *stdout* 和 *stderr* 属性,即使在 *stdout* 被重定向时,后者也可以用于显示警告和错误信息:: + + >>> sys.stderr.write('Warning, log file not found starting a new one\n') + Warning, log file not found starting a new one + +大多脚本的定向终止都使用 ``sys.exit()`` 。 + + +.. _tut-string-pattern-matching: + +字符串正则匹配 +======================= + +`re `_ 模块为高级字符串处理提供了正则表达式工具。对于复杂的匹配和处理,正则表达式提供了简洁、优化的解决方案:: + + >>> import re + >>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest') + ['foot', 'fell', 'fastest'] + >>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat') + 'cat in the hat' + +只需简单的操作时,字符串方法最好用,因为它们易读,又容易调试:: + + >>> 'tea for too'.replace('too', 'two') + 'tea for two' + + +.. _tut-mathematics: + +数学 +=========== + +`math `_ 模块为浮点运算提供了对底层 C 函数库的访问:: + + >>> import math + >>> math.cos(math.pi / 4.0) + 0.70710678118654757 + >>> math.log(1024, 2) + 10.0 + +`random `_ 提供了生成随机数的工具:: + + >>> import random + >>> random.choice(['apple', 'pear', 'banana']) + 'apple' + >>> random.sample(xrange(100), 10) # sampling without replacement + [30, 83, 16, 4, 8, 81, 41, 50, 18, 33] + >>> random.random() # random float + 0.17970987693706186 + >>> random.randrange(6) # random integer chosen from range(6) + 4 + + +.. _tut-internet-access: + +互联网访问 +=============== + +有几个模块用于访问互联网以及处理网络通信协议。其中最简单的两个是用于处理从 urls 接收的数据的 `urllib2 `_ 以及用于发送电子邮件的 `smtplib `_:: + + >>> import urllib2 + >>> for line in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): + ... line = line.decode('utf-8') # Decoding the binary data to text. + ... if 'EST' in line or 'EDT' in line: # look for Eastern Time + ... print line + +
Nov. 25, 09:43:32 PM EST + + >>> import smtplib + >>> server = smtplib.SMTP('localhost') + >>> server.sendmail('soothsayer@example.org', 'jcaesar@example.org', + ... """To: jcaesar@example.org + ... From: soothsayer@example.org + ... + ... Beware the Ides of March. + ... """) + >>> server.quit() + +(注意第二个例子需要在 localhost 运行一个邮件服务器。) + + +.. _tut-dates-and-times: + +日期和时间 +=============== + +`datetime `_ 模块为日期和时间处理同时提供了简单和复杂的方法。支持日期和时间算法的同时,实现的重点放在更有效的处理和格式化输出。该模块还支持时区处理:: + + >>> # dates are easily constructed and formatted + >>> from datetime import date + >>> now = date.today() + >>> now + datetime.date(2003, 12, 2) + >>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") + '12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.' + + >>> # dates support calendar arithmetic + >>> birthday = date(1964, 7, 31) + >>> age = now - birthday + >>> age.days + 14368 + + +.. _tut-data-compression: + +数据压缩 +================ + +以下模块直接支持通用的数据打包和压缩格式:`zlib `_,`gzip `_,`bz2 `_,`zipfile `_ 以及 +`tarfile `_:: + + >>> import zlib + >>> s = b'witch which has which witches wrist watch' + >>> len(s) + 41 + >>> t = zlib.compress(s) + >>> len(t) + 37 + >>> zlib.decompress(t) + b'witch which has which witches wrist watch' + >>> zlib.crc32(s) + 226805979 + + +.. _tut-performance-measurement: + +性能度量 +======================= + +有些用户对了解解决同一问题的不同方法之间的性能差异很感兴趣。Python 提供了一个度量工具,为这些问题提供了直接答案。 + +例如,使用元组封装和拆封来交换元素看起来要比使用传统的方法要诱人的多。`timeit `_ 证明了后者更快一些:: + + >>> from timeit import Timer + >>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit() + 0.57535828626024577 + >>> Timer('a,b = b,a', 'a=1; b=2').timeit() + 0.54962537085770791 + +相对于 `timeit `_ 的细粒度,`profile `_ 和 `pstats `_ 模块提供了针对更大代码块的时间度量工具。 + + +.. _tut-quality-control: + +质量控制 +=============== + +开发高质量软件的方法之一是为每一个函数开发测试代码,并且在开发过程中经常进行测试。 + +`doctest `_ 模块提供了一个工具,扫描模块并根据程序中内嵌的文档字符串执行测试。测试构造如同简单的将它的输出结果剪切并粘贴到文档字符串中。通过用户提供的例子,它发展了文档,允许 doctest 模块确认代码的结果是否与文档一致:: + + def average(values): + """Computes the arithmetic mean of a list of numbers. + + >>> print average([20, 30, 70]) + 40.0 + """ + return sum(values, 0.0) / len(values) + + import doctest + doctest.testmod() # automatically validate the embedded tests + +`unittest `_ 模块不像 `doctest `_ 模块那么容易使用,不过它可以在一个独立的文件里提供一个更全面的测试集:: + + import unittest + + class TestStatisticalFunctions(unittest.TestCase): + + def test_average(self): + self.assertEqual(average([20, 30, 70]), 40.0) + self.assertEqual(round(average([1, 5, 7]), 1), 4.3) + self.assertRaises(ZeroDivisionError, average, []) + self.assertRaises(TypeError, average, 20, 30, 70) + + unittest.main() # Calling from the command line invokes all tests + + +.. _tut-batteries-included: + +“瑞士军刀” +================== + +Python 展现了“瑞士军刀”的哲学。这可以通过它更大的包的高级和健壮的功能来得到最好的展现。例如: + +* `xmlrpclib `_ 和 `SimpleXMLRPCServer `_ 模块让远程过程调用变得轻而易举。 + + 尽管模块有这样的名字,用户无需拥有XML的知识或处理 XML。 + +* `email `_ 包是一个管理邮件信息的库,包括MIME和其它基于 RFC2822 的信息文档。 + + 不同于实际发送和接收信息的 `smtplib `_ 和 `poplib `_ 模块,email 包包含一个构造或解析复杂消息结构(包括附件)及实现互联网编码和头协议的完整工具集。 + +* `xml.dom `_ 和 `xml.sax `_ 包为流行的信息交换格式提供了强大的支持。 + + 同样,`csv `_ 模块支持在通用数据库格式中直接读写。综合起来,这些模块和包大大简化了 Python 应用程序和其它工具之间的数据交换。 + +* 国际化由 `gettext `_, `locale `_ 和 `codecs `_ 包支持。 diff --git a/html/_sources/stdlib2.txt b/docs/html/_sources/stdlib2.txt similarity index 57% rename from html/_sources/stdlib2.txt rename to docs/html/_sources/stdlib2.txt index d42a4e7..955a8a4 100644 --- a/html/_sources/stdlib2.txt +++ b/docs/html/_sources/stdlib2.txt @@ -13,13 +13,13 @@ 输出格式 ================= -:mod:`repr` 模块为大型的或深度嵌套的容器缩写显示提供了 :func:`repr` 函数的一个定制版本:: +`repr `_ 模块为大型的或深度嵌套的容器缩写显示提供了 `repr() `_ 函数的一个定制版本:: >>> import repr >>> repr.repr(set('supercalifragilisticexpialidocious')) "set(['a', 'c', 'd', 'e', 'f', 'g', ...])" -:mod:`pprint` 模块给老手提供了一种解释器可读的方式深入控制内置和用户自定义对象的打印。当输出超过一行的时候,“美化打印(pretty printer)”添加断行和标识符,使得数据结构显示的更清晰:: +`pprint `_ 模块给老手提供了一种解释器可读的方式深入控制内置和用户自定义对象的打印。当输出超过一行的时候,“美化打印(pretty printer)”添加断行和标识符,使得数据结构显示的更清晰:: >>> import pprint >>> t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta', @@ -32,7 +32,7 @@ [['magenta', 'yellow'], 'blue']]] -:mod:`textwrap` 模块格式化文本段落以适应设定的屏宽:: +`textwrap `_ 模块格式化文本段落以适应设定的屏宽:: >>> import textwrap >>> doc = """The wrap() method is just like fill() except that it returns @@ -45,7 +45,7 @@ instead of one big string with newlines to separate the wrapped lines. -:mod:`locale` 模块按访问预定好的国家信息数据库。locale 的格式化函数属性集提供了一个直接方式以分组标示格式化数字:: +`locale `_ 模块按访问预定好的国家信息数据库。locale 的格式化函数属性集提供了一个直接方式以分组标示格式化数字:: >>> import locale >>> locale.setlocale(locale.LC_ALL, 'English_United States.1252') @@ -64,16 +64,16 @@ 模板 ========== -:mod:`string` 提供了一个灵活多变的模版类 :class:`Template` ,使用它最终用户可以简单地进行编辑。这使用户可以在不进行改变的情况下定制他们的应用程序。 +`string `_ 提供了一个灵活多变的模版类 `Template `_ ,使用它最终用户可以简单地进行编辑。这使用户可以在不进行改变的情况下定制他们的应用程序。 -格式使用 ``$`` 为开头的 Python 合法标识(数字、字母和下划线)作为占位符。占位符外面的大括号使它可以和其它的字符不加空格混在一起。 ``$$`` 创建一个单独的 ``$``:: +格式使用 ``$`` 为开头的 Python 合法标识(数字、字母和下划线)作为占位符。占位符外面的大括号使它可以和其它的字符不加空格混在一起。``$$`` 创建一个单独的 ``$``:: >>> from string import Template >>> t = Template('${village}folk send $$10 to $cause.') >>> t.substitute(village='Nottingham', cause='the ditch fund') 'Nottinghamfolk send $10 to the ditch fund.' -当一个占位符在字典或关键字参数中没有被提供时, :meth:`substitute` 方法就会抛出一个 :exc:`KeyError` 异常。 对于邮件合并风格的应用程序,用户提供的数据可能并不完整,这时使用 :meth:`safe_substitute` 方法可能更适合 — 如果数据不完整,它就不会改变占位符:: +当一个占位符在字典或关键字参数中没有被提供时,`substitute() `_ 方法就会抛出一个 `KeyError `_ 异常。对于邮件合并风格的应用程序,用户提供的数据可能并不完整,这时使用 `safe_substitute() `_ 方法可能更适合。如果数据不完整,它就不会改变占位符:: >>> t = Template('Return the $item to $owner.') >>> d = dict(item='unladen swallow') @@ -84,7 +84,7 @@ >>> t.safe_substitute(d) 'Return the unladen swallow to $owner.' -模板子类可以指定一个自定义分隔符。 例如,图像查看器的批量重命名工具可能选择使用百分号作为占位符,像当前日期,图片序列号或文件格式:: +模板子类可以指定一个自定义分隔符。例如,图像查看器的批量重命名工具可能选择使用百分号作为占位符,像当前日期,图片序列号或文件格式:: >>> import time, os.path >>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg'] @@ -112,7 +112,7 @@ 使用二进制数据记录布局 ======================================= -:mod:`struct` 模块为使用变长的二进制记录格式提供了 :func:`pack` 和 :func:`unpack` 函数。 下面的示例演示了在不使用 :mod:`zipfile` 模块的情况下如何迭代一个 ZIP 文件的头信息。 压缩码 ``"H"`` 和 ``"I"`` 分别表示2和4字节无符号数字, ``"<"`` 表明它们都是标准大小并且按照 little-endian 字节排序。 :: +`struct `_ 模块为使用变长的二进制记录格式提供了 `pack() `_ 和 `unpack() `_ 函数。下面的示例演示了在不使用 `zipfile `_ 模块的情况下如何迭代一个 ZIP 文件的头信息。压缩码 ``"H"`` 和 ``"I"`` 分别表示2和4字节无符号数字,``"<"`` 表明它们都是标准大小并且按照 little-endian 字节排序:: import struct @@ -141,7 +141,7 @@ 线程是一个分离无顺序依赖关系任务的技术。在某些任务运行于后台的时候应用程序会变得迟缓,线程可以提升其速度。一个有关的用途是在 I/O 的同时其它线程可以并行计算。 -下面的代码显示了高级模块 :mod:`threading` 如何在主程序运行的同时运行任务:: +下面的代码显示了高级模块 `threading `_ 如何在主程序运行的同时运行任务:: import threading, zipfile @@ -163,9 +163,9 @@ background.join() # Wait for the background task to finish print 'Main program waited until background was done.' -多线程应用程序的主要挑战是协调线程,诸如线程间共享数据或其它资源。 为了达到那个目的,线程模块提供了许多同步化的原生支持,包括:锁,事件,条件变量和信号灯。 +多线程应用程序的主要挑战是协调线程,诸如线程间共享数据或其它资源。为了达到那个目的,线程模块提供了许多同步化的原生支持,包括:锁,事件,条件变量和信号灯。 -尽管这些工具很强大,微小的设计错误也可能造成难以挽回的故障。 因此,任务协调的首选方法是把对一个资源的所有访问集中在一个单独的线程中,然后使用 :mod:`queue` 模块用那个线程服务其他线程的请求。 为内部线程通信和协调而使用 :class:`Queue` 对象的应用程序更易于设计,更可读,并且更可靠。 +尽管这些工具很强大,微小的设计错误也可能造成难以挽回的故障。因此,任务协调的首选方法是把对一个资源的所有访问集中在一个单独的线程中,然后使用 `Queue `_ 模块用那个线程服务其他线程的请求。为内部线程通信和协调而使用 `Queue.Queue `_ 对象的应用程序更易于设计,更可读,并且更可靠。 .. _tut-logging: @@ -173,7 +173,7 @@ 日志 ======= -:mod:`logging` 模块提供了完整和灵活的日志系统。它最简单的用法是记录信息并发送到一个文件或 ``sys.stderr``:: +`logging `_ 模块提供了完整和灵活的日志系统。它最简单的用法是记录信息并发送到一个文件或 ``sys.stderr``:: import logging logging.debug('Debugging information') @@ -188,8 +188,7 @@ ERROR:root:Error occurred CRITICAL:root:Critical error -- shutting down -默认情况下捕获信息和调试消息并将输出发送到标准错误流。其它可选的路由信息方式通过 email,数据报文,socket 或者 HTTP Server。基于消息属性,新的过滤器可以选择不同的路由: :const:`DEBUG`, :const:`INFO`, -:const:`WARNING`, :const:`ERROR`, 和 :const:`CRITICAL` 。 +默认情况下捕获信息和调试消息并将输出发送到标准错误流。其它可选的路由信息方式通过 email,数据报文,socket 或者 HTTP Server。基于消息属性,新的过滤器可以选择不同的路由::const:`DEBUG`,:const:`INFO`,:const:`WARNING`,:const:`ERROR` 和 :const:`CRITICAL` 。 日志系统可以直接在 Python 代码中定制,也可以不经过应用程序直接在一个用户可编辑的配置文件中加载。 @@ -199,9 +198,9 @@ 弱引用 =============== -Python 自动进行内存管理(对大多数的对象进行引用计数和垃圾回收—— :term:`garbage collection` ——以循环利用)在最后一个引用消失后,内存会很快释放。 +Python 自动进行内存管理(对大多数的对象进行引用计数和垃圾回收 `garbage collection `_ 以循环利用)在最后一个引用消失后,内存会很快释放。 -这个工作方式对大多数应用程序工作良好,但是偶尔会需要跟踪对象来做一些事。不幸的是,仅仅为跟踪它们创建引用也会使其长期存在。 :mod:`weakref` 模块提供了不用创建引用的跟踪对象工具,一旦对象不再存在,它自动从弱引用表上删除并触发回调。典型的应用包括捕获难以构造的对象:: +这个工作方式对大多数应用程序工作良好,但是偶尔会需要跟踪对象来做一些事。不幸的是,仅仅为跟踪它们创建引用也会使其长期存在。`weakref `_ 模块提供了不用创建引用的跟踪对象工具,一旦对象不再存在,它自动从弱引用表上删除并触发回调。典型的应用包括捕获难以构造的对象:: >>> import weakref, gc >>> class A: @@ -234,7 +233,7 @@ Python 自动进行内存管理(对大多数的对象进行引用计数和垃 很多数据结构可能会用到内置列表类型。然而,有时可能需要不同性能代价的实现。 -:mod:`array` 模块提供了一个类似列表的 :class:`array()` 对象,它仅仅是存储数据,更为紧凑。以下的示例演示了一个存储双字节无符号整数的数组(类型编码 ``"H"`` )而非存储 16 字节 Python 整数对象的普通正规列表:: +`array `_ 模块提供了一个类似列表的 `array() `_ 对象,它仅仅是存储数据,更为紧凑。以下的示例演示了一个存储双字节无符号整数的数组(类型编码 ``"H"`` )而非存储 16 字节 Python 整数对象的普通正规列表:: >>> from array import array >>> a = array('H', [4000, 10, 700, 22222]) @@ -243,7 +242,7 @@ Python 自动进行内存管理(对大多数的对象进行引用计数和垃 >>> a[1:3] array('H', [10, 700]) -:mod:`collections` 模块提供了类似列表的 :class:`deque()` 对象,它从左边添加(append)和弹出(pop)更快,但是在内部查询更慢。这些对象更适用于队列实现和广度优先的树搜索:: +`collections `_ 模块提供了类似列表的 `deque() `_ 对象,它从左边添加(append)和弹出(pop)更快,但是在内部查询更慢。这些对象更适用于队列实现和广度优先的树搜索:: >>> from collections import deque >>> d = deque(["task1", "task2", "task3"]) @@ -259,7 +258,7 @@ Python 自动进行内存管理(对大多数的对象进行引用计数和垃 return m unsearched.append(m) -除了链表的替代实现,该库还提供了 :mod:`bisect` 这样的模块以操作存储链表:: +除了链表的替代实现,该库还提供了 `bisect `_ 这样的模块以操作存储链表:: >>> import bisect >>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')] @@ -267,7 +266,7 @@ Python 自动进行内存管理(对大多数的对象进行引用计数和垃 >>> scores [(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')] -:mod:`heapq` 提供了基于正规链表的堆实现。最小的值总是保持在 0 点。这在希望循环访问最小元素但是不想执行完整堆排序的时候非常有用:: +`heapq `_ 提供了基于正规链表的堆实现。最小的值总是保持在 0 点。这在希望循环访问最小元素但是不想执行完整堆排序的时候非常有用:: >>> from heapq import heapify, heappop, heappush >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] @@ -282,7 +281,7 @@ Python 自动进行内存管理(对大多数的对象进行引用计数和垃 十进制浮点数算法 ================================= -:mod:`decimal` 模块提供了一个 :class:`Decimal` 数据类型用于浮点数计算。相比内置的二进制浮点数实现 :class:`float` ,这个类型有助于 +`decimal `_ 模块提供了一个 `Decimal `_ 数据类型用于浮点数计算。相比内置的二进制浮点数实现 `float `_,这个类型有助于: * 金融应用和其它需要精确十进制表达的场合, @@ -290,7 +289,9 @@ Python 自动进行内存管理(对大多数的对象进行引用计数和垃 * 控制舍入以适应法律或者规定要求, -* 确保十进制数位精度,或者 +* 确保十进制数位精度, + + 或者 * 用户希望计算结果与手算相符的场合。 @@ -302,9 +303,9 @@ Python 自动进行内存管理(对大多数的对象进行引用计数和垃 >>> round(.70 * 1.05, 2) 0.73 -:class:`Decimal` 的结果总是保有结尾的 0,自动从两位精度延伸到4位。 Decimal 重现了手工的数学运算,这就确保了二进制浮点数无法精确保有的数据精度。 +`Decimal `_ 的结果总是保有结尾的 0,自动从两位精度延伸到4位。Decimal 重现了手工的数学运算,这就确保了二进制浮点数无法精确保有的数据精度。 -高精度使 :class:`Decimal` 可以执行二进制浮点数无法进行的模运算和等值测试:: +高精度使 `Decimal `_ 可以执行二进制浮点数无法进行的模运算和等值测试:: >>> Decimal('1.00') % Decimal('.10') Decimal('0.00') @@ -316,7 +317,7 @@ Python 自动进行内存管理(对大多数的对象进行引用计数和垃 >>> sum([0.1]*10) == 1.0 False -:mod:`decimal` 提供了必须的高精度算法:: +`decimal `_ 提供了必须的高精度算法:: >>> getcontext().prec = 36 >>> Decimal(1) / Decimal(7) diff --git a/docs/html/_sources/whatnow.txt b/docs/html/_sources/whatnow.txt new file mode 100644 index 0000000..11ead45 --- /dev/null +++ b/docs/html/_sources/whatnow.txt @@ -0,0 +1,41 @@ +.. _tut-whatnow: + +********* +接下来? +********* + +读过这本指南应该会让你有兴趣使用 Python —— 可能你已经期待着用 Python 解决你的实际问题了。可以在哪里进行一步学习? + +入门指南是 Python 文档集的一部分。其中的另一些文档包括: + +* `Python 标准库 `_: + + 应该浏览一下这份文档,它为标准库中的类型、函数和模块提供了完整(尽管很简略)的参考资料。标准的 Python 发布版包括了大量的附加模块。其中有针对读取 Unix 邮箱、接收 HTTP 文档、生成随机数、解析命令行选项、写 CGI 程序、压缩数据以及很多其它任务的模块。略读一下库参考会给你很多解决问题的思路。 + +* `安装 Python 模块 `_ 展示了如何安装其他 Python 用户编写的附加模块。 + +* `Python 语言参考 `_: 詳細说明了 Python 语法和语义。它读起来很累,不过对于语言本身,有份完整的手册很有用。 + +其它 Python 资源: + +* http://www.python.org: Python 官方网站。它包含代码、文档和 Web 上与 Python 有关的页面链接。 + + 该网站镜像于世界各地,类似欧洲、日本和澳大利亚。镜像可能会比主站快,这取决于你的地理位置。 + +* http://docs.python.org: 快速访问 Python 的文档。 + +* http://pypi.python.org: Python 包索引,以前昵称为奶酪店,索引了可供下载的,用户创建的 Python 模块。 + + 如果你发布了代码,可以注册到这里,这样别人可以找到它。 + +* http://aspn.activestate.com/ASPN/Python/Cookbook/: Python 食谱是大量的示例代码、大型的集合,和有用的脚本。 + + 值得关注的是这次资源已经结集成书,名为《Python 食谱》(O’Reilly & Associates, ISBN 0-596-00797-3) + +与 Python 有关的问题,以及问题报告,可以发到新闻组 :newsgroup:`comp.lang.python`,或者发送到邮件组 python-list@python.org 。新闻组和邮件组是开放的,所以发送的消息可以自动的跟到另一个之后。每天有超过 120 个投递(高峰时有数百),提问(以及回答)问题,为新功能提建议,发布新模块。在发信之前,请查阅 `常见问题 +`_ (亦称 FAQ),或者在 Python 源码发布包的 :file:`Misc/` 目录中查阅。邮件组也可以在 http://mail.python.org/pipermail/ 访问。FAQ回答了很多被反复提到的问题,很可能已经解答了你的问题。 + +.. Postings figure based on average of last six months activity as + 最近六个月的提交数在 www.egroups.com 有报告;2000年六月:21272 封 / 182 天 = 116.9 封/天,并且还在平稳的上升。(现在是多少?) + + diff --git a/html/_static/ajax-loader.gif b/docs/html/_static/ajax-loader.gif similarity index 100% rename from html/_static/ajax-loader.gif rename to docs/html/_static/ajax-loader.gif diff --git a/html/_static/basic.css b/docs/html/_static/basic.css similarity index 85% rename from html/_static/basic.css rename to docs/html/_static/basic.css index c959cf0..2b513f0 100644 --- a/html/_static/basic.css +++ b/docs/html/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -52,6 +52,8 @@ div.sphinxsidebar { width: 230px; margin-left: -100%; font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; } div.sphinxsidebar ul { @@ -83,10 +85,6 @@ div.sphinxsidebar #searchbox input[type="text"] { width: 170px; } -div.sphinxsidebar #searchbox input[type="submit"] { - width: 30px; -} - img { border: 0; max-width: 100%; @@ -187,6 +185,13 @@ div.genindex-jumpbox { /* -- general body styles --------------------------------------------------- */ +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + a.headerlink { visibility: hidden; } @@ -197,7 +202,10 @@ h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, -dt:hover > a.headerlink { +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { visibility: visible; } @@ -314,6 +322,13 @@ table.docutils { border-collapse: collapse; } +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; border-top: 0; @@ -344,6 +359,25 @@ table.citation td { border-bottom: none; } +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + + /* -- other body styles ----------------------------------------------------- */ ol.arabic { @@ -406,6 +440,10 @@ dl.glossary dt { font-size: 1.3em; } +.sig-paren { + font-size: larger; +} + .versionmodified { font-style: italic; } @@ -471,22 +509,51 @@ table.highlighttable td { padding: 0 0.5em 0 0.5em; } -tt.descname { +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { background-color: transparent; font-weight: bold; font-size: 1.2em; } -tt.descclassname { +code.descclassname { background-color: transparent; } -tt.xref, a tt { +code.xref, a code { background-color: transparent; font-weight: bold; } -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { background-color: transparent; } diff --git a/html/_static/comment-bright.png b/docs/html/_static/comment-bright.png similarity index 100% rename from html/_static/comment-bright.png rename to docs/html/_static/comment-bright.png diff --git a/html/_static/comment-close.png b/docs/html/_static/comment-close.png similarity index 100% rename from html/_static/comment-close.png rename to docs/html/_static/comment-close.png diff --git a/html/_static/comment.png b/docs/html/_static/comment.png similarity index 100% rename from html/_static/comment.png rename to docs/html/_static/comment.png diff --git a/docs/html/_static/css/badge_only.css b/docs/html/_static/css/badge_only.css new file mode 100644 index 0000000..7e17fb1 --- /dev/null +++ b/docs/html/_static/css/badge_only.css @@ -0,0 +1,2 @@ +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}} +/*# sourceMappingURL=badge_only.css.map */ diff --git a/docs/html/_static/css/theme.css b/docs/html/_static/css/theme.css new file mode 100644 index 0000000..3ff3c1b --- /dev/null +++ b/docs/html/_static/css/theme.css @@ -0,0 +1,6 @@ +*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.1.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.1.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.1.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.pull-left.icon{margin-right:.3em}.fa.pull-right,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-square:before,.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .icon,.nav .fa,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .icon{display:inline}.btn .fa.fa-large,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#f3f6f6;color:#cad2d3}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fff;color:#cad2d3;border-color:transparent}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9B59B6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#2980B9;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-side-nav-search{z-index:200;background-color:#2980B9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:absolute;top:0;left:0;width:300px;overflow:hidden;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}nav.stickynav{position:fixed;top:0}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt{color:#000}.rst-content tt big,.rst-content tt em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt{font-weight:bold}.rst-content a tt{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center} +/*# sourceMappingURL=theme.css.map */ +.wy-side-ad {color: #fcfcfc;display: block;margin-bottom: 0.809em;padding: 0.809em;text-align: center;z-index: 200;} \ No newline at end of file diff --git a/html/_static/doctools.js b/docs/html/_static/doctools.js similarity index 80% rename from html/_static/doctools.js rename to docs/html/_static/doctools.js index 2036e5f..8163495 100644 --- a/html/_static/doctools.js +++ b/docs/html/_static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -91,6 +91,30 @@ jQuery.fn.highlightText = function(text, className) { }); }; +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + /** * Small JavaScript module for the documentation. */ @@ -100,6 +124,7 @@ var Documentation = { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); + }, /** @@ -152,9 +177,10 @@ var Documentation = { /** * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 */ fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) + if (document.location.hash) window.setTimeout(function() { document.location.href += ''; }, 10); @@ -227,6 +253,29 @@ var Documentation = { }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keyup(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); } }; @@ -235,4 +284,4 @@ _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); -}); +}); \ No newline at end of file diff --git a/docs/html/_static/down-pressed.png b/docs/html/_static/down-pressed.png new file mode 100644 index 0000000..7c30d00 Binary files /dev/null and b/docs/html/_static/down-pressed.png differ diff --git a/docs/html/_static/down.png b/docs/html/_static/down.png new file mode 100644 index 0000000..f48098a Binary files /dev/null and b/docs/html/_static/down.png differ diff --git a/docs/html/_static/file.png b/docs/html/_static/file.png new file mode 100644 index 0000000..254c60b Binary files /dev/null and b/docs/html/_static/file.png differ diff --git a/docs/html/_static/fonts/FontAwesome.otf b/docs/html/_static/fonts/FontAwesome.otf new file mode 100644 index 0000000..8b0f54e Binary files /dev/null and b/docs/html/_static/fonts/FontAwesome.otf differ diff --git a/docs/html/_static/fonts/fontawesome-webfont.eot b/docs/html/_static/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..7c79c6a Binary files /dev/null and b/docs/html/_static/fonts/fontawesome-webfont.eot differ diff --git a/docs/html/_static/fonts/fontawesome-webfont.svg b/docs/html/_static/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..45fdf33 --- /dev/null +++ b/docs/html/_static/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/html/_static/fonts/fontawesome-webfont.ttf b/docs/html/_static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..e89738d Binary files /dev/null and b/docs/html/_static/fonts/fontawesome-webfont.ttf differ diff --git a/docs/html/_static/fonts/fontawesome-webfont.woff b/docs/html/_static/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..8c1748a Binary files /dev/null and b/docs/html/_static/fonts/fontawesome-webfont.woff differ diff --git a/docs/html/_static/jquery-1.11.1.js b/docs/html/_static/jquery-1.11.1.js new file mode 100644 index 0000000..d4b67f7 --- /dev/null +++ b/docs/html/_static/jquery-1.11.1.js @@ -0,0 +1,10308 @@ +/*! + * jQuery JavaScript Library v1.11.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-05-01T17:42Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.11.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v1.10.19 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-04-18 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = "
"; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowclip^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !(--remaining) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + + +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery(function() { + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +}); + + + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; +}; +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + // Minified: var a,b,c + var input = document.createElement( "input" ), + div = document.createElement( "div" ), + fragment = document.createDocumentFragment(); + + // Setup + div.innerHTML = "
a"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = ""; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "