diff --git a/doc/html/HTML.manifest b/doc/html/HTML.manifest
new file mode 100644
index 00000000..edde06ad
--- /dev/null
+++ b/doc/html/HTML.manifest
@@ -0,0 +1,31 @@
+index.html
+rn.html
+building.html
+building/background.html
+building/no_install_quickstart.html
+building/installing_boost_python_on_your_.html
+building/configuring_boost_build.html
+building/choosing_a_boost_python_library_.html
+building/include_issues.html
+building/python_debugging_builds.html
+building/testing_boost_python.html
+building/notes_for_mingw_and_cygwin_with_.html
+configuration.html
+support.html
+faq.html
+faq/i_m_getting_the_attempt_to_retur.html
+faq/is_return_internal_reference_eff.html
+faq/how_can_i_wrap_functions_which_t.html
+faq/fatal_error_c1204_compiler_limit.html
+faq/how_do_i_debug_my_python_extensi.html
+faq/why_doesn_t_my_operator_work.html
+faq/does_boost_python_work_with_mac_.html
+faq/how_can_i_find_the_existing_pyob.html
+faq/how_can_i_wrap_a_function_which0.html
+faq/compilation_takes_too_much_time_.html
+faq/how_do_i_create_sub_packages_usi.html
+faq/error_c2064_term_does_not_evalua.html
+faq/how_can_i_automatically_convert_.html
+faq/why_is_my_automatic_to_python_co.html
+faq/is_boost_python_thread_aware_com.html
+glossary.html
diff --git a/doc/html/article.html b/doc/html/article.html
new file mode 100644
index 00000000..bd0ad6e6
--- /dev/null
+++ b/doc/html/article.html
@@ -0,0 +1,929 @@
+
+
+
+
+
+
+Building Hybrid Systems with Boost.Python
+
+
+
+
+
+<--- Cannot embed stylesheet '/rst.css': No such file or directory. --->
+
+
+
+
Building Hybrid Systems with Boost.Python
+
+
+
+
+Author:
+David Abrahams
+Contact:
+dave@boost-consulting.com
+Organization:
+Boost Consulting
+Date:
+2003-05-14
+Author:
+Ralf W. Grosse-Kunstleve
+Copyright:
+Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved
+
+
+
+
+
+
Boost.Python is an open source C++ library which provides a concise
+IDL-like interface for binding C++ classes and functions to
+Python. Leveraging the full power of C++ compile-time introspection
+and of recently developed metaprogramming techniques, this is achieved
+entirely in pure C++, without introducing a new syntax.
+Boost.Python's rich set of features and high-level interface make it
+possible to engineer packages from the ground up as hybrid systems,
+giving programmers easy and coherent access to both the efficient
+compile-time polymorphism of C++ and the extremely convenient run-time
+polymorphism of Python.
+
+
+
+
Python and C++ are in many ways as different as two languages could
+be: while C++ is usually compiled to machine-code, Python is
+interpreted. Python's dynamic type system is often cited as the
+foundation of its flexibility, while in C++ static typing is the
+cornerstone of its efficiency. C++ has an intricate and difficult
+compile-time meta-language, while in Python, practically everything
+happens at runtime.
+
Yet for many programmers, these very differences mean that Python and
+C++ complement one another perfectly. Performance bottlenecks in
+Python programs can be rewritten in C++ for maximal speed, and
+authors of powerful C++ libraries choose Python as a middleware
+language for its flexible system integration capabilities.
+Furthermore, the surface differences mask some strong similarities:
+
+'C'-family control structures (if, while, for...)
+Support for object-orientation, functional programming, and generic
+programming (these are both multi-paradigm programming languages.)
+Comprehensive operator overloading facilities, recognizing the
+importance of syntactic variability for readability and
+expressivity.
+High-level concepts such as collections and iterators.
+High-level encapsulation facilities (C++: namespaces, Python: modules)
+to support the design of re-usable libraries.
+Exception-handling for effective management of error conditions.
+C++ idioms in common use, such as handle/body classes and
+reference-counted smart pointers mirror Python reference semantics.
+
+
Given Python's rich 'C' interoperability API, it should in principle
+be possible to expose C++ type and function interfaces to Python with
+an analogous interface to their C++ counterparts. However, the
+facilities provided by Python alone for integration with C++ are
+relatively meager. Compared to C++ and Python, 'C' has only very
+rudimentary abstraction facilities, and support for exception-handling
+is completely missing. 'C' extension module writers are required to
+manually manage Python reference counts, which is both annoyingly
+tedious and extremely error-prone. Traditional extension modules also
+tend to contain a great deal of boilerplate code repetition which
+makes them difficult to maintain, especially when wrapping an evolving
+API.
+
These limitations have lead to the development of a variety of wrapping
+systems. SWIG is probably the most popular package for the
+integration of C/C++ and Python. A more recent development is SIP ,
+which was specifically designed for interfacing Python with the Qt
+graphical user interface library. Both SWIG and SIP introduce their
+own specialized languages for customizing inter-language bindings.
+This has certain advantages, but having to deal with three different
+languages (Python, C/C++ and the interface language) also introduces
+practical and mental difficulties. The CXX package demonstrates an
+interesting alternative. It shows that at least some parts of
+Python's 'C' API can be wrapped and presented through a much more
+user-friendly C++ interface. However, unlike SWIG and SIP, CXX does
+not include support for wrapping C++ classes as new Python types.
+
The features and goals of Boost.Python overlap significantly with
+many of these other systems. That said, Boost.Python attempts to
+maximize convenience and flexibility without introducing a separate
+wrapping language. Instead, it presents the user with a high-level
+C++ interface for wrapping C++ classes and functions, managing much of
+the complexity behind-the-scenes with static metaprogramming.
+Boost.Python also goes beyond the scope of earlier systems by
+providing:
+
+Support for C++ virtual functions that can be overridden in Python.
+Comprehensive lifetime management facilities for low-level C++
+pointers and references.
+Support for organizing extensions as Python packages,
+with a central registry for inter-language type conversions.
+A safe and convenient mechanism for tying into Python's powerful
+serialization engine (pickle).
+Coherence with the rules for handling C++ lvalues and rvalues that
+can only come from a deep understanding of both the Python and C++
+type systems.
+
+
The key insight that sparked the development of Boost.Python is that
+much of the boilerplate code in traditional extension modules could be
+eliminated using C++ compile-time introspection. Each argument of a
+wrapped C++ function must be extracted from a Python object using a
+procedure that depends on the argument type. Similarly the function's
+return type determines how the return value will be converted from C++
+to Python. Of course argument and return types are part of each
+function's type, and this is exactly the source from which
+Boost.Python deduces most of the information required.
+
This approach leads to user guided wrapping : as much information is
+extracted directly from the source code to be wrapped as is possible
+within the framework of pure C++, and some additional information is
+supplied explicitly by the user. Mostly the guidance is mechanical
+and little real intervention is required. Because the interface
+specification is written in the same full-featured language as the
+code being exposed, the user has unprecedented power available when
+she does need to take control.
+
+
+
+
The primary goal of Boost.Python is to allow users to expose C++
+classes and functions to Python using nothing more than a C++
+compiler. In broad strokes, the user experience should be one of
+directly manipulating C++ objects from Python.
+
However, it's also important not to translate all interfaces too
+literally: the idioms of each language must be respected. For
+example, though C++ and Python both have an iterator concept, they are
+expressed very differently. Boost.Python has to be able to bridge the
+interface gap.
+
It must be possible to insulate Python users from crashes resulting
+from trivial misuses of C++ interfaces, such as accessing
+already-deleted objects. By the same token the library should
+insulate C++ users from low-level Python 'C' API, replacing
+error-prone 'C' interfaces like manual reference-count management and
+raw PyObject pointers with more-robust alternatives.
+
Support for component-based development is crucial, so that C++ types
+exposed in one extension module can be passed to functions exposed in
+another without loss of crucial information like C++ inheritance
+relationships.
+
Finally, all wrapping must be non-intrusive , without modifying or
+even seeing the original C++ source code. Existing C++ libraries have
+to be wrappable by third parties who only have access to header files
+and binaries.
+
+
+
+
And now for a preview of Boost.Python, and how it improves on the raw
+facilities offered by Python. Here's a function we might want to
+expose:
+
+char const* greet(unsigned x)
+{
+ static char const* const msgs[] = { "hello", "Boost.Python", "world!" };
+
+ if (x > 2)
+ throw std::range_error("greet: index out of range");
+
+ return msgs[x];
+}
+
+
To wrap this function in standard C++ using the Python 'C' API, we'd
+need something like this:
+
+extern "C" // all Python interactions use 'C' linkage and calling convention
+{
+ // Wrapper to handle argument/result conversion and checking
+ PyObject* greet_wrap(PyObject* args, PyObject * keywords)
+ {
+ int x;
+ if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments
+ {
+ char const* result = greet(x); // invoke wrapped function
+ return PyString_FromString(result); // convert result to Python
+ }
+ return 0; // error occurred
+ }
+
+ // Table of wrapped functions to be exposed by the module
+ static PyMethodDef methods[] = {
+ { "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" }
+ , { NULL, NULL, 0, NULL } // sentinel
+ };
+
+ // module initialization function
+ DL_EXPORT init_hello()
+ {
+ (void) Py_InitModule("hello", methods); // add the methods to the module
+ }
+}
+
+
Now here's the wrapping code we'd use to expose it with Boost.Python:
+
+#include <boost/python.hpp>
+using namespace boost::python;
+BOOST_PYTHON_MODULE(hello)
+{
+ def("greet", greet, "return one of 3 parts of a greeting");
+}
+
+
and here it is in action:
+
+>>> import hello
+>>> for x in range(3):
+... print hello.greet(x)
+...
+hello
+Boost.Python
+world!
+
+
Aside from the fact that the 'C' API version is much more verbose,
+it's worth noting a few things that it doesn't handle correctly:
+
+The original function accepts an unsigned integer, and the Python
+'C' API only gives us a way of extracting signed integers. The
+Boost.Python version will raise a Python exception if we try to pass
+a negative number to hello.greet , but the other one will proceed
+to do whatever the C++ implementation does when converting an
+negative integer to unsigned (usually wrapping to some very large
+number), and pass the incorrect translation on to the wrapped
+function.
+That brings us to the second problem: if the C++ greet()
+function is called with a number greater than 2, it will throw an
+exception. Typically, if a C++ exception propagates across the
+boundary with code generated by a 'C' compiler, it will cause a
+crash. As you can see in the first version, there's no C++
+scaffolding there to prevent this from happening. Functions wrapped
+by Boost.Python automatically include an exception-handling layer
+which protects Python users by translating unhandled C++ exceptions
+into a corresponding Python exception.
+A slightly more-subtle limitation is that the argument conversion
+used in the Python 'C' API case can only get that integer x in
+one way . PyArg_ParseTuple can't convert Python long objects
+(arbitrary-precision integers) which happen to fit in an unsigned
+int but not in a signed long , nor will it ever handle a
+wrapped C++ class with a user-defined implicit operator unsigned
+int() conversion. Boost.Python's dynamic type conversion
+registry allows users to add arbitrary conversion methods.
+
+
+
+
+
This section outlines some of the library's major features. Except as
+neccessary to avoid confusion, details of library implementation are
+omitted.
+
+
+
C++ classes and structs are exposed with a similarly-terse interface.
+Given:
+
+struct World
+{
+ void set(std::string msg) { this->msg = msg; }
+ std::string greet() { return msg; }
+ std::string msg;
+};
+
+
The following code will expose it in our extension module:
+
+#include <boost/python.hpp>
+BOOST_PYTHON_MODULE(hello)
+{
+ class_<World>("World")
+ .def("greet", &World::greet)
+ .def("set", &World::set)
+ ;
+}
+
+
Although this code has a certain pythonic familiarity, people
+sometimes find the syntax bit confusing because it doesn't look like
+most of the C++ code they're used to. All the same, this is just
+standard C++. Because of their flexible syntax and operator
+overloading, C++ and Python are great for defining domain-specific
+(sub)languages
+(DSLs), and that's what we've done in Boost.Python. To break it down:
+
+class_<World>("World")
+
+
constructs an unnamed object of type class_<World> and passes
+"World" to its constructor. This creates a new-style Python class
+called World in the extension module, and associates it with the
+C++ type World in the Boost.Python type conversion registry. We
+might have also written:
+
+class_<World> w("World");
+
+
but that would've been more verbose, since we'd have to name w
+again to invoke its def() member function:
+
+w.def("greet", &World::greet)
+
+
There's nothing special about the location of the dot for member
+access in the original example: C++ allows any amount of whitespace on
+either side of a token, and placing the dot at the beginning of each
+line allows us to chain as many successive calls to member functions
+as we like with a uniform syntax. The other key fact that allows
+chaining is that class_<> member functions all return a reference
+to *this .
+
So the example is equivalent to:
+
+class_<World> w("World");
+w.def("greet", &World::greet);
+w.def("set", &World::set);
+
+
It's occasionally useful to be able to break down the components of a
+Boost.Python class wrapper in this way, but the rest of this article
+will stick to the terse syntax.
+
For completeness, here's the wrapped class in use:
+
+>>> import hello
+>>> planet = hello.World()
+>>> planet.set('howdy')
+>>> planet.greet()
+'howdy'
+
+
+
+
Since our World class is just a plain struct , it has an
+implicit no-argument (nullary) constructor. Boost.Python exposes the
+nullary constructor by default, which is why we were able to write:
+
+>>> planet = hello.World()
+
+
However, well-designed classes in any language may require constructor
+arguments in order to establish their invariants. Unlike Python,
+where __init__ is just a specially-named method, In C++
+constructors cannot be handled like ordinary member functions. In
+particular, we can't take their address: &World::World is an
+error. The library provides a different interface for specifying
+constructors. Given:
+
+struct World
+{
+ World(std::string msg); // added constructor
+ ...
+
+
we can modify our wrapping code as follows:
+
+class_<World>("World", init<std::string>())
+ ...
+
+
of course, a C++ class may have additional constructors, and we can
+expose those as well by passing more instances of init<...> to
+def() :
+
+class_<World>("World", init<std::string>())
+ .def(init<double, double>())
+ ...
+
+
Boost.Python allows wrapped functions, member functions, and
+constructors to be overloaded to mirror C++ overloading.
+
+
+
+
Any publicly-accessible data members in a C++ class can be easily
+exposed as either readonly or readwrite attributes:
+
+class_<World>("World", init<std::string>())
+ .def_readonly("msg", &World::msg)
+ ...
+
+
and can be used directly in Python:
+
+>>> planet = hello.World('howdy')
+>>> planet.msg
+'howdy'
+
+
This does not result in adding attributes to the World instance
+__dict__ , which can result in substantial memory savings when
+wrapping large data structures. In fact, no instance __dict__
+will be created at all unless attributes are explicitly added from
+Python. Boost.Python owes this capability to the new Python 2.2 type
+system, in particular the descriptor interface and property type.
+
In C++, publicly-accessible data members are considered a sign of poor
+design because they break encapsulation, and style guides usually
+dictate the use of "getter" and "setter" functions instead. In
+Python, however, __getattr__ , __setattr__ , and since 2.2,
+property mean that attribute access is just one more
+well-encapsulated syntactic tool at the programmer's disposal.
+Boost.Python bridges this idiomatic gap by making Python property
+creation directly available to users. If msg were private, we
+could still expose it as attribute in Python as follows:
+
+class_<World>("World", init<std::string>())
+ .add_property("msg", &World::greet, &World::set)
+ ...
+
+
The example above mirrors the familiar usage of properties in Python
+2.2+:
+
+>>> class World(object):
+... __init__(self, msg):
+... self.__msg = msg
+... def greet(self):
+... return self.__msg
+... def set(self, msg):
+... self.__msg = msg
+... msg = property(greet, set)
+
+
+
+
+
The ability to write arithmetic operators for user-defined types has
+been a major factor in the success of both languages for numerical
+computation, and the success of packages like NumPy attests to the
+power of exposing operators in extension modules. Boost.Python
+provides a concise mechanism for wrapping operator overloads. The
+example below shows a fragment from a wrapper for the Boost rational
+number library:
+
+class_<rational<int> >("rational_int")
+ .def(init<int, int>()) // constructor, e.g. rational_int(3,4)
+ .def("numerator", &rational<int>::numerator)
+ .def("denominator", &rational<int>::denominator)
+ .def(-self) // __neg__ (unary minus)
+ .def(self + self) // __add__ (homogeneous)
+ .def(self * self) // __mul__
+ .def(self + int()) // __add__ (heterogenous)
+ .def(int() + self) // __radd__
+ ...
+
+
The magic is performed using a simplified application of "expression
+templates" [VELD1995] , a technique originally developed for
+optimization of high-performance matrix algebra expressions. The
+essence is that instead of performing the computation immediately,
+operators are overloaded to construct a type representing the
+computation. In matrix algebra, dramatic optimizations are often
+available when the structure of an entire expression can be taken into
+account, rather than evaluating each operation "greedily".
+Boost.Python uses the same technique to build an appropriate Python
+method object based on expressions involving self .
+
+
+
+
C++ inheritance relationships can be represented to Boost.Python by adding
+an optional bases<...> argument to the class_<...> template
+parameter list as follows:
+
+class_<Derived, bases<Base1,Base2> >("Derived")
+ ...
+
+
This has two effects:
+
+When the class_<...> is created, Python type objects
+corresponding to Base1 and Base2 are looked up in
+Boost.Python's registry, and are used as bases for the new Python
+Derived type object, so methods exposed for the Python Base1
+and Base2 types are automatically members of the Derived
+type. Because the registry is global, this works correctly even if
+Derived is exposed in a different module from either of its
+bases.
+C++ conversions from Derived to its bases are added to the
+Boost.Python registry. Thus wrapped C++ methods expecting (a
+pointer or reference to) an object of either base type can be
+called with an object wrapping a Derived instance. Wrapped
+member functions of class T are treated as though they have an
+implicit first argument of T& , so these conversions are
+neccessary to allow the base class methods to be called for derived
+objects.
+
+
Of course it's possible to derive new Python classes from wrapped C++
+class instances. Because Boost.Python uses the new-style class
+system, that works very much as for the Python built-in types. There
+is one significant detail in which it differs: the built-in types
+generally establish their invariants in their __new__ function, so
+that derived classes do not need to call __init__ on the base
+class before invoking its methods :
+
+>>> class L(list):
+... def __init__(self):
+... pass
+...
+>>> L().reverse()
+>>>
+
+
Because C++ object construction is a one-step operation, C++ instance
+data cannot be constructed until the arguments are available, in the
+__init__ function:
+
+>>> class D(SomeBoostPythonClass):
+... def __init__(self):
+... pass
+...
+>>> D().some_boost_python_method()
+Traceback (most recent call last):
+ File "<stdin>", line 1, in ?
+TypeError: bad argument type for built-in operation
+
+
This happened because Boost.Python couldn't find instance data of type
+SomeBoostPythonClass within the D instance; D 's __init__
+function masked construction of the base class. It could be corrected
+by either removing D 's __init__ function or having it call
+SomeBoostPythonClass.__init__(...) explicitly.
+
+
+
+
Deriving new types in Python from extension classes is not very
+interesting unless they can be used polymorphically from C++. In
+other words, Python method implementations should appear to override
+the implementation of C++ virtual functions when called through base
+class pointers/references from C++ . Since the only way to alter the
+behavior of a virtual function is to override it in a derived class,
+the user must build a special derived class to dispatch a polymorphic
+class' virtual functions:
+
+//
+// interface to wrap:
+//
+class Base
+{
+ public:
+ virtual int f(std::string x) { return 42; }
+ virtual ~Base();
+};
+
+int calls_f(Base const& b, std::string x) { return b.f(x); }
+
+//
+// Wrapping Code
+//
+
+// Dispatcher class
+struct BaseWrap : Base
+{
+ // Store a pointer to the Python object
+ BaseWrap(PyObject* self_) : self(self_) {}
+ PyObject* self;
+
+ // Default implementation, for when f is not overridden
+ int f_default(std::string x) { return this->Base::f(x); }
+ // Dispatch implementation
+ int f(std::string x) { return call_method<int>(self, "f", x); }
+};
+
+...
+ def("calls_f", calls_f);
+ class_<Base, BaseWrap>("Base")
+ .def("f", &Base::f, &BaseWrap::f_default)
+ ;
+
+
Now here's some Python code which demonstrates:
+
+>>> class Derived(Base):
+... def f(self, s):
+... return len(s)
+...
+>>> calls_f(Base(), 'foo')
+42
+>>> calls_f(Derived(), 'forty-two')
+9
+
+
Things to notice about the dispatcher class:
+
+The key element which allows overriding in Python is the
+call_method invocation, which uses the same global type
+conversion registry as the C++ function wrapping does to convert its
+arguments from C++ to Python and its return type from Python to C++.
+Any constructor signatures you wish to wrap must be replicated with
+an initial PyObject* argument
+The dispatcher must store this argument so that it can be used to
+invoke call_method
+The f_default member function is needed when the function being
+exposed is not pure virtual; there's no other way Base::f can be
+called on an object of type BaseWrap , since it overrides f .
+
+
+
+
+
Admittedly, this formula is tedious to repeat, especially on a project
+with many polymorphic classes. That it is neccessary reflects some
+limitations in C++'s compile-time introspection capabilities: there's
+no way to enumerate the members of a class and find out which are
+virtual functions. At least one very promising project has been
+started to write a front-end which can generate these dispatchers (and
+other wrapping code) automatically from C++ headers.
+
Pyste is being developed by Bruno da Silva de Oliveira. It builds on
+GCC_XML , which generates an XML version of GCC's internal program
+representation. Since GCC is a highly-conformant C++ compiler, this
+ensures correct handling of the most-sophisticated template code and
+full access to the underlying type system. In keeping with the
+Boost.Python philosophy, a Pyste interface description is neither
+intrusive on the code being wrapped, nor expressed in some unfamiliar
+language: instead it is a 100% pure Python script. If Pyste is
+successful it will mark a move away from wrapping everything directly
+in C++ for many of our users. It will also allow us the choice to
+shift some of the metaprogram code from C++ to Python. We expect that
+soon, not only our users but the Boost.Python developers themselves
+will be "thinking hybrid" about their own code.
+
+
+
+
+
Serialization is the process of converting objects in memory to a
+form that can be stored on disk or sent over a network connection. The
+serialized object (most often a plain string) can be retrieved and
+converted back to the original object. A good serialization system will
+automatically convert entire object hierarchies. Python's standard
+pickle module is just such a system. It leverages the language's strong
+runtime introspection facilities for serializing practically arbitrary
+user-defined objects. With a few simple and unintrusive provisions this
+powerful machinery can be extended to also work for wrapped C++ objects.
+Here is an example:
+
+#include <string>
+
+struct World
+{
+ World(std::string a_msg) : msg(a_msg) {}
+ std::string greet() const { return msg; }
+ std::string msg;
+};
+
+#include <boost/python.hpp>
+using namespace boost::python;
+
+struct World_picklers : pickle_suite
+{
+ static tuple
+ getinitargs(World const& w) { return make_tuple(w.greet()); }
+};
+
+BOOST_PYTHON_MODULE(hello)
+{
+ class_<World>("World", init<std::string>())
+ .def("greet", &World::greet)
+ .def_pickle(World_picklers())
+ ;
+}
+
+
Now let's create a World object and put it to rest on disk:
+
+>>> import hello
+>>> import pickle
+>>> a_world = hello.World("howdy")
+>>> pickle.dump(a_world, open("my_world", "w"))
+
+
In a potentially different script on a potentially different
+computer with a potentially different operating system :
+
+>>> import pickle
+>>> resurrected_world = pickle.load(open("my_world", "r"))
+>>> resurrected_world.greet()
+'howdy'
+
+
Of course the cPickle module can also be used for faster
+processing.
+
Boost.Python's pickle_suite fully supports the pickle protocol
+defined in the standard Python documentation. Like a __getinitargs__
+function in Python, the pickle_suite's getinitargs() is responsible for
+creating the argument tuple that will be use to reconstruct the pickled
+object. The other elements of the Python pickling protocol,
+__getstate__ and __setstate__ can be optionally provided via C++
+getstate and setstate functions. C++'s static type system allows the
+library to ensure at compile-time that nonsensical combinations of
+functions (e.g. getstate without setstate) are not used.
+
Enabling serialization of more complex C++ objects requires a little
+more work than is shown in the example above. Fortunately the
+object interface (see next section) greatly helps in keeping the
+code manageable.
+
+
+
+
Experienced 'C' language extension module authors will be familiar
+with the ubiquitous PyObject* , manual reference-counting, and the
+need to remember which API calls return "new" (owned) references or
+"borrowed" (raw) references. These constraints are not just
+cumbersome but also a major source of errors, especially in the
+presence of exceptions.
+
Boost.Python provides a class object which automates reference
+counting and provides conversion to Python from C++ objects of
+arbitrary type. This significantly reduces the learning effort for
+prospective extension module writers.
+
Creating an object from any other type is extremely simple:
+
+object s("hello, world"); // s manages a Python string
+
+
object has templated interactions with all other types, with
+automatic to-python conversions. It happens so naturally that it's
+easily overlooked:
+
+object ten_Os = 10 * s[4]; // -> "oooooooooo"
+
+
In the example above, 4 and 10 are converted to Python objects
+before the indexing and multiplication operations are invoked.
+
The extract<T> class template can be used to convert Python objects
+to C++ types:
+
+double x = extract<double>(o);
+
+
If a conversion in either direction cannot be performed, an
+appropriate exception is thrown at runtime.
+
The object type is accompanied by a set of derived types
+that mirror the Python built-in types such as list , dict ,
+tuple , etc. as much as possible. This enables convenient
+manipulation of these high-level types from C++:
+
+dict d;
+d["some"] = "thing";
+d["lucky_number"] = 13;
+list l = d.keys();
+
+
This almost looks and works like regular Python code, but it is pure
+C++. Of course we can wrap C++ functions which accept or return
+object instances.
+
+
+
+
+
Because of the practical and mental difficulties of combining
+programming languages, it is common to settle a single language at the
+outset of any development effort. For many applications, performance
+considerations dictate the use of a compiled language for the core
+algorithms. Unfortunately, due to the complexity of the static type
+system, the price we pay for runtime performance is often a
+significant increase in development time. Experience shows that
+writing maintainable C++ code usually takes longer and requires far
+more hard-earned working experience than developing comparable Python
+code. Even when developers are comfortable working exclusively in
+compiled languages, they often augment their systems by some type of
+ad hoc scripting layer for the benefit of their users without ever
+availing themselves of the same advantages.
+
Boost.Python enables us to think hybrid . Python can be used for
+rapidly prototyping a new application; its ease of use and the large
+pool of standard libraries give us a head start on the way to a
+working system. If necessary, the working code can be used to
+discover rate-limiting hotspots. To maximize performance these can
+be reimplemented in C++, together with the Boost.Python bindings
+needed to tie them back into the existing higher-level procedure.
+
Of course, this top-down approach is less attractive if it is clear
+from the start that many algorithms will eventually have to be
+implemented in C++. Fortunately Boost.Python also enables us to
+pursue a bottom-up approach. We have used this approach very
+successfully in the development of a toolbox for scientific
+applications. The toolbox started out mainly as a library of C++
+classes with Boost.Python bindings, and for a while the growth was
+mainly concentrated on the C++ parts. However, as the toolbox is
+becoming more complete, more and more newly added functionality can be
+implemented in Python.
+
+
This figure shows the estimated ratio of newly added C++ and Python
+code over time as new algorithms are implemented. We expect this
+ratio to level out near 70% Python. Being able to solve new problems
+mostly in Python rather than a more difficult statically typed
+language is the return on our investment in Boost.Python. The ability
+to access all of our code from Python allows a broader group of
+developers to use it in the rapid development of new applications.
+
+
+
+
The first version of Boost.Python was developed in 2000 by Dave
+Abrahams at Dragon Systems, where he was privileged to have Tim Peters
+as a guide to "The Zen of Python". One of Dave's jobs was to develop
+a Python-based natural language processing system. Since it was
+eventually going to be targeting embedded hardware, it was always
+assumed that the compute-intensive core would be rewritten in C++ to
+optimize speed and memory footprint. The project also wanted to
+test all of its C++ code using Python test scripts. The only
+tool we knew of for binding C++ and Python was SWIG , and at the time
+its handling of C++ was weak. It would be false to claim any deep
+insight into the possible advantages of Boost.Python's approach at
+this point. Dave's interest and expertise in fancy C++ template
+tricks had just reached the point where he could do some real damage,
+and Boost.Python emerged as it did because it filled a need and
+because it seemed like a cool thing to try.
+
This early version was aimed at many of the same basic goals we've
+described in this paper, differing most-noticeably by having a
+slightly more cumbersome syntax and by lack of special support for
+operator overloading, pickling, and component-based development.
+These last three features were quickly added by Ullrich Koethe and
+Ralf Grosse-Kunstleve, and other enthusiastic contributors arrived
+on the scene to contribute enhancements like support for nested
+modules and static member functions.
+
By early 2001 development had stabilized and few new features were
+being added, however a disturbing new fact came to light: Ralf had
+begun testing Boost.Python on pre-release versions of a compiler using
+the EDG front-end, and the mechanism at the core of Boost.Python
+responsible for handling conversions between Python and C++ types was
+failing to compile. As it turned out, we had been exploiting a very
+common bug in the implementation of all the C++ compilers we had
+tested. We knew that as C++ compilers rapidly became more
+standards-compliant, the library would begin failing on more
+platforms. Unfortunately, because the mechanism was so central to the
+functioning of the library, fixing the problem looked very difficult.
+
Fortunately, later that year Lawrence Berkeley and later Lawrence
+Livermore National labs contracted with Boost Consulting for support
+and development of Boost.Python, and there was a new opportunity to
+address fundamental issues and ensure a future for the library. A
+redesign effort began with the low level type conversion architecture,
+building in standards-compliance and support for component-based
+development (in contrast to version 1 where conversions had to be
+explicitly imported and exported across module boundaries). A new
+analysis of the relationship between the Python and C++ objects was
+done, resulting in more intuitive handling for C++ lvalues and
+rvalues.
+
The emergence of a powerful new type system in Python 2.2 made the
+choice of whether to maintain compatibility with Python 1.5.2 easy:
+the opportunity to throw away a great deal of elaborate code for
+emulating classic Python classes alone was too good to pass up. In
+addition, Python iterators and descriptors provided crucial and
+elegant tools for representing similar C++ constructs. The
+development of the generalized object interface allowed us to
+further shield C++ programmers from the dangers and syntactic burdens
+of the Python 'C' API. A great number of other features including C++
+exception translation, improved support for overloaded functions, and
+most significantly, CallPolicies for handling pointers and
+references, were added during this period.
+
In October 2002, version 2 of Boost.Python was released. Development
+since then has concentrated on improved support for C++ runtime
+polymorphism and smart pointers. Peter Dimov's ingenious
+boost::shared_ptr design in particular has allowed us to give the
+hybrid developer a consistent interface for moving objects back and
+forth across the language barrier without loss of information. At
+first, we were concerned that the sophistication and complexity of the
+Boost.Python v2 implementation might discourage contributors, but the
+emergence of Pyste and several other significant feature
+contributions have laid those fears to rest. Daily questions on the
+Python C++-sig and a backlog of desired improvements show that the
+library is getting used. To us, the future looks bright.
+
+
+
+
Boost.Python achieves seamless interoperability between two rich and
+complimentary language environments. Because it leverages template
+metaprogramming to introspect about types and functions, the user
+never has to learn a third syntax: the interface definitions are
+written in concise and maintainable C++. Also, the wrapping system
+doesn't have to parse C++ headers or represent the type system: the
+compiler does that work for us.
+
Computationally intensive tasks play to the strengths of C++ and are
+often impossible to implement efficiently in pure Python, while jobs
+like serialization that are trivial in Python can be very difficult in
+pure C++. Given the luxury of building a hybrid software system from
+the ground up, we can approach design with new confidence and power.
+
+
+
+
+
+
diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css
new file mode 100644
index 00000000..28f89359
--- /dev/null
+++ b/doc/html/boostbook.css
@@ -0,0 +1,716 @@
+
+/*=============================================================================
+Copyright (c) 2004 Joel de Guzman
+http://spirit.sourceforge.net/
+
+Copyright 2013 Niall Douglas additions for colors and alignment.
+Copyright 2013 Paul A. Bristow additions for more colors and alignments.
+
+Distributed under the Boost Software License, Version 1.0. (See accompany-
+ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+/*=============================================================================
+Body defaults
+=============================================================================*/
+
+ body
+ {
+ margin: 1em;
+ font-family: sans-serif;
+ }
+
+/*=============================================================================
+Paragraphs
+=============================================================================*/
+
+ p
+ {
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.15;
+ }
+
+/*=============================================================================
+Program listings
+=============================================================================*/
+
+ /* Code on paragraphs */
+ p tt.computeroutput
+ {
+ font-size: 9pt;
+ }
+
+ pre.synopsis
+ {
+ font-size: 9pt;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ .programlisting,
+ .screen
+ {
+ font-size: 9pt;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ /* Program listings in tables don't get borders */
+ td .programlisting,
+ td .screen
+ {
+ margin: 0pc 0pc 0pc 0pc;
+ padding: 0pc 0pc 0pc 0pc;
+ }
+
+/*=============================================================================
+Headings
+=============================================================================*/
+
+ h1, h2, h3, h4, h5, h6
+ {
+ text-align: left;
+ margin: 1em 0em 0.5em 0em;
+ font-weight: bold;
+ }
+
+ h1 { font-size: 140%; }
+ h2 { font-weight: bold; font-size: 140%; }
+ h3 { font-weight: bold; font-size: 130%; }
+ h4 { font-weight: bold; font-size: 120%; }
+ h5 { font-weight: normal; font-style: italic; font-size: 110%; }
+ h6 { font-weight: normal; font-style: italic; font-size: 100%; }
+
+ /* Top page titles */
+ title,
+ h1.title,
+ h2.title
+ h3.title,
+ h4.title,
+ h5.title,
+ h6.title,
+ .refentrytitle
+ {
+ font-weight: bold;
+ margin-bottom: 1pc;
+ }
+
+ h1.title { font-size: 140% }
+ h2.title { font-size: 140% }
+ h3.title { font-size: 130% }
+ h4.title { font-size: 120% }
+ h5.title { font-size: 110% }
+ h6.title { font-size: 100% }
+
+ .section h1
+ {
+ margin: 0em 0em 0.5em 0em;
+ font-size: 140%;
+ }
+
+ .section h2 { font-size: 140% }
+ .section h3 { font-size: 130% }
+ .section h4 { font-size: 120% }
+ .section h5 { font-size: 110% }
+ .section h6 { font-size: 100% }
+
+ /* Code on titles */
+ h1 tt.computeroutput { font-size: 140% }
+ h2 tt.computeroutput { font-size: 140% }
+ h3 tt.computeroutput { font-size: 130% }
+ h4 tt.computeroutput { font-size: 130% }
+ h5 tt.computeroutput { font-size: 130% }
+ h6 tt.computeroutput { font-size: 130% }
+
+
+/*=============================================================================
+Author
+=============================================================================*/
+
+ h3.author
+ {
+ font-size: 100%
+ }
+
+/*=============================================================================
+Lists
+=============================================================================*/
+
+ li
+ {
+ font-size: 10pt;
+ line-height: 1.3;
+ }
+
+ /* Unordered lists */
+ ul
+ {
+ text-align: left;
+ }
+
+ /* Ordered lists */
+ ol
+ {
+ text-align: left;
+ }
+
+/*=============================================================================
+Links
+=============================================================================*/
+
+ a
+ {
+ text-decoration: none; /* no underline */
+ }
+
+ a:hover
+ {
+ text-decoration: underline;
+ }
+
+/*=============================================================================
+Spirit style navigation
+=============================================================================*/
+
+ .spirit-nav
+ {
+ text-align: right;
+ }
+
+ .spirit-nav a
+ {
+ color: white;
+ padding-left: 0.5em;
+ }
+
+ .spirit-nav img
+ {
+ border-width: 0px;
+ }
+
+/*=============================================================================
+Copyright footer
+=============================================================================*/
+ .copyright-footer
+ {
+ text-align: right;
+ font-size: 70%;
+ }
+
+ .copyright-footer p
+ {
+ text-align: right;
+ font-size: 80%;
+ }
+
+/*=============================================================================
+Table of contents
+=============================================================================*/
+
+ div.toc
+ {
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.1pc 1pc 0.1pc 1pc;
+ font-size: 80%;
+ line-height: 1.15;
+ }
+
+ .boost-toc
+ {
+ float: right;
+ padding: 0.5pc;
+ }
+
+ /* Code on toc */
+ .toc .computeroutput { font-size: 120% }
+
+ /* No margin on nested menus */
+
+ .toc dl dl { margin: 0; }
+
+/*=============================================================================
+Tables
+=============================================================================*/
+
+ .table-title,
+ div.table p.title
+ {
+ margin-left: 4%;
+ padding-right: 0.5em;
+ padding-left: 0.5em;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ width: 92%;
+ margin-left: 4%;
+ margin-right: 4%;
+ }
+
+ div.informaltable table,
+ div.table table
+ {
+ padding: 4px;
+ }
+
+ /* Table Cells */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ padding: 0.5em;
+ text-align: left;
+ font-size: 9pt;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ padding: 0.5em 0.5em 0.5em 0.5em;
+ border: 1pt solid white;
+ font-size: 80%;
+ }
+
+ table.simplelist
+ {
+ width: auto !important;
+ margin: 0em !important;
+ padding: 0em !important;
+ border: none !important;
+ }
+ table.simplelist td
+ {
+ margin: 0em !important;
+ padding: 0em !important;
+ text-align: left !important;
+ font-size: 9pt !important;
+ border: none !important;
+ }
+
+/*=============================================================================
+Suppress margins in tables
+=============================================================================*/
+
+ table th > *:first-child,
+ table td > *:first-child
+ {
+ margin-top: 0;
+ }
+
+ table th > *:last-child,
+ table td > *:last-child
+ {
+ margin-bottom: 0;
+ }
+
+/*=============================================================================
+Blurbs
+=============================================================================*/
+
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ p.blurb
+ {
+ font-size: 9pt; /* A little bit smaller than the main text */
+ line-height: 1.2;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ p.blurb img
+ {
+ padding: 1pt;
+ }
+
+/*=============================================================================
+Variable Lists
+=============================================================================*/
+
+ div.variablelist
+ {
+ margin: 1em 0;
+ }
+
+ /* Make the terms in definition lists bold */
+ div.variablelist dl dt,
+ span.term
+ {
+ font-weight: bold;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td
+ {
+ text-align: left;
+ vertical-align: top;
+ padding: 0em 2em 0em 0em;
+ font-size: 10pt;
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+ div.variablelist dl dt
+ {
+ margin-bottom: 0.2em;
+ }
+
+ div.variablelist dl dd
+ {
+ margin: 0em 0em 0.5em 2em;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td p,
+ div.variablelist dl dd p
+ {
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+/*=============================================================================
+Misc
+=============================================================================*/
+
+ /* Title of books and articles in bibliographies */
+ span.title
+ {
+ font-style: italic;
+ }
+
+ span.underline
+ {
+ text-decoration: underline;
+ }
+
+ span.strikethrough
+ {
+ text-decoration: line-through;
+ }
+
+ /* Copyright, Legal Notice */
+ div div.legalnotice p
+ {
+ text-align: left
+ }
+
+/*=============================================================================
+Colors
+=============================================================================*/
+
+ @media screen
+ {
+ body {
+ background-color: #FFFFFF;
+ color: #000000;
+ }
+
+ /* Syntax Highlighting */
+ .keyword { color: #0000AA; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #402080; }
+ .char { color: teal; }
+ .comment { color: #800000; }
+ .string { color: teal; }
+ .number { color: teal; }
+ .white_bkd { background-color: #FFFFFF; }
+ .dk_grey_bkd { background-color: #999999; }
+
+ /* Links */
+ a, a .keyword, a .identifier, a .special, a .preprocessor
+ a .char, a .comment, a .string, a .number
+ {
+ color: #005a9c;
+ }
+
+ a:visited, a:visited .keyword, a:visited .identifier,
+ a:visited .special, a:visited .preprocessor a:visited .char,
+ a:visited .comment, a:visited .string, a:visited .number
+ {
+ color: #9c5a9c;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ {
+ text-decoration: none; /* no underline */
+ color: #000000;
+ }
+
+ /* Copyright, Legal Notice */
+ .copyright
+ {
+ color: #666666;
+ font-size: small;
+ }
+
+ div div.legalnotice p
+ {
+ color: #666666;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Blurbs */
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ p.blurb
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ div.toc
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ background-color: #F0F0F0;
+ border: 1px solid #DCDCDC;
+ }
+
+ .copyright-footer
+ {
+ color: #8F8F8F;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ color: #00A000;
+ }
+ }
+
+ @media print
+ {
+ /* Links */
+ a
+ {
+ color: black;
+ }
+
+ a:visited
+ {
+ color: black;
+ }
+
+ .spirit-nav
+ {
+ display: none;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid gray;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid gray;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ div.toc
+ {
+ border: 1px solid gray;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ border: 1px solid gray;
+ border-collapse: collapse;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid gray;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ border: 1px solid gray;
+ }
+
+ table.simplelist tr td
+ {
+ border: none !important;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ font-weight: bold;
+ }
+ }
+
+/*=============================================================================
+Images
+=============================================================================*/
+
+ span.inlinemediaobject img
+ {
+ vertical-align: middle;
+ }
+
+/*==============================================================================
+Super and Subscript: style so that line spacing isn't effected, see
+http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341
+==============================================================================*/
+
+sup,
+sub {
+height: 0;
+line-height: 1;
+vertical-align: baseline;
+position: relative;
+
+}
+
+/* For internet explorer: */
+
+* html sup,
+* html sub {
+vertical-align: bottom;
+}
+
+sup {
+bottom: 1ex;
+}
+
+sub {
+top: .5ex;
+}
+
+/*==============================================================================
+Indexes: pretty much the same as the TOC.
+==============================================================================*/
+
+ .index
+ {
+ font-size: 80%;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ margin-left: 0px;
+ }
+
+ .index ul
+ {
+ padding-left: 3em;
+ }
+
+ .index p
+ {
+ padding: 2px;
+ margin: 2px;
+ }
+
+ .index-entry-level-0
+ {
+ font-weight: bold;
+ }
+
+ .index em
+ {
+ font-weight: bold;
+ }
+
+
+/*==============================================================================
+Alignment and coloring use 'role' feature, available from Quickbook 1.6 up.
+Added from Niall Douglas for role color and alignment.
+http://article.gmane.org/gmane.comp.lib.boost.devel/243318
+*/
+
+/* Add text alignment (see http://www.w3schools.com/cssref/pr_text_text-align.asp) */
+span.aligncenter
+{
+ display: inline-block; width: 100%; text-align: center;
+}
+span.alignright
+{
+ display: inline-block; width: 100%; text-align: right;
+}
+/* alignleft is the default. */
+span.alignleft
+{
+ display: inline-block; width: 100%; text-align: left;
+}
+
+/* alignjustify stretches the word spacing so that each line has equal width
+within a chosen fraction of page width (here arbitrarily 20%).
+*Not* useful inside table items as the column width remains the total string width.
+Nor very useful, except to temporarily restrict the width.
+*/
+span.alignjustify
+{
+ display: inline-block; width: 20%; text-align: justify;
+}
+
+/* Text colors.
+Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywords.
+Quickbook Usage: [role red Some red text]
+
+*/
+span.red { inline-block; color: red; }
+span.green { color: green; }
+span.lime { color: #00FF00; }
+span.blue { color: blue; }
+span.navy { color: navy; }
+span.yellow { color: yellow; }
+span.magenta { color: magenta; }
+span.indigo { color: #4B0082; }
+span.cyan { color: cyan; }
+span.purple { color: purple; }
+span.gold { color: gold; }
+span.silver { color: silver; } /* lighter gray */
+span.gray { color: #808080; } /* light gray */
diff --git a/doc/html/building.html b/doc/html/building.html
new file mode 100644
index 00000000..0d5c0571
--- /dev/null
+++ b/doc/html/building.html
@@ -0,0 +1,61 @@
+
+
+
+Chapter 2. Building and Testing
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 2. Building and Testing
+
+
Copyright © 2002-2015 David Abrahams, Stefan Seefeld
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/building/background.html b/doc/html/building/background.html
new file mode 100644
index 00000000..d1d85155
--- /dev/null
+++ b/doc/html/building/background.html
@@ -0,0 +1,70 @@
+
+
+
+Background
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There are two basic models for combining C++ and Python:
+
+
+
+ extending ,
+ in which the end-user launches the Python interpreter executable and
+ imports Python “extension modules” written in C++. Think of taking
+ a library written in C++ and giving it a Python interface so Python programmers
+ can use it. From Python, these modules look just like regular Python
+ modules.
+
+
+ embedding ,
+ in which the end-user launches a program written in C++ that in turn
+ invokes the Python interpreter as a library subroutine. Think of adding
+ scriptability to an existing application.
+
+
+
+ The key distinction between extending and embedding is the location of the
+ C++ main ()
+ function: in the Python interpreter executable, or in some other program,
+ respectively. Note that even when embedding Python in another program, extension
+ modules are often the best way to make C/C++ functionality accessible to
+ Python code , so the use of extension modules is really at the heart
+ of both models.
+
+
+ Except in rare cases, extension modules are built as dynamically-loaded libraries
+ with a single entry point, which means you can change them without rebuilding
+ either the other extension modules or the executable containing main () .
+
+
+
+
+
+
+
diff --git a/doc/html/building/choosing_a_boost_python_library_.html b/doc/html/building/choosing_a_boost_python_library_.html
new file mode 100644
index 00000000..58663404
--- /dev/null
+++ b/doc/html/building/choosing_a_boost_python_library_.html
@@ -0,0 +1,128 @@
+
+
+
+Choosing a Boost.Python Library Binary
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ If—instead of letting Boost.Build construct and link with the right libraries
+ automatically—you choose to use a pre-built Boost.Python library, you'll
+ need to think about which one to link with. The Boost.Python binary comes
+ in both static and dynamic flavors. Take care to choose the right flavor
+ for your application.
+
+
+
+
+ The dynamic library is the safest and most-versatile choice:
+
+
+
+ A single copy of the library code is used by all extension modules
+ built with a given toolset.
+
+
+ The library contains a type conversion registry. Because one registry
+ is shared among all extension modules, instances of a class exposed
+ to Python in one dynamically-loaded extension module can be passed
+ to functions exposed in another such module.
+
+
+
+
+
+
+ It might be appropriate to use the static Boost.Python library in any of
+ the following cases:
+
+
+
+ You are extending
+ python and the types exposed in your dynamically-loaded extension module
+ don't need to be used by any other Boost.Python extension modules,
+ and you don't care if the core library code is duplicated among them.
+
+
+ You are embedding
+ python in your application and either:
+
+
+ You are targeting a Unix variant OS other than MacOS or AIX,
+ where the dynamically-loaded extension modules can “see”
+ the Boost.Python library symbols that are part of the executable.
+
+
+ Or, you have statically linked some Boost.Python extension modules
+ into your application and you don't care if any dynamically-loaded
+ Boost.Python extension modules are able to use the types exposed
+ by your statically-linked extension modules (and vice-versa).
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/building/configuring_boost_build.html b/doc/html/building/configuring_boost_build.html
new file mode 100644
index 00000000..e82a74e6
--- /dev/null
+++ b/doc/html/building/configuring_boost_build.html
@@ -0,0 +1,264 @@
+
+
+
+Configuring Boost.Build
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ As described in the Boost.Build
+ Reference Manual , a file called user - config . jam in
+ your home directory is used to specify the tools and libraries available
+ to the build system. You may need to create or edit user - config . jam to
+ tell Boost.Build how to invoke Python, #include
+ its headers, and link with its libraries.
+
+
+
+
+Note
+
+
+ If you are using a unix-variant OS and you ran Boost's configure
+ script, it may have generated a user - config . jam
+ for you. If your configure /make sequence was successful and Boost.Python
+ binaries were built, your user - config . jam
+ file is probably already correct.
+
+
+
+ If you have one fairly “standard” python installation for your platform,
+ you might not need to do anything special to describe it. If you haven't
+ configured python in user - config . jam (and
+ you don't specify -- without - python
+ on the Boost.Build command line), Boost.Build will automatically execute
+ the equivalent of
+
+
import toolset : using ;
+using python ;
+
+
+ which automatically looks for Python in the most likely places. However,
+ that only happens when using the Boost.Python project file (e.g. when referred
+ to by another project as in the quickstart method). If instead you are linking
+ against separately-compiled Boost.Python binaries, you should set up a user - config . jam file
+ with at least the minimal incantation above.
+
+
+
+
+ If you have several versions of Python installed, or Python is installed
+ in an unusual way, you may want to supply any or all of the following optional
+ parameters to using python .
+
+
+
+
+version
+
+ the version of Python to use. Should be in Major.Minor format, for
+ example, 2.3 . Do not
+ include the subminor version (i.e. not
+ 2.5 . 1 ). If you have multiple Python versions
+ installed, the version will usually be the only configuration argument
+ required.
+
+cmd-or-prefix
+
+ preferably, a command that invokes a Python interpreter. Alternatively,
+ the installation prefix for Python libraries and header files. Only
+ use the alternative formulation if there is no appropriate Python
+ executable available.
+
+includes
+
+ the #include paths
+ for Python headers. Normally the correct path(s) will be automatically
+ deduced from version
+ and/or cmd - or - prefix .
+
+libraries
+
+ the path to Python library binaries. On MacOS/Darwin, you can also
+ pass the path of the Python framework. Normally the correct path(s)
+ will be automatically deduced from version
+ and/or cmd - or - prefix .
+
+condition
+
+ if specified, should be a set of Boost.Build properties that are
+ matched against the build configuration when Boost.Build selects
+ a Python configuration to use. See examples below for details.
+
+extension-suffix
+
+ A string to append to the name of extension modules before the true
+ filename extension. You almost certainly don't need to use this.
+ Usually this suffix is only used when targeting a Windows debug build
+ of Python, and will be set automatically for you based on the value
+ of the <python-debugging>
+ feature. However, at least one Linux distribution (Ubuntu Feisty
+ Fawn) has a specially configured <python-dbg>
+ package that claims to use such a suffix.
+
+
+
+
+
+
+
+ Note that in the examples below, case and especially
+ whitespace are significant.
+
+
+
+
+ If you have both python 2.5 and python 2.4 installed, user - config . jam might contain
+
+using python : 2.5 ; # Make both versions of Python available
+using python : 2.4 ; # To build with python 2.4 , add python = 2.4
+ # to your command line .
+
+
+ The first version configured (2.5) becomes the default. To build against
+ python 2.4, add python = 2.4
+ to the bjam command
+ line.
+
+
+
+
+ If you have python installed in an unusual location, you might supply
+ the path to the interpreter in the cmd - or - prefix
+ parameter:
+
+using python : : / usr / local / python - 2.6 - beta / bin / python ;
+
+
+
+
+ If you have a separate build of Python for use with a particular toolset,
+ you might supply that toolset in the condition
+ parameter:
+
+using python ; # use for most toolsets
+
+# Use with Intel C ++ toolset
+using python
+ : # version
+ : c :\\ Devel \\ Python - 2.5 - IntelBuild \\ PCBuild \\ python # cmd - or - prefix
+ : # includes
+ : # libraries
+ : < toolset > intel # condition
+ ;
+
+
+
+
+ If you have downloaded the Python sources and built both the normal
+ and the "python
+ debugging" builds from source on Windows, you might see:
+
+using python : 2.5 : C :\\ src \\ Python - 2.5 \\ PCBuild \\ python ;
+using python : 2.5 : C :\\ src \\ Python - 2.5 \\ PCBuild \\ python_d
+ : # includes
+ : # libs
+ : < python - debugging > on ;
+
+
+
+
+ You can set up your user-config.jam so a bjam built under Windows can
+ build/test both Windows and Cygwin_ python extensions. Just pass < target - os > cygwin
+ in the condition parameter
+ for the cygwin python installation:
+
+# windows installation
+using python ;
+
+# cygwin installation
+using python : : c :\\ cygwin \\ bin \\ python2 . 5 : : : < target - os > cygwin ;
+
+
+ when you put target-os=cygwin in your build request, it should build
+ with the cygwin version of python: _
+
+bjam target - os = cygwin toolset = gcc
+
+
+ This is supposed to work the other way, too (targeting windows python
+ with a Cygwin bjam) but it seems
+ as though the support in Boost.Build's toolsets for building that way
+ is broken at the time of this writing.
+
+
+
+
+ Note that because of the
+ way Boost.Build currently selects target alternatives , you
+ might have be very explicit in your build requests. For example, given:
+
+using python : 2.5 ; # a regular windows build
+using python : 2.4 : : : : < target - os > cygwin ;
+
+
+ building with
+
+bjam target - os = cygwin
+
+
+ will yield an error. Instead, you'll need to write
+
+bjam target - os = cygwin / python = 2.4
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/building/include_issues.html b/doc/html/building/include_issues.html
new file mode 100644
index 00000000..6ba4d059
--- /dev/null
+++ b/doc/html/building/include_issues.html
@@ -0,0 +1,53 @@
+
+
+
+#include Issues
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1. If you should ever have occasion to #include
+ "python.h" directly in a
+ translation unit of a program using Boost.Python, use #include
+ "boost/python/detail/wrap_python.hpp"
+ instead. It handles several issues necessary for use with Boost.Python, one
+ of which is mentioned in the next section.
+
+
+ 2. Be sure not to #include
+ any system headers before wrap_python . hpp . This
+ restriction is actually imposed by Python, or more properly, by Python's
+ interaction with your operating system. See http://docs.python.org/ext/simpleExample.html
+ for details.
+
+
+
+
+
+
+
diff --git a/doc/html/building/installing_boost_python_on_your_.html b/doc/html/building/installing_boost_python_on_your_.html
new file mode 100644
index 00000000..6ab4c4c3
--- /dev/null
+++ b/doc/html/building/installing_boost_python_on_your_.html
@@ -0,0 +1,52 @@
+
+
+
+Installing Boost.Python on your System
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Since Boost.Python is a separately-compiled (as opposed to header - only ) library, its user relies on the services
+ of a Boost.Python library binary.
+
+
+ If you need a regular installation of the Boost.Python library binaries on
+ your system, the Boost Getting
+ Started Guide will walk you through the steps of creating one. If
+ building binaries from source, you might want to supply the -- with - python
+ argument to bjam (or the
+ -- with - libraries = python
+ argument to configure ), so
+ only the Boost.Python binary will be built, rather than all the Boost binaries.
+
+
+
+
+
+
+
diff --git a/doc/html/building/no_install_quickstart.html b/doc/html/building/no_install_quickstart.html
new file mode 100644
index 00000000..7273dee3
--- /dev/null
+++ b/doc/html/building/no_install_quickstart.html
@@ -0,0 +1,318 @@
+
+
+
+No-Install Quickstart
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ There is no need to “install Boost” in order to get started using Boost.Python.
+ These instructions use Boost.Build
+ projects, which will build those binaries as soon as they're needed. Your
+ first tests may take a little longer while you wait for Boost.Python to build,
+ but doing things this way will save you from worrying about build intricacies
+ like which library binaries to use for a specific compiler configuration
+ and figuring out the right compiler options to use yourself.
+
+
+
+
+Note
+
+
+
+ Of course it's possible to use other build systems to build Boost.Python
+ and its extensions, but they are not officially supported by Boost. Moreover
+ 99% of all “I can't build Boost.Python” problems
+ come from trying to use another build system without first following
+ these instructions.
+
+
+ If you want to use another system anyway, we suggest that you follow these
+ instructions, and then invoke bjam
+ with the
+
+
+ - a
+ - o filename
+
+
+ options to dump the build commands it executes to a file, so you can see
+ what your alternate build system needs to do.
+
+
+
+
+
+
+ 1. Get Boost; see sections 1 and 2 of the Boost Getting
+ Started Guide .
+
+
+ 2. Get the bjam build driver.
+ See section 5 of the Boost Getting
+ Started Guide .
+
+
+ 3. cd into the example / quickstart / directory of your Boost.Python installation,
+ which contains a small example project.
+
+
+ 4. Invoke bjam . Replace
+ the “stage “ argument
+ from the example invocation from section 5 of the Boost Getting
+ Started Guide with “test ,“
+ to build all the test targets. Also add the argument “-- verbose - test ” to see the output generated by
+ the tests when they are run. On Windows, your bjam
+ invocation might look something like:
+
+
C :\\...\\ quickstart > bjam toolset = msvc -- verbose - test test
+
+
+ and on Unix variants, perhaps,
+
+
.../ quickstart $ bjam toolset = gcc -- verbose - test test
+
+
+
+
+Note
+
+
+ For the sake of concision, the rest of this guide will use unix-style
+ forward slashes in pathnames instead of the backslashes with which Windows
+ users may be more familiar. The forward slashes should work everywhere
+ except in Command
+ Prompt windows, where you should use backslashes.
+
+
+
+ If you followed this procedure successfully, you will have built an extension
+ module called extending
+ and tested it by running a Python script called test_extending . py .
+ You will also have built and run a simple application called embedding that embeds python.
+
+
+
+
+
+ If you're seeing lots of compiler and/or linker error messages, it's probably
+ because Boost.Build is having trouble finding your Python installation.
+ You might want to pass the -- debug - configuration option to bjam the first few times you invoke it,
+ to make sure that Boost.Build is correctly locating all the parts of your
+ Python installation. If it isn't, consider Configuring
+ Boost.Build as detailed below.
+
+
+ If you're still having trouble, Someone on one of the following mailing
+ lists may be able to help:
+
+
+
+
+
+
+ Rejoice! If you're new to Boost.Python, at this point it might be a good
+ idea to ignore build issues for a while and concentrate on learning the
+ library by going through the Tutorial
+ and perhaps some of the Reference Manual ,
+ trying out what you've learned about the API by modifying the quickstart
+ project.
+
+
+
+
+
+
+ If you're content to keep your extension module forever in one source file
+ called extending . cpp , inside your Boost.Python distribution,
+ and import it forever as extending ,
+ then you can stop here. However, it's likely that you will want to make
+ a few changes. There are a few things you can do without having to learn
+ Boost.Build in depth.
+
+
+ The project you just built is specified in two files in the current directory:
+ boost - build . jam , which tells bjam
+ where it can find the interpreted code of the Boost build system, and
+ Jamroot , which describes
+ the targets you just built. These files are heavily commented, so they
+ should be easy to modify. Take care, however, to preserve whitespace. Punctuation
+ such as ; will not be recognized
+ as intended by bjam if
+ it is not surrounded by whitespace.
+
+
+
+
+ You'll probably want to copy this project elsewhere so you can change
+ it without modifying your Boost distribution. To do that, simply
+
+
+ a. copy the entire example / quickstart / directory into a new directory.
+
+
+ b. In the new copies of boost - build . jam
+ and Jamroot , locate the
+ relative path near the top of the file that is clearly marked by a comment,
+ and edit that path so that it refers to the same directory your Boost
+ distribution as it referred to when the file was in its original location
+ in the example / quickstart /
+ directory.
+
+
+ For example, if you moved the project from / home / dave / boost_1_34_0 / libs / python / example / quickstart to / home / dave / my - project , you could change the first
+ path in boost - build . jam from
+
+
../../../../ tools / build / src
+
+
+ to
+
+
/ home / dave / boost_1_34_0 / tools / build / src
+
+
+ and change the first path in Jamroot
+ from
+
+
../../../..
+
+
+ to
+
+
/ home / dave / boost_1_34_0
+
+
+
+
+
+ The names of additional source files involved in building your extension
+ module or embedding application can be listed in Jamroot
+ right alongside extending . cpp
+ or embedding . cpp respectively. Just be sure to leave
+ whitespace around each filename:
+
+
… file1 . cpp file2 . cpp file3 . cpp …
+
+
+ Naturally, if you want to change the name of a source file you can tell
+ Boost.Build about it by editing the name in Jamroot .
+
+
+
+
+
+ The name of the extension module is determined by two things:
+
+
+
+ the name in Jamroot
+ immediately following python - extension ,
+ and
+
+
+ the name passed to BOOST_PYTHON_MODULE
+ in extending . cpp .
+
+
+
+ To change the name of the extension module from extending
+ to hello , you'd edit
+ Jamroot , changing
+
+
python - extension extending : extending . cpp ;
+
+
+ to
+
+
python - extension hello : extending . cpp ;
+
+
+ and you'd edit extending.cpp, changing
+
+
BOOST_PYTHON_MODULE ( extending )
+
+
+ to
+
+
BOOST_PYTHON_MODULE ( hello )
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/building/notes_for_mingw_and_cygwin_with_.html b/doc/html/building/notes_for_mingw_and_cygwin_with_.html
new file mode 100644
index 00000000..a51035d5
--- /dev/null
+++ b/doc/html/building/notes_for_mingw_and_cygwin_with_.html
@@ -0,0 +1,47 @@
+
+
+
+Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are using a version of Python prior to 2.4.1 with a MinGW prior to
+ 3.0.0 (with binutils-2.13.90-20030111-1), you will need to create a MinGW-compatible
+ version of the Python library; the one shipped with Python will only work
+ with a Microsoft-compatible linker. Follow the instructions in the “Non-Microsoft”
+ section of the “Building Extensions: Tips And Tricks” chapter in Installing Python Modules
+ to create libpythonXX . a , where XX
+ corresponds to the major and minor version numbers of your Python installation.
+
+
+
+
+
+
+
diff --git a/doc/html/building/python_debugging_builds.html b/doc/html/building/python_debugging_builds.html
new file mode 100644
index 00000000..357d732d
--- /dev/null
+++ b/doc/html/building/python_debugging_builds.html
@@ -0,0 +1,78 @@
+
+
+
+Python Debugging Builds
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Python can be built in a special “python debugging” configuration that
+ adds extra checks and instrumentation that can be very useful for developers
+ of extension modules. The data structures used by the debugging configuration
+ contain additional members, so a Python executable
+ built with python debugging enabled cannot be used with an extension module
+ or library compiled without it, and vice-versa.
+
+
+ Since pre-built “python debugging” versions of the Python executable
+ and libraries are not supplied with most distributions of Python, and we didn't want to force our users to build them, Boost.Build
+ does not automatically enable python debugging in its debug
+ build variant (which is the default). Instead there is a special build property
+ called python - debugging that, when used as a build property,
+ will define the right preprocessor symbols and select the right libraries
+ to link with.
+
+
+ On unix-variant platforms, the debugging versions of Python's data structures
+ will only be used if the symbol Py_DEBUG
+ is defined. On many windows compilers, when extension modules are built with
+ the preprocessor symbol _DEBUG ,
+ Python defaults to force linking with a special debugging version of the
+ Python DLL. Since that symbol is very commonly used even when Python is not
+ present, Boost.Python temporarily undefines _DEBUG
+ when Python . h is #included from boost / python / detail / wrap_python . hpp -
+ unless BOOST_DEBUG_PYTHON
+ is defined. The upshot is that if you want “python debugging”and you
+ aren't using Boost.Build, you should make sure BOOST_DEBUG_PYTHON
+ is defined, or python debugging will be suppressed.
+
+
+
+
+
+
+
+
diff --git a/doc/html/building/testing_boost_python.html b/doc/html/building/testing_boost_python.html
new file mode 100644
index 00000000..cbe198d5
--- /dev/null
+++ b/doc/html/building/testing_boost_python.html
@@ -0,0 +1,42 @@
+
+
+
+Testing Boost.Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To run the full test suite for Boost.Python, invoke bjam
+ in the test subdirectory
+ of your Boost.Python distribution.
+
+
+
+
+
+
+
diff --git a/doc/html/configuration.html b/doc/html/configuration.html
new file mode 100644
index 00000000..78faae48
--- /dev/null
+++ b/doc/html/configuration.html
@@ -0,0 +1,340 @@
+
+
+
+Chapter 3. Configuration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 3. Configuration
+
+
Copyright © 2002-2015 David Abrahams, Stefan Seefeld
+
+
+
+
+
+
+
+ Boost.Python uses several configuration
+ macros in < boost / config . hpp > , as well as configuration macros meant
+ to be supplied by the application. These macros are documented here.
+
+
+
+
+
+ These are the macros that may be defined by an application using Boost.Python.
+ Note that if you extend a strict interpretation of the C++ standard to
+ cover dynamic libraries, using different values of these macros when compiling
+ different libraries (including extension modules and the Boost.Python library
+ itself) is a violation of the ODR . However,
+ we know of no C++ implementations on which this particular violation is
+ detectable or causes any problems.
+
+
+
+
+
+
+ These macros are defined by Boost.Python
+ and are implementation details of interest only to implementors and those
+ porting to new platforms.
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/faq.html b/doc/html/faq.html
new file mode 100644
index 00000000..1c921bca
--- /dev/null
+++ b/doc/html/faq.html
@@ -0,0 +1,84 @@
+
+
+
+Chapter 5. Frequently Asked Questions (FAQs)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Chapter 5. Frequently Asked Questions (FAQs)
+
+
+
+ If what you're trying to do is something like this:
+
+
typedef boost :: function < void ( string s ) > funcptr ;
+
+void foo ( funcptr fp )
+{
+ fp ( "hello,world!" );
+}
+
+BOOST_PYTHON_MODULE ( test )
+{
+ def ( "foo" , foo );
+}
+
+
+ And then:
+
+
>>> def hello ( s ):
+... print s
+...
+>>> foo ( hello )
+hello , world !
+
+
+ The short answer is: "you can't". This is not a Boost.Python limitation
+ so much as a limitation of C++. The problem is that a Python function is
+ actually data, and the only way of associating data with a C++ function pointer
+ is to store it in a static variable of the function. The problem with that
+ is that you can only associate one piece of data with every C++ function,
+ and we have no way of compiling a new C++ function on-the-fly for every Python
+ function you decide to pass to foo .
+ In other words, this could work if the C++ function is always going to invoke
+ the same Python function, but you probably don't want
+ that.
+
+
+ If you have the luxury of changing the C++ code you're wrapping, pass it
+ an object instead and call
+ that; the overloaded function call operator will invoke the Python function
+ you pass it behind the object .
+
+
+
+
+
+
+
+
diff --git a/doc/html/faq/compilation_takes_too_much_time_.html b/doc/html/faq/compilation_takes_too_much_time_.html
new file mode 100644
index 00000000..2fb2fcbe
--- /dev/null
+++ b/doc/html/faq/compilation_takes_too_much_time_.html
@@ -0,0 +1,42 @@
+
+
+
+Compilation takes too much time and eats too much memory! What can I do to make it faster?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Please refer to the Reducing Compiling Time
+ section in the Tutorial .
+
+
+
+
+
+
+
diff --git a/doc/html/faq/does_boost_python_work_with_mac_.html b/doc/html/faq/does_boost_python_work_with_mac_.html
new file mode 100644
index 00000000..3b09e519
--- /dev/null
+++ b/doc/html/faq/does_boost_python_work_with_mac_.html
@@ -0,0 +1,93 @@
+
+
+
+Does Boost.Python work with Mac OS X?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ It is known to work under 10.2.8 and 10.3 using Apple's gcc 3.3 compiler:
+
+
gcc ( GCC ) 3.3 20030304 ( Apple Computer , Inc . build 1493 )
+
+ Under 10.2.8 get the August 2003 gcc update (free at http://connect.apple.com ).
+ Under 10.3 get the Xcode Tools v1.0 (also free).
+
+
+ Python 2.3 is required. The Python that ships with 10.3 is fine. Under 10.2.8
+ use these commands to install Python as a framework:
+
+
./ configure -- enable - framework
+make
+make frameworkinstall
+
+ The last command requires root privileges because the target directory is
+ / Library / Frameworks / Python . framework / Versions / 2.3 . However,
+ the installation does not interfere with the Python version that ships with
+ 10.2.8.
+
+
+ It is also crucial to increase the stacksize
+ before starting compilations, e.g.:
+
+
limit stacksize 8192 k
+
+ If the stacksize is too small
+ the build might crash with internal compiler errors.
+
+
+ Sometimes Apple's compiler exhibits a bug by printing an error like the following
+ while compiling a boost :: python :: class_ < your_type >
+ template instantiation:
+
+
.../ inheritance . hpp : 44 : error : cannot
+ dynamic_cast ` p ' (of type `struct cctbx::boost_python::<unnamed>::add_pair*
+ ' ) to type ` void * ' ( source type is not polymorphic )
+
+
+ We do not know a general workaround, but if the definition of your_type can be modified the following
+ was found to work in all cases encountered so far:
+
+
struct your_type
+{
+
+#if defined ( __MACH__ ) & amp ;& amp ; defined ( __APPLE_CC__ ) & amp ;& amp ; __APPLE_CC__ == 1493
+ bool dummy_ ;
+#endif
+
+ double x ;
+ int j ;
+
+};
+
+
+
+
+
+
+
diff --git a/doc/html/faq/error_c2064_term_does_not_evalua.html b/doc/html/faq/error_c2064_term_does_not_evalua.html
new file mode 100644
index 00000000..c03ff124
--- /dev/null
+++ b/doc/html/faq/error_c2064_term_does_not_evalua.html
@@ -0,0 +1,77 @@
+
+
+
+error C2064: term does not evaluate to a function taking 2 arguments
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Niall Douglas provides these notes:
+
+
+ If you see Microsoft Visual C++ 7.1 (MS Visual Studio .NET 2003) issue an
+ error message like the following it is most likely due to a bug in the compiler:
+
+
boost \ boost \ python \ detail \ invoke . hpp ( 76 ):
+error C2064 : term does not evaluate to a function taking 2 arguments "
+
+
+ This message is triggered by code like the following:
+
+
#include < boost / python . hpp >
+
+using namespace boost :: python ;
+
+class FXThread
+{
+public :
+ bool setAutoDelete ( bool doso ) throw ();
+};
+
+void Export_FXThread ()
+{
+ class_ < FXThread >( "FXThread" )
+ . def ( "setAutoDelete" , & amp ; FXThread :: setAutoDelete )
+ ;
+}
+
+
+ The bug is related to the throw () modifier. As a workaround cast off the
+ modifier. E.g.:
+
+
. def ( "setAutoDelete" , ( bool ( FXThread ::*)( bool )) & FXThread :: setAutoDelete )
+
+
+ (The bug has been reported to Microsoft.)
+
+
+
+
+
+
+
diff --git a/doc/html/faq/fatal_error_c1204_compiler_limit.html b/doc/html/faq/fatal_error_c1204_compiler_limit.html
new file mode 100644
index 00000000..9622393b
--- /dev/null
+++ b/doc/html/faq/fatal_error_c1204_compiler_limit.html
@@ -0,0 +1,96 @@
+
+
+
+fatal error C1204:Compiler limit:internal structure overflow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Q: I get this error message when
+ compiling a large source file. What can I do?
+
+
+ A: You have two choices:
+
+
+
+ Upgrade your compiler (preferred)
+
+
+
+ Break your source file up into multiple translation units.
+
+
+ my_module . cpp :
+
+...
+void more_of_my_module ();
+BOOST_PYTHON_MODULE ( my_module )
+{
+ def ( "foo" , foo );
+ def ( "bar" , bar );
+ ...
+ more_of_my_module ();
+}
+
+
+ more_of_my_module . cpp :
+
+void more_of_my_module ()
+{
+ def ( "baz" , baz );
+ ...
+}
+
+
+ If you find that a class_ <...> declaration can't fit in a
+ single source file without triggering the error, you can always pass
+ a reference to the class_
+ object to a function in another source file, and call some of its member
+ functions (e.g. . def (...) ) in the auxilliary source file:
+
+
+ more_of_my_class . cpp :
+
+void more_of_my_class ( class & lt ; my_class & gt ;& amp ; x )
+{
+ x
+ . def ( "baz" , baz )
+ . add_property ( "xx" , & my_class :: get_xx , & my_class :: set_xx )
+ ;
+ ...
+}
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/faq/how_can_i_automatically_convert_.html b/doc/html/faq/how_can_i_automatically_convert_.html
new file mode 100644
index 00000000..cc186764
--- /dev/null
+++ b/doc/html/faq/how_can_i_automatically_convert_.html
@@ -0,0 +1,146 @@
+
+
+
+How can I automatically convert my custom string type to and from a Python string?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ralf W. Grosse-Kunstleve provides these notes:
+
+
+ Below is a small, self-contained demo extension module that shows how to
+ do this. Here is the corresponding trivial test:
+
+
import custom_string
+assert custom_string . hello () == "Hello world."
+assert custom_string . size ( "california" ) == 10
+
+
+ If you look at the code you will find:
+
+
+
+ A custom to_python converter
+ (easy): custom_string_to_python_str
+
+
+ A custom lvalue converter (needs more code): custom_string_from_python_str
+
+
+
+ The custom converters are registered in the global Boost.Python registry
+ near the top of the module initialization function. Once flow control has
+ passed through the registration code the automatic conversions from and to
+ Python strings will work in any module imported in the same process.
+
+
#include < boost / python / module . hpp >
+#include < boost / python / def . hpp >
+#include < boost / python / to_python_converter . hpp >
+
+namespace sandbox { namespace {
+
+class custom_string
+{
+ public :
+ custom_string () {}
+ custom_string ( std :: string const & value ) : value_ ( value ) {}
+ std :: string const & value () const { return value_ ; }
+ private :
+ std :: string value_ ;
+};
+
+struct custom_string_to_python_str
+{
+ static PyObject * convert ( custom_string const & s )
+ {
+ return boost :: python :: incref ( boost :: python :: object ( s . value ()). ptr ());
+ }
+};
+
+struct custom_string_from_python_str
+{
+ custom_string_from_python_str ()
+ {
+ boost :: python :: converter :: registry :: push_back (
+ & convertible ,
+ & construct ,
+ boost :: python :: type_id < custom_string >());
+ }
+
+ static void * convertible ( PyObject * obj_ptr )
+ {
+ if (! PyString_Check ( obj_ptr )) return 0 ;
+ return obj_ptr ;
+ }
+
+ static void construct (
+ PyObject * obj_ptr ,
+ boost :: python :: converter :: rvalue_from_python_stage1_data * data )
+ {
+ const char * value = PyString_AsString ( obj_ptr );
+ if ( value == 0 ) boost :: python :: throw_error_already_set ();
+ void * storage = (
+ ( boost :: python :: converter :: rvalue_from_python_storage < custom_string >*)
+ data )-> storage . bytes ;
+ new ( storage ) custom_string ( value );
+ data -> convertible = storage ;
+ }
+};
+
+custom_string hello () { return custom_string ( "Hello world." ); }
+
+std :: size_t size ( custom_string const & s ) { return s . value (). size (); }
+
+void init_module ()
+{
+ using namespace boost :: python ;
+
+ boost :: python :: to_python_converter <
+ custom_string ,
+ custom_string_to_python_str >();
+
+ custom_string_from_python_str ();
+
+ def ( "hello" , hello );
+ def ( "size" , size );
+}
+
+}}
+
+BOOST_PYTHON_MODULE ( custom_string )
+{
+ sandbox :: init_module ();
+}
+
+
+
+
+
+
+
diff --git a/doc/html/faq/how_can_i_find_the_existing_pyob.html b/doc/html/faq/how_can_i_find_the_existing_pyob.html
new file mode 100644
index 00000000..d423fdd5
--- /dev/null
+++ b/doc/html/faq/how_can_i_find_the_existing_pyob.html
@@ -0,0 +1,103 @@
+
+
+
+How can I find the existing PyObject that holds a C++ object?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "I am wrapping a function that always returns a pointer to an already-held
+ C++ object."
+
+
+ One way to do that is to hijack the mechanisms used for wrapping a class
+ with virtual functions. If you make a wrapper class with an initial PyObject*
+ constructor argument and store that PyObject* as "self", you can
+ get back to it by casting down to that wrapper type in a thin wrapper function.
+ For example:
+
+
class X { X ( int ); virtual ~ X (); ... };
+X * f ();
+
+
+
+
+struct X_wrap : X
+{
+ X_wrap ( PyObject * self , int v ) : self ( self ), X ( v ) {}
+ PyObject * self ;
+};
+
+handle <> f_wrap ()
+{
+ X_wrap * xw = dynamic_cast < X_wrap *>( f ());
+ assert ( xw != 0 );
+ return handle <>( borrowed ( xw -> self ));
+}
+
+...
+
+def ( "f" , f_wrap ());
+class_ < X , X_wrap , boost :: noncopyable >( "X" , init < int >())
+ ...
+ ;
+
+
+ Of course, if X has no virtual functions you'll have to use static_cast instead of dynamic_cast
+ with no runtime check that it's valid. This approach also only works if the
+ X object was constructed
+ from Python, because X s constructed
+ from C++ are of course never X_wrap
+ objects.
+
+
+ Another approach to this requires you to change your C++ code a bit; if that's
+ an option for you it might be a better way to go. work we've been meaning
+ to get to anyway. When a shared_ptr < X >
+ is converted from Python, the shared_ptr actually manages a reference to
+ the containing Python object. When a shared_ptr<X> is converted back
+ to Python, the library checks to see if it's one of those "Python object
+ managers" and if so just returns the original Python object. So you
+ could just write object ( p ) to get
+ the Python object back. To exploit this you'd have to be able to change the
+ C++ code you're wrapping so that it deals with shared_ptr instead of raw
+ pointers.
+
+
+ There are other approaches too. The functions that receive the Python object
+ that you eventually want to return could be wrapped with a thin wrapper that
+ records the correspondence between the object address and its containing
+ Python object, and you could have your f_wrap function look in that mapping
+ to get the Python object out.
+
+
+
+
+
+
+
diff --git a/doc/html/faq/how_can_i_wrap_a_function_which0.html b/doc/html/faq/how_can_i_wrap_a_function_which0.html
new file mode 100644
index 00000000..b107a256
--- /dev/null
+++ b/doc/html/faq/how_can_i_wrap_a_function_which0.html
@@ -0,0 +1,86 @@
+
+
+
+How can I wrap a function which needs to take ownership of a raw pointer?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Q: Part of an API that I'm wrapping goes
+ something like this:
+
+
struct A {}; struct B { void add ( A * ); }
+where B :: add () takes ownership of the pointer passed to it .
+
+
+ However:
+
+
a = mod . A ()
+b = mod . B ()
+b . add ( a )
+del a
+del b
+# python interpreter crashes
+# later due to memory corruption .
+
+
+ Even binding the lifetime of a to b via with_custodian_and_ward
+ doesn't prevent the python object a from ultimately trying to delete the
+ object it's pointing to. Is there a way to accomplish a 'transfer-of-ownership'
+ of a wrapped C++ object?
+
+
+ --Bruce Lowery
+
+
+ Yes: Make sure the C++ object is held by auto_ptr:
+
+
class_ < A , std :: auto_ptr < A > >( "A" )
+ ...
+ ;
+
+
+ Then make a thin wrapper function which takes an auto_ptr parameter:
+
+
void b_insert ( B & b , std :: auto_ptr < A > a )
+{
+ b . insert ( a . get ());
+ a . release ();
+}
+
+
+ Wrap that as B.add. Note that pointers returned via manage_new_object
+ will also be held by auto_ptr ,
+ so this transfer-of-ownership will also work correctly.
+
+
+
+
+
+
+
diff --git a/doc/html/faq/how_can_i_wrap_functions_which_t.html b/doc/html/faq/how_can_i_wrap_functions_which_t.html
new file mode 100644
index 00000000..ba8e1b97
--- /dev/null
+++ b/doc/html/faq/how_can_i_wrap_functions_which_t.html
@@ -0,0 +1,124 @@
+
+
+
+How can I wrap functions which take C++ containers as arguments?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ralf W. Grosse-Kunstleve provides these notes:
+
+
+
+
+ Using the regular class_ <> wrapper:
+
+class_ < std :: vector < double > >( "std_vector_double" )
+ . def (...)
+ ...
+;
+
+
+ This can be moved to a template so that several types (double , int ,
+ long , etc.) can be wrapped
+ with the same code. This technique is used in the file scitbx / include / scitbx / array_family / boost_python / flex_wrapper . h in the "scitbx" package.
+ The file could easily be modified for wrapping std :: vector <> instantiations. This type of
+ C++/Python binding is most suitable for containers that may contain a
+ large number of elements (>10000).
+
+
+
+
+ Using custom rvalue converters. Boost.Python "rvalue converters"
+ match function signatures such as:
+
+void foo ( std :: vector < double > const & array );
+void foo ( std :: vector < double > array );
+
+
+ Some custom rvalue converters are implemented in the file scitbx / include / scitbx / boost_python / container_conversions . h This code can be used to convert
+ from C++ container types such as std :: vector <> or std :: list <> to Python tuples and vice versa.
+ A few simple examples can be found in the file scitbx / array_family / boost_python / regression_test_module . cpp
+ Automatic C++ container <-> Python tuple conversions are most suitable
+ for containers of moderate size. These converters generate significantly
+ less object code compared to alternative 1 above.
+
+
+
+
+ A disadvantage of using alternative 2 is that operators such as arithmetic
+ +,-,*,/,% are not available. It would be useful to have custom rvalue converters
+ that convert to a "math_array" type instead of tuples. This is
+ currently not implemented but is possible within the framework of Boost.Python
+ V2 as it will be released in the next couple of weeks. [ed.: this was posted
+ on 2002/03/10]
+
+
+ It would also be useful to also have "custom lvalue converters"
+ such as std :: vector <>
+ <-> Python list. These converters would support the modification of
+ the Python list from C++. For example:
+
+
+ C++:
+
+
void foo ( std :: vector < double > & array )
+{
+ for ( std :: size_t i = 0 ; i & lt ; array . size (); i ++) {
+ array [ i ] *= 2 ;
+ }
+}
+
+
+ Python:
+
+
>>> l = [ 1 , 2 , 3 ]
+>>> foo ( l )
+>>> print l
+[ 2 , 4 , 6 ]
+
+
+ Custom lvalue converters require changes to the Boost.Python core library
+ and are currently not available.
+
+
+ P.S.:
+
+
+ The "scitbx" files referenced above are available via anonymous
+ CVS:
+
+
cvs - d : pserver : anonymous @ cvs . cctbx . sourceforge . net :/ cvsroot / cctbx login
+cvs - d : pserver : anonymous @ cvs . cctbx . sourceforge . net :/ cvsroot / cctbx co scitbx
+
+
+
+
+
+
+
diff --git a/doc/html/faq/how_do_i_create_sub_packages_usi.html b/doc/html/faq/how_do_i_create_sub_packages_usi.html
new file mode 100644
index 00000000..1a902b48
--- /dev/null
+++ b/doc/html/faq/how_do_i_create_sub_packages_usi.html
@@ -0,0 +1,41 @@
+
+
+
+How do I create sub-packages using Boost.Python?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Please refer to the Creating Packages section in the Tutorial .
+
+
+
+
+
+
+
diff --git a/doc/html/faq/how_do_i_debug_my_python_extensi.html b/doc/html/faq/how_do_i_debug_my_python_extensi.html
new file mode 100644
index 00000000..b8099db9
--- /dev/null
+++ b/doc/html/faq/how_do_i_debug_my_python_extensi.html
@@ -0,0 +1,151 @@
+
+
+
+How do I debug my Python extensions?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Greg Burley gives the following answer for Unix GCC users:
+
+
+
+ Once you have created a boost python extension for your c++ library or
+ class, you may need to debug the code. Afterall this is one of the reasons
+ for wrapping the library in python. An expected side-effect or benefit
+ of using BPL is that debugging should be isolated to the c++ library that
+ is under test, given that python code is minimal and boost::python either
+ works or it doesn't. (ie. While errors can occur when the wrapping method
+ is invalid, most errors are caught by the compiler ;-).
+
+
+ The basic steps required to initiate a gdb session to debug a c++ library
+ via python are shown here. Note, however that you should start the gdb
+ session in the directory that contains your BPL my_ext.so module.
+
+( gdb ) target exec python
+( gdb ) run
+>>> from my_ext import *
+>>> [ C - c ]
+( gdb ) break MyClass :: MyBuggyFunction
+( gdb ) cont
+>>> pyobj = MyClass ()
+>>> pyobj . MyBuggyFunction ()
+Breakpoint 1 , MyClass :: MyBuggyFunction ...
+Current language : auto ; currently c ++
+( gdb ) do debugging stuff
+
+
+
+ Greg's approach works even better using Emacs' "gdb" command, since
+ it will show you each line of source as you step through it.
+
+
+ On Windows , my favorite debugging solution
+ is the debugger that comes with Microsoft Visual C++ 7. This debugger seems
+ to work with code generated by all versions of Microsoft and Metrowerks toolsets;
+ it's rock solid and "just works" without requiring any special
+ tricks from the user.
+
+
+ Raoul Gough has provided the following for gdb on Windows:
+
+
+
+ gdb support for Windows DLLs has improved lately, so it is now possible
+ to debug Python extensions using a few tricks. Firstly, you will need an
+ up-to-date gdb with support for minimal symbol extraction from a DLL. Any
+ gdb from version 6 onwards, or Cygwin gdb-20030214-1 and onwards should
+ do. A suitable release will have a section in the gdb.info file under Configuration
+ - Native - Cygwin Native - Non-debug DLL symbols. Refer to that info section
+ for more details of the procedures outlined here.
+
+
+ Secondly, it seems necessary to set a breakpoint in the Python interpreter,
+ rather than using ^C to break execution. A good place to set this breakpoint
+ is PyOS_Readline, which will stop execution immediately before reading
+ each interactive Python command. You have to let Python start once under
+ the debugger, so that it loads its own DLL, before you can set the breakpoint:
+
+$ gdb python
+GNU gdb 2003 - 09 - 02 - cvs ( cygwin - special )
+[...]
+
+( gdb ) run
+Starting program : / cygdrive / c / Python22 / python . exe
+Python 2.2 . 2 (# 37 , Oct 14 2002 , 17 : 02 : 34 ) [ MSC 32 bit ( Intel )] on win32
+Type "help" , "copyright" , "credits" or "license" for more information .
+>>> ^ Z
+
+
+Program exited normally .
+( gdb ) break *& PyOS_Readline
+Breakpoint 1 at 0x1e04eff0
+( gdb ) run
+Starting program : / cygdrive / c / Python22 / python . exe
+Python 2.2 . 2 (# 37 , Oct 14 2002 , 17 : 02 : 34 ) [ MSC 32 bit ( Intel )] on win32
+Type "help" , "copyright" , "credits" or "license" for more information .
+
+Breakpoint 1 , 0x1e04eff0 in python22 ! PyOS_Readline ()
+ from / cygdrive / c / WINNT / system32 / python22 . dll
+( gdb ) cont
+Continuing .
+>>> from my_ext import *
+
+Breakpoint 1 , 0x1e04eff0 in python22 ! PyOS_Readline ()
+ from / cygdrive / c / WINNT / system32 / python22 . dll
+( gdb ) # my_ext now loaded ( with any debugging symbols it contains )
+
+
+
+
+ If you are launching your extension module tests with Boost.Build
+ using the boost - python - runtest rule, you can ask it to launch
+ your debugger for you by adding "--debugger=debugger "
+ to your bjam command-line:
+
+
bjam - sTOOLS = vc7 . 1 "--debugger=devenv /debugexe" test
+bjam - sTOOLS = gcc - sPYTHON_LAUNCH = gdb test
+
+
+ It can also be extremely useful to add the - d + 2
+ option when you run your test, because Boost.Build will then show you the
+ exact commands it uses to invoke it. This will invariably involve setting
+ up PYTHONPATH and other important environment variables such as LD_LIBRARY_PATH
+ which may be needed by your debugger in order to get things to work right.
+
+
+
+
+
+
+
diff --git a/doc/html/faq/i_m_getting_the_attempt_to_retur.html b/doc/html/faq/i_m_getting_the_attempt_to_retur.html
new file mode 100644
index 00000000..7d1f857a
--- /dev/null
+++ b/doc/html/faq/i_m_getting_the_attempt_to_retur.html
@@ -0,0 +1,67 @@
+
+
+
+I'm getting the "attempt to return dangling reference" error. What am I doing wrong?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ That exception is protecting you from causing a nasty crash. It usually happens
+ in response to some code like this:
+
+
period const & get_floating_frequency () const
+{
+ return boost :: python :: call_method < period const &>(
+ m_self , "get_floating_frequency" );
+}
+
+
+ And you get:
+
+
ReferenceError : Attempt to return dangling reference to object of type :
+class period
+
+
+ In this case, the Python method invoked by call_method
+ constructs a new Python object. You're trying to return a reference to a
+ C++ object (an instance of class period ) contained within and owned by that
+ Python object. Because the called method handed back a brand new object,
+ the only reference to it is held for the duration of get_floating_frequency () above. When the function returns, the Python
+ object will be destroyed, destroying the instance of class
+ period , and leaving the returned
+ reference dangling. That's already undefined behavior, and if you try to
+ do anything with that reference you're likely to cause a crash. Boost.Python
+ detects this situation at runtime and helpfully throws an exception instead
+ of letting you do that.
+
+
+
+
+
+
+
diff --git a/doc/html/faq/is_boost_python_thread_aware_com.html b/doc/html/faq/is_boost_python_thread_aware_com.html
new file mode 100644
index 00000000..55662715
--- /dev/null
+++ b/doc/html/faq/is_boost_python_thread_aware_com.html
@@ -0,0 +1,60 @@
+
+
+
+Is Boost.Python thread-aware/compatible with multiple interpreters?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Niall Douglas provides these notes:
+
+
+ The quick answer to this is: no.
+
+
+ The longer answer is that it can be patched to be so, but it's complex. You
+ will need to add custom lock/unlock wrapping of every time your code enters
+ Boost.Python (particularly every virtual function override) plus heavily
+ modify boost / python / detail / invoke . hpp with custom unlock/lock wrapping of
+ every time Boost.Python enters your code. You must furthermore take care
+ to not unlock/lock when Boost.Python is invoking iterator
+ changes via invoke . hpp .
+
+
+ There is a patched invoke . hpp posted
+ on the C++-SIG mailing list archives and you can find a real implementation
+ of all the machinery necessary to fully implement this in the TnFOX project
+ at this SourceForge
+ project location.
+
+
+
+
+
+
+
diff --git a/doc/html/faq/is_return_internal_reference_eff.html b/doc/html/faq/is_return_internal_reference_eff.html
new file mode 100644
index 00000000..45133816
--- /dev/null
+++ b/doc/html/faq/is_return_internal_reference_eff.html
@@ -0,0 +1,62 @@
+
+
+
+Is return_internal_reference efficient?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Q: /I have an object composed of 12 doubles.
+ A const &
+ to this object is returned by a member function of another class. From the
+ viewpoint of using the returned object in Python I do not care if I get a
+ copy or a reference to the returned object. In Boost.Python I have the choice
+ of using copy_const_reference
+ or return_internal_reference .
+ Are there considerations that would lead me to prefer one over the other,
+ such as size of generated code or memory overhead?/
+
+
+ A: copy_const_reference
+ will make an instance with storage for one of your objects, size = base_size + 12 * sizeof ( double ) .
+ return_internal_reference
+ will make an instance with storage for a pointer to one of your objects,
+ size =
+ base_size +
+ sizeof ( void *) . However,
+ it will also create a weak reference object which goes in the source object's
+ weakreflist and a special callback object to manage the lifetime of the internally-referenced
+ object. My guess? copy_const_reference
+ is your friend here, resulting in less overall memory use and less fragmentation,
+ also probably fewer total cycles.
+
+
+
+
+
+
+
diff --git a/doc/html/faq/why_doesn_t_my_operator_work.html b/doc/html/faq/why_doesn_t_my_operator_work.html
new file mode 100644
index 00000000..d0be0be5
--- /dev/null
+++ b/doc/html/faq/why_doesn_t_my_operator_work.html
@@ -0,0 +1,63 @@
+
+
+
+Why doesn't my *= operator work?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Q: I have exported my class to
+ python, with many overloaded operators. it works fine for me except the
+ *= operator. It always tells
+ me "can't multiply sequence with non int type". If I use p1 . __imul__ ( p2 )
+ instead of p1 *=
+ p2 , it successfully executes my
+ code. What's wrong with me?
+
+
+ A: There's nothing wrong with you. This
+ is a bug in Python 2.2. You can see the same effect in Pure Python (you can
+ learn a lot about what's happening in Boost.Python by playing with new-style
+ classes in Pure Python).
+
+
>>> class X ( object ):
+... def __imul__ ( self , x ):
+... print 'imul'
+...
+>>> x = X ()
+>>> x *= 1
+
+
+ To cure this problem, all you need to do is upgrade your Python to version
+ 2.2.1 or later.
+
+
+
+
+
+
+
diff --git a/doc/html/faq/why_is_my_automatic_to_python_co.html b/doc/html/faq/why_is_my_automatic_to_python_co.html
new file mode 100644
index 00000000..2efaf07a
--- /dev/null
+++ b/doc/html/faq/why_is_my_automatic_to_python_co.html
@@ -0,0 +1,67 @@
+
+
+
+Why is my automatic to-python conversion not being found?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Niall Douglas provides these notes:
+
+
+ If you define custom converters similar to the ones shown above the def_readonly ()
+ and def_readwrite ()
+ member functions provided by boost :: python :: class_
+ for direct access to your member data will not work as expected. This is
+ because def_readonly ( "bar" ,& foo :: bar ) is equivalent to:
+
+
. add_property ( "bar" , make_getter (& foo :: bar , return_internal_reference ()))
+
+
+ Similarly, def_readwrite ( "bar" ,& foo :: bar )
+ is equivalent to:
+
+
. add_property ( "bar" , make_getter (& foo :: bar , return_internal_reference ()),
+ make_setter (& foo :: bar , return_internal_reference ())
+
+
+ In order to define return value policies compatible with the custom conversions
+ replace def_readonly ()
+ and def_readwrite ()
+ by add_property () .
+ E.g.:
+
+
. add_property ( "bar" , make_getter (& foo :: bar , return_value_policy < return_by_value >()),
+ make_setter (& foo :: bar , return_value_policy < return_by_value >()))
+
+
+
+
+
+
+
diff --git a/doc/html/glossary.html b/doc/html/glossary.html
new file mode 100644
index 00000000..63d0003d
--- /dev/null
+++ b/doc/html/glossary.html
@@ -0,0 +1,81 @@
+
+
+
+Chapter 6. Glossary
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+arity
+
+ The number of argumnts accepted by a function or member function. Unless
+ otherwise specified, the hidden this
+ argument to member functions is not counted when specifying arity.
+
+ntbs
+
+ Null-Terminated Byte String, or 'C'-string. C++ string literals are
+ ntbs es. An ntbs
+ must never be null.
+
+raise
+
+ Exceptions in Python are "raised", not "thrown",
+ as they are in C++. When this documentation says that some Python exception
+ is "raised" in the context of C++ code, it means that the corresponding
+ Python exception is set via the Python/'C'
+ API , and throw_error_already_set () is called.
+
+POD
+
+ A technical term from the C++ standard. Short for "Plain Ol'Data":
+ A POD-struct is an aggregate class that has no non-static data members
+ of type pointer to member, non-POD-struct, non-POD-union (or array of
+ such types) or reference, and has no user-defined copy assign- ment operator
+ and no user-defined destructor. Similarly, a POD-union is an aggregate
+ union that has no non-static data members of type pointer to member,
+ non-POD-struct, non-POD-union (or array of such types) or reference,
+ and has no user-defined copy assignment operator and no user-defined
+ destructor. A POD class is a class that is either a POD-struct or a POD-union.
+ An aggregate is an array or a class (clause 9) with no user-declared
+ constructors (12.1), no private or protected non-static data members
+ (clause 11), no base classes (clause 10), and no virtual functions (10.3).
+
+ODR
+
+ The "One Definition Rule", which says that any entity in a
+ C++ program must have the same definition in all translation units (object
+ files) which make up a program.
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/alert.png b/doc/html/images/alert.png
new file mode 100644
index 00000000..b4645bc7
Binary files /dev/null and b/doc/html/images/alert.png differ
diff --git a/doc/html/images/blank.png b/doc/html/images/blank.png
new file mode 100644
index 00000000..764bf4f0
Binary files /dev/null and b/doc/html/images/blank.png differ
diff --git a/doc/html/images/boost.png b/doc/html/images/boost.png
new file mode 100644
index 00000000..b4d51fcd
Binary files /dev/null and b/doc/html/images/boost.png differ
diff --git a/doc/html/images/bpl.png b/doc/html/images/bpl.png
new file mode 100644
index 00000000..c2d8c69e
Binary files /dev/null and b/doc/html/images/bpl.png differ
diff --git a/doc/html/images/bpl.svg b/doc/html/images/bpl.svg
new file mode 100644
index 00000000..9a72d2c4
--- /dev/null
+++ b/doc/html/images/bpl.svg
@@ -0,0 +1,224 @@
+
+image/svg+xml Boost.Python
+
\ No newline at end of file
diff --git a/doc/html/images/callouts/1.png b/doc/html/images/callouts/1.png
new file mode 100644
index 00000000..6003ad3a
Binary files /dev/null and b/doc/html/images/callouts/1.png differ
diff --git a/doc/html/images/callouts/1.svg b/doc/html/images/callouts/1.svg
new file mode 100644
index 00000000..e2e87dc5
--- /dev/null
+++ b/doc/html/images/callouts/1.svg
@@ -0,0 +1,15 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/10.png b/doc/html/images/callouts/10.png
new file mode 100644
index 00000000..0426f516
Binary files /dev/null and b/doc/html/images/callouts/10.png differ
diff --git a/doc/html/images/callouts/10.svg b/doc/html/images/callouts/10.svg
new file mode 100644
index 00000000..4740f587
--- /dev/null
+++ b/doc/html/images/callouts/10.svg
@@ -0,0 +1,18 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/11.png b/doc/html/images/callouts/11.png
new file mode 100644
index 00000000..821afc4f
Binary files /dev/null and b/doc/html/images/callouts/11.png differ
diff --git a/doc/html/images/callouts/11.svg b/doc/html/images/callouts/11.svg
new file mode 100644
index 00000000..09a0b2cf
--- /dev/null
+++ b/doc/html/images/callouts/11.svg
@@ -0,0 +1,16 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/12.png b/doc/html/images/callouts/12.png
new file mode 100644
index 00000000..7cec7272
Binary files /dev/null and b/doc/html/images/callouts/12.png differ
diff --git a/doc/html/images/callouts/12.svg b/doc/html/images/callouts/12.svg
new file mode 100644
index 00000000..9794044c
--- /dev/null
+++ b/doc/html/images/callouts/12.svg
@@ -0,0 +1,18 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/13.png b/doc/html/images/callouts/13.png
new file mode 100644
index 00000000..5b41e02a
Binary files /dev/null and b/doc/html/images/callouts/13.png differ
diff --git a/doc/html/images/callouts/13.svg b/doc/html/images/callouts/13.svg
new file mode 100644
index 00000000..64268bb4
--- /dev/null
+++ b/doc/html/images/callouts/13.svg
@@ -0,0 +1,20 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/14.png b/doc/html/images/callouts/14.png
new file mode 100644
index 00000000..de5bdbd3
Binary files /dev/null and b/doc/html/images/callouts/14.png differ
diff --git a/doc/html/images/callouts/14.svg b/doc/html/images/callouts/14.svg
new file mode 100644
index 00000000..469aa974
--- /dev/null
+++ b/doc/html/images/callouts/14.svg
@@ -0,0 +1,17 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/15.png b/doc/html/images/callouts/15.png
new file mode 100644
index 00000000..3fd6ac38
Binary files /dev/null and b/doc/html/images/callouts/15.png differ
diff --git a/doc/html/images/callouts/15.svg b/doc/html/images/callouts/15.svg
new file mode 100644
index 00000000..8202233e
--- /dev/null
+++ b/doc/html/images/callouts/15.svg
@@ -0,0 +1,19 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/16.svg b/doc/html/images/callouts/16.svg
new file mode 100644
index 00000000..01d6bf81
--- /dev/null
+++ b/doc/html/images/callouts/16.svg
@@ -0,0 +1,20 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/17.svg b/doc/html/images/callouts/17.svg
new file mode 100644
index 00000000..0a04c556
--- /dev/null
+++ b/doc/html/images/callouts/17.svg
@@ -0,0 +1,17 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/18.svg b/doc/html/images/callouts/18.svg
new file mode 100644
index 00000000..1cb891b3
--- /dev/null
+++ b/doc/html/images/callouts/18.svg
@@ -0,0 +1,21 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/19.svg b/doc/html/images/callouts/19.svg
new file mode 100644
index 00000000..e6fbb179
--- /dev/null
+++ b/doc/html/images/callouts/19.svg
@@ -0,0 +1,20 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/2.png b/doc/html/images/callouts/2.png
new file mode 100644
index 00000000..f7c15788
Binary files /dev/null and b/doc/html/images/callouts/2.png differ
diff --git a/doc/html/images/callouts/2.svg b/doc/html/images/callouts/2.svg
new file mode 100644
index 00000000..07d03395
--- /dev/null
+++ b/doc/html/images/callouts/2.svg
@@ -0,0 +1,17 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/20.svg b/doc/html/images/callouts/20.svg
new file mode 100644
index 00000000..ccbfd403
--- /dev/null
+++ b/doc/html/images/callouts/20.svg
@@ -0,0 +1,20 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/21.svg b/doc/html/images/callouts/21.svg
new file mode 100644
index 00000000..93ec53fd
--- /dev/null
+++ b/doc/html/images/callouts/21.svg
@@ -0,0 +1,18 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/22.svg b/doc/html/images/callouts/22.svg
new file mode 100644
index 00000000..f48c5f3f
--- /dev/null
+++ b/doc/html/images/callouts/22.svg
@@ -0,0 +1,20 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/23.svg b/doc/html/images/callouts/23.svg
new file mode 100644
index 00000000..66242129
--- /dev/null
+++ b/doc/html/images/callouts/23.svg
@@ -0,0 +1,22 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/24.svg b/doc/html/images/callouts/24.svg
new file mode 100644
index 00000000..a3d55253
--- /dev/null
+++ b/doc/html/images/callouts/24.svg
@@ -0,0 +1,19 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/25.svg b/doc/html/images/callouts/25.svg
new file mode 100644
index 00000000..56614a97
--- /dev/null
+++ b/doc/html/images/callouts/25.svg
@@ -0,0 +1,21 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/26.svg b/doc/html/images/callouts/26.svg
new file mode 100644
index 00000000..56faeaca
--- /dev/null
+++ b/doc/html/images/callouts/26.svg
@@ -0,0 +1,22 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/27.svg b/doc/html/images/callouts/27.svg
new file mode 100644
index 00000000..a75c8121
--- /dev/null
+++ b/doc/html/images/callouts/27.svg
@@ -0,0 +1,19 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/28.svg b/doc/html/images/callouts/28.svg
new file mode 100644
index 00000000..7f8cf1a3
--- /dev/null
+++ b/doc/html/images/callouts/28.svg
@@ -0,0 +1,23 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/29.svg b/doc/html/images/callouts/29.svg
new file mode 100644
index 00000000..cb63adf1
--- /dev/null
+++ b/doc/html/images/callouts/29.svg
@@ -0,0 +1,22 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/3.png b/doc/html/images/callouts/3.png
new file mode 100644
index 00000000..3ff0a939
Binary files /dev/null and b/doc/html/images/callouts/3.png differ
diff --git a/doc/html/images/callouts/3.svg b/doc/html/images/callouts/3.svg
new file mode 100644
index 00000000..918be806
--- /dev/null
+++ b/doc/html/images/callouts/3.svg
@@ -0,0 +1,19 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/30.svg b/doc/html/images/callouts/30.svg
new file mode 100644
index 00000000..dc43ba1e
--- /dev/null
+++ b/doc/html/images/callouts/30.svg
@@ -0,0 +1,22 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/4.png b/doc/html/images/callouts/4.png
new file mode 100644
index 00000000..6aa29fc0
Binary files /dev/null and b/doc/html/images/callouts/4.png differ
diff --git a/doc/html/images/callouts/4.svg b/doc/html/images/callouts/4.svg
new file mode 100644
index 00000000..8eb6a53b
--- /dev/null
+++ b/doc/html/images/callouts/4.svg
@@ -0,0 +1,16 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/5.png b/doc/html/images/callouts/5.png
new file mode 100644
index 00000000..36e78586
Binary files /dev/null and b/doc/html/images/callouts/5.png differ
diff --git a/doc/html/images/callouts/5.svg b/doc/html/images/callouts/5.svg
new file mode 100644
index 00000000..ca7a9f22
--- /dev/null
+++ b/doc/html/images/callouts/5.svg
@@ -0,0 +1,18 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/6.png b/doc/html/images/callouts/6.png
new file mode 100644
index 00000000..c943676b
Binary files /dev/null and b/doc/html/images/callouts/6.png differ
diff --git a/doc/html/images/callouts/6.svg b/doc/html/images/callouts/6.svg
new file mode 100644
index 00000000..783a0b9d
--- /dev/null
+++ b/doc/html/images/callouts/6.svg
@@ -0,0 +1,19 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/7.png b/doc/html/images/callouts/7.png
new file mode 100644
index 00000000..20940de3
Binary files /dev/null and b/doc/html/images/callouts/7.png differ
diff --git a/doc/html/images/callouts/7.svg b/doc/html/images/callouts/7.svg
new file mode 100644
index 00000000..59b3714b
--- /dev/null
+++ b/doc/html/images/callouts/7.svg
@@ -0,0 +1,16 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/8.png b/doc/html/images/callouts/8.png
new file mode 100644
index 00000000..d8e34d4a
Binary files /dev/null and b/doc/html/images/callouts/8.png differ
diff --git a/doc/html/images/callouts/8.svg b/doc/html/images/callouts/8.svg
new file mode 100644
index 00000000..c1803a3c
--- /dev/null
+++ b/doc/html/images/callouts/8.svg
@@ -0,0 +1,20 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/callouts/9.png b/doc/html/images/callouts/9.png
new file mode 100644
index 00000000..abe63607
Binary files /dev/null and b/doc/html/images/callouts/9.png differ
diff --git a/doc/html/images/callouts/9.svg b/doc/html/images/callouts/9.svg
new file mode 100644
index 00000000..bc149d3c
--- /dev/null
+++ b/doc/html/images/callouts/9.svg
@@ -0,0 +1,19 @@
+
+
+
+
+]>
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/caution.png b/doc/html/images/caution.png
new file mode 100644
index 00000000..5b7809ca
Binary files /dev/null and b/doc/html/images/caution.png differ
diff --git a/doc/html/images/caution.svg b/doc/html/images/caution.svg
new file mode 100644
index 00000000..4bd586a0
--- /dev/null
+++ b/doc/html/images/caution.svg
@@ -0,0 +1,68 @@
+
+
+
+
+
+ Attenzione
+
+
+
+ pulsante
+
+
+
+
+ Open Clip Art Library
+
+
+
+
+ Architetto Francesco Rollandin
+
+
+
+
+ Architetto Francesco Rollandin
+
+
+
+ image/svg+xml
+
+
+ en
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/draft.png b/doc/html/images/draft.png
new file mode 100644
index 00000000..0084708c
Binary files /dev/null and b/doc/html/images/draft.png differ
diff --git a/doc/html/images/home.png b/doc/html/images/home.png
new file mode 100644
index 00000000..5584aacb
Binary files /dev/null and b/doc/html/images/home.png differ
diff --git a/doc/html/images/home.svg b/doc/html/images/home.svg
new file mode 100644
index 00000000..e803a317
--- /dev/null
+++ b/doc/html/images/home.svg
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/important.png b/doc/html/images/important.png
new file mode 100644
index 00000000..12c90f60
Binary files /dev/null and b/doc/html/images/important.png differ
diff --git a/doc/html/images/important.svg b/doc/html/images/important.svg
new file mode 100644
index 00000000..dd84f3fe
--- /dev/null
+++ b/doc/html/images/important.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/jam.png b/doc/html/images/jam.png
new file mode 100644
index 00000000..224ed791
Binary files /dev/null and b/doc/html/images/jam.png differ
diff --git a/doc/html/images/next.png b/doc/html/images/next.png
new file mode 100644
index 00000000..59800b4e
Binary files /dev/null and b/doc/html/images/next.png differ
diff --git a/doc/html/images/next.svg b/doc/html/images/next.svg
new file mode 100644
index 00000000..75fa83ed
--- /dev/null
+++ b/doc/html/images/next.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/next_disabled.png b/doc/html/images/next_disabled.png
new file mode 100644
index 00000000..10a8c59d
Binary files /dev/null and b/doc/html/images/next_disabled.png differ
diff --git a/doc/html/images/note.png b/doc/html/images/note.png
new file mode 100644
index 00000000..d0c3c645
Binary files /dev/null and b/doc/html/images/note.png differ
diff --git a/doc/html/images/note.svg b/doc/html/images/note.svg
new file mode 100644
index 00000000..648299d2
--- /dev/null
+++ b/doc/html/images/note.svg
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/prev.png b/doc/html/images/prev.png
new file mode 100644
index 00000000..d88a40f9
Binary files /dev/null and b/doc/html/images/prev.png differ
diff --git a/doc/html/images/prev.svg b/doc/html/images/prev.svg
new file mode 100644
index 00000000..6d88ffdd
--- /dev/null
+++ b/doc/html/images/prev.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/prev_disabled.png b/doc/html/images/prev_disabled.png
new file mode 100644
index 00000000..ab3c17e0
Binary files /dev/null and b/doc/html/images/prev_disabled.png differ
diff --git a/doc/html/images/smiley.png b/doc/html/images/smiley.png
new file mode 100644
index 00000000..30a77f71
Binary files /dev/null and b/doc/html/images/smiley.png differ
diff --git a/doc/html/images/tip.png b/doc/html/images/tip.png
new file mode 100644
index 00000000..5c4aab3b
Binary files /dev/null and b/doc/html/images/tip.png differ
diff --git a/doc/html/images/tip.svg b/doc/html/images/tip.svg
new file mode 100644
index 00000000..cd437a5e
--- /dev/null
+++ b/doc/html/images/tip.svg
@@ -0,0 +1,84 @@
+
+
+
+
+
+ lamp
+
+
+
+ office
+
+ lamp
+
+
+
+
+ Open Clip Art Library
+
+
+
+
+ Sergio Luiz Araujo Silva
+
+
+
+
+ Public Domain
+
+
+ set 2005
+ image/svg+xml
+
+
+ en
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/toc-blank.png b/doc/html/images/toc-blank.png
new file mode 100644
index 00000000..6ffad17a
Binary files /dev/null and b/doc/html/images/toc-blank.png differ
diff --git a/doc/html/images/toc-minus.png b/doc/html/images/toc-minus.png
new file mode 100644
index 00000000..abbb020c
Binary files /dev/null and b/doc/html/images/toc-minus.png differ
diff --git a/doc/html/images/toc-plus.png b/doc/html/images/toc-plus.png
new file mode 100644
index 00000000..941312ce
Binary files /dev/null and b/doc/html/images/toc-plus.png differ
diff --git a/doc/html/images/up.png b/doc/html/images/up.png
new file mode 100644
index 00000000..17d9c3ec
Binary files /dev/null and b/doc/html/images/up.png differ
diff --git a/doc/html/images/up.svg b/doc/html/images/up.svg
new file mode 100644
index 00000000..d31aa9c8
--- /dev/null
+++ b/doc/html/images/up.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/images/up_disabled.png b/doc/html/images/up_disabled.png
new file mode 100644
index 00000000..e22bc871
Binary files /dev/null and b/doc/html/images/up_disabled.png differ
diff --git a/doc/html/images/warning.png b/doc/html/images/warning.png
new file mode 100644
index 00000000..1c33db8f
Binary files /dev/null and b/doc/html/images/warning.png differ
diff --git a/doc/html/images/warning.svg b/doc/html/images/warning.svg
new file mode 100644
index 00000000..fc8d7484
--- /dev/null
+++ b/doc/html/images/warning.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/html/index.html b/doc/html/index.html
new file mode 100644
index 00000000..bba6cce2
--- /dev/null
+++ b/doc/html/index.html
@@ -0,0 +1,135 @@
+
+
+
+Boost.Python
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+David Abrahams
+
+
+Stefan Seefeld
+
+
+
Copyright © 2002-2015 David
+ Abrahams, Stefan Seefeld
+
+
+
+
+
+
+ Welcome to Boost.Python, a C++ library which enables seamless interoperability
+ between C++ and the Python programming language. The library includes support
+ for:
+
+
+
+ References and Pointers
+
+
+ Globally Registered Type Coercions
+
+
+ Automatic Cross-Module Type Conversions
+
+
+ Efficient Function Overloading
+
+
+ C++ to Python Exception Translation
+
+
+ Default Arguments
+
+
+ Keyword Arguments
+
+
+ Manipulating Python objects in C++
+
+
+ Exporting C++ Iterators as Python Iterators
+
+
+ Documentation Strings
+
+
+
+ The development of these features was funded in part by grants to Boost Consulting
+ from the Lawrence Livermore National Laboratories
+ and by the Computational Crystallography Initiative
+ at Lawrence Berkeley National Laboratories.
+
+
+
+
+ Building Hybrid Systems With Boost Python ,
+ by Dave Abrahams and Ralf W. Grosse-Kunstleve
+
+
+
+Last revised: December 25, 2020 at 16:51:18 GMT
+
+
+
+
+
+
diff --git a/doc/html/numpy/.buildinfo b/doc/html/numpy/.buildinfo
new file mode 100644
index 00000000..87310e9e
--- /dev/null
+++ b/doc/html/numpy/.buildinfo
@@ -0,0 +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: 374e3c15a89643f46322a816fc37dcdf
+tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/doc/html/numpy/.doctrees/environment.pickle b/doc/html/numpy/.doctrees/environment.pickle
new file mode 100644
index 00000000..2d89ee8e
Binary files /dev/null and b/doc/html/numpy/.doctrees/environment.pickle differ
diff --git a/doc/html/numpy/.doctrees/index.doctree b/doc/html/numpy/.doctrees/index.doctree
new file mode 100644
index 00000000..0f07d220
Binary files /dev/null and b/doc/html/numpy/.doctrees/index.doctree differ
diff --git a/doc/html/numpy/.doctrees/reference/binary_ufunc.doctree b/doc/html/numpy/.doctrees/reference/binary_ufunc.doctree
new file mode 100644
index 00000000..70d373fa
Binary files /dev/null and b/doc/html/numpy/.doctrees/reference/binary_ufunc.doctree differ
diff --git a/doc/html/numpy/.doctrees/reference/dtype.doctree b/doc/html/numpy/.doctrees/reference/dtype.doctree
new file mode 100644
index 00000000..e77b328f
Binary files /dev/null and b/doc/html/numpy/.doctrees/reference/dtype.doctree differ
diff --git a/doc/html/numpy/.doctrees/reference/index.doctree b/doc/html/numpy/.doctrees/reference/index.doctree
new file mode 100644
index 00000000..8e6c5b11
Binary files /dev/null and b/doc/html/numpy/.doctrees/reference/index.doctree differ
diff --git a/doc/html/numpy/.doctrees/reference/multi_iter.doctree b/doc/html/numpy/.doctrees/reference/multi_iter.doctree
new file mode 100644
index 00000000..ae31dd5a
Binary files /dev/null and b/doc/html/numpy/.doctrees/reference/multi_iter.doctree differ
diff --git a/doc/html/numpy/.doctrees/reference/ndarray.doctree b/doc/html/numpy/.doctrees/reference/ndarray.doctree
new file mode 100644
index 00000000..7d7075b5
Binary files /dev/null and b/doc/html/numpy/.doctrees/reference/ndarray.doctree differ
diff --git a/doc/html/numpy/.doctrees/reference/unary_ufunc.doctree b/doc/html/numpy/.doctrees/reference/unary_ufunc.doctree
new file mode 100644
index 00000000..81734d8e
Binary files /dev/null and b/doc/html/numpy/.doctrees/reference/unary_ufunc.doctree differ
diff --git a/doc/html/numpy/.doctrees/tutorial/dtype.doctree b/doc/html/numpy/.doctrees/tutorial/dtype.doctree
new file mode 100644
index 00000000..992a3477
Binary files /dev/null and b/doc/html/numpy/.doctrees/tutorial/dtype.doctree differ
diff --git a/doc/html/numpy/.doctrees/tutorial/fromdata.doctree b/doc/html/numpy/.doctrees/tutorial/fromdata.doctree
new file mode 100644
index 00000000..ee881810
Binary files /dev/null and b/doc/html/numpy/.doctrees/tutorial/fromdata.doctree differ
diff --git a/doc/html/numpy/.doctrees/tutorial/index.doctree b/doc/html/numpy/.doctrees/tutorial/index.doctree
new file mode 100644
index 00000000..6d6e9ce1
Binary files /dev/null and b/doc/html/numpy/.doctrees/tutorial/index.doctree differ
diff --git a/doc/html/numpy/.doctrees/tutorial/ndarray.doctree b/doc/html/numpy/.doctrees/tutorial/ndarray.doctree
new file mode 100644
index 00000000..40157e7e
Binary files /dev/null and b/doc/html/numpy/.doctrees/tutorial/ndarray.doctree differ
diff --git a/doc/html/numpy/.doctrees/tutorial/simple.doctree b/doc/html/numpy/.doctrees/tutorial/simple.doctree
new file mode 100644
index 00000000..2a197d9b
Binary files /dev/null and b/doc/html/numpy/.doctrees/tutorial/simple.doctree differ
diff --git a/doc/html/numpy/.doctrees/tutorial/ufunc.doctree b/doc/html/numpy/.doctrees/tutorial/ufunc.doctree
new file mode 100644
index 00000000..6f68dea2
Binary files /dev/null and b/doc/html/numpy/.doctrees/tutorial/ufunc.doctree differ
diff --git a/doc/html/numpy/_sources/index.rst.txt b/doc/html/numpy/_sources/index.rst.txt
new file mode 100644
index 00000000..bb3b623e
--- /dev/null
+++ b/doc/html/numpy/_sources/index.rst.txt
@@ -0,0 +1,14 @@
+.. Boost.Python NumPy extension documentation master file, created by
+ sphinx-quickstart on Thu Oct 27 09:04:58 2011.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to the documentation of the Boost.Python NumPy extension!
+=================================================================
+
+.. toctree::
+ :maxdepth: 2
+
+ Tutorial
+ Reference
+
diff --git a/doc/html/numpy/_sources/reference/binary_ufunc.rst.txt b/doc/html/numpy/_sources/reference/binary_ufunc.rst.txt
new file mode 100644
index 00000000..0215e555
--- /dev/null
+++ b/doc/html/numpy/_sources/reference/binary_ufunc.rst.txt
@@ -0,0 +1,110 @@
+binary_ufunc
+============
+
+.. contents :: Table of Contents
+
+A ``binary_ufunc`` is a struct used as an intermediate step to broadcast two arguments so that a C++ function can be converted to a ufunc like function
+
+ ```` contains the ``binary_ufunc`` structure definitions
+
+
+synopsis
+--------
+
+::
+
+ namespace boost
+ {
+ namespace python
+ {
+ namespace numpy
+ {
+
+ template
+
+ struct binary_ufunc
+ {
+
+ static object call(TBinaryFunctor & self,
+ object const & input1,
+ object const & input2,
+ object const & output);
+
+ static object make();
+ };
+
+ }
+ }
+ }
+
+
+constructors
+------------
+
+::
+
+ struct example_binary_ufunc
+ {
+ typedef any_valid first_argument_type;
+ typedef any_valid second_argument_type;
+ typedef any_valid result_type;
+ };
+
+:Requirements: The ``any_valid`` type must be defined using typedef as a valid C++ type in order to use the struct methods correctly
+
+:Note: The struct must be exposed as a Python class, and an instance of the class must be created to use the ``call`` method corresponding to the ``__call__`` attribute of the Python object
+
+accessors
+---------
+
+::
+
+ template
+ static object call(TBinaryFunctor & self,
+ object const & input,
+ object const & output);
+
+:Requires: Typenames ``TBinaryFunctor`` and optionally ``TArgument1`` and ``TArgument2`` for argument type and ``TResult`` for result type
+
+:Effects: Passes a Python object to the underlying C++ functor after broadcasting its arguments
+
+::
+
+ template
+ static object make();
+
+:Requires: Typenames ``TBinaryFunctor`` and optionally ``TArgument1`` and ``TArgument2`` for argument type and ``TResult`` for result type
+
+:Returns: A Python function object to call the overloaded () operator in the struct (in typical usage)
+
+Example(s)
+----------
+
+::
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+ struct BinarySquare
+ {
+ typedef double first_argument_type;
+ typedef double second_argument_type;
+ typedef double result_type;
+
+ double operator()(double a,double b) const { return (a*a + b*b) ; }
+ };
+
+ p::object ud = p::class_ >("BinarySquare").def("__call__", np::binary_ufunc::make());
+ p::object inst = ud();
+ result_array = inst.attr("__call__")(demo_array,demo_array) ;
+ std::cout << "Square of list with binary ufunc is " << p::extract (p::str(result_array)) << std::endl ;
+
diff --git a/doc/html/numpy/_sources/reference/dtype.rst.txt b/doc/html/numpy/_sources/reference/dtype.rst.txt
new file mode 100644
index 00000000..03227116
--- /dev/null
+++ b/doc/html/numpy/_sources/reference/dtype.rst.txt
@@ -0,0 +1,92 @@
+dtype
+=====
+
+.. contents :: Table of Contents
+
+A `dtype`_ is an object describing the type of the elements of an ndarray
+
+.. _dtype: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#data-type-objects-dtype
+
+ ```` contains the method calls necessary to generate a python object equivalent to a numpy.dtype from builtin C++ objects, as well as to create custom dtypes from user defined types
+
+
+synopsis
+--------
+
+::
+
+ namespace boost
+ {
+ namespace python
+ {
+ namespace numpy
+ {
+
+ class dtype : public object
+ {
+ static python::detail::new_reference convert(object::object_cref arg, bool align);
+ public:
+
+ // Convert an arbitrary Python object to a data-type descriptor object.
+ template
+ explicit dtype(T arg, bool align=false);
+
+ // Get the built-in numpy dtype associated with the given scalar template type.
+ template static dtype get_builtin();
+
+ // Return the size of the data type in bytes.
+ int get_itemsize() const;
+ };
+
+ }
+ }
+ }
+
+constructors
+------------
+
+::
+
+ template
+ explicit dtype(T arg, bool align=false)
+
+:Requirements: ``T`` must be either :
+
+ * a built-in C++ typename convertible to object
+ * a valid python object or convertible to object
+
+:Effects: Constructs an object from the supplied python object / convertible
+ to object / builtin C++ data type
+
+:Throws: Nothing
+
+::
+
+ template static dtype get_builtin();
+
+:Requirements: The typename supplied, ``T`` must be a builtin C++ type also supported by numpy
+
+:Returns: Numpy dtype corresponding to builtin C++ type
+
+accessors
+---------
+
+::
+
+ int get_itemsize() const;
+
+:Returns: the size of the data type in bytes.
+
+
+Example(s)
+----------
+
+::
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+ np::dtype dtype = np::dtype::get_builtin();
+ p::tuple for_custom_dtype = p::make_tuple("ha",dtype);
+ np::dtype custom_dtype = np::dtype(list_for_dtype);
+
diff --git a/doc/html/numpy/_sources/reference/index.rst.txt b/doc/html/numpy/_sources/reference/index.rst.txt
new file mode 100644
index 00000000..5c0d852d
--- /dev/null
+++ b/doc/html/numpy/_sources/reference/index.rst.txt
@@ -0,0 +1,12 @@
+Boost.Python NumPy extension Reference
+======================================
+
+.. toctree::
+ :maxdepth: 2
+
+ dtype
+ ndarray
+ unary_ufunc
+ binary_ufunc
+ multi_iter
+
diff --git a/doc/html/numpy/_sources/reference/multi_iter.rst.txt b/doc/html/numpy/_sources/reference/multi_iter.rst.txt
new file mode 100644
index 00000000..c1d812ef
--- /dev/null
+++ b/doc/html/numpy/_sources/reference/multi_iter.rst.txt
@@ -0,0 +1,94 @@
+multi_iter
+==========
+
+.. contents :: Table of Contents
+
+A ``multi_iter`` is a Python object, intended to be used as an iterator It should generally only be used in loops.
+
+ ```` contains the class definitions for ``multi_iter``
+
+
+synopsis
+--------
+
+::
+
+ namespace boost
+ {
+ namespace python
+ {
+ namespace numpy
+ {
+
+ class multi_iter : public object
+ {
+ public:
+ void next();
+ bool not_done() const;
+ char * get_data(int n) const;
+ int const get_nd() const;
+ Py_intptr_t const * get_shape() const;
+ Py_intptr_t const shape(int n) const;
+ };
+
+
+ multi_iter make_multi_iter(object const & a1);
+ multi_iter make_multi_iter(object const & a1, object const & a2);
+ multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3);
+
+ }
+ }
+ }
+
+
+constructors
+------------
+
+::
+
+ multi_iter make_multi_iter(object const & a1);
+ multi_iter make_multi_iter(object const & a1, object const & a2);
+ multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3);
+
+:Returns: A Python iterator object broadcasting over one, two or three sequences as supplied
+
+accessors
+---------
+
+::
+
+ void next();
+
+:Effects: Increments the iterator
+
+::
+
+ bool not_done() const;
+
+:Returns: boolean value indicating whether the iterator is at its end
+
+::
+
+ char * get_data(int n) const;
+
+:Returns: a pointer to the element of the nth broadcasted array.
+
+::
+
+ int const get_nd() const;
+
+:Returns: the number of dimensions of the broadcasted array expression
+
+::
+
+ Py_intptr_t const * get_shape() const;
+
+:Returns: the shape of the broadcasted array expression as an array of integers.
+
+::
+
+ Py_intptr_t const shape(int n) const;
+
+:Returns: the shape of the broadcasted array expression in the nth dimension.
+
+
diff --git a/doc/html/numpy/_sources/reference/ndarray.rst.txt b/doc/html/numpy/_sources/reference/ndarray.rst.txt
new file mode 100644
index 00000000..1486c73a
--- /dev/null
+++ b/doc/html/numpy/_sources/reference/ndarray.rst.txt
@@ -0,0 +1,382 @@
+ndarray
+=======
+
+.. contents :: Table of Contents
+
+A `ndarray`_ is an N-dimensional array which contains items of the same type and size, where N is the number of dimensions and is specified in the form of a ``shape`` tuple. Optionally, the numpy ``dtype`` for the objects contained may also be specified.
+
+.. _ndarray: http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html
+.. _dtype: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#data-type-objects-dtype
+
+ ```` contains the structures and methods necessary to move raw data between C++ and Python and create ndarrays from the data
+
+
+
+synopsis
+--------
+
+::
+
+ namespace boost
+ {
+ namespace python
+ {
+ namespace numpy
+ {
+
+ class ndarray : public object
+ {
+
+ public:
+
+ enum bitflag
+ {
+ NONE=0x0, C_CONTIGUOUS=0x1, F_CONTIGUOUS=0x2, V_CONTIGUOUS=0x1|0x2,
+ ALIGNED=0x4, WRITEABLE=0x8, BEHAVED=0x4|0x8,
+ CARRAY_RO=0x1|0x4, CARRAY=0x1|0x4|0x8, CARRAY_MIS=0x1|0x8,
+ FARRAY_RO=0x2|0x4, FARRAY=0x2|0x4|0x8, FARRAY_MIS=0x2|0x8,
+ UPDATE_ALL=0x1|0x2|0x4, VARRAY=0x1|0x2|0x8, ALL=0x1|0x2|0x4|0x8
+ };
+
+ ndarray view(dtype const & dt) const;
+ ndarray astype(dtype const & dt) const;
+ ndarray copy() const;
+ int const shape(int n) const;
+ int const strides(int n) const;
+ char * get_data() const;
+ dtype get_dtype() const;
+ python::object get_base() const;
+ void set_base(object const & base);
+ Py_intptr_t const * get_shape() const;
+ Py_intptr_t const * get_strides() const;
+ int const get_nd() const;
+
+ bitflag const get_flags() const;
+
+ ndarray transpose() const;
+ ndarray squeeze() const;
+ ndarray reshape(tuple const & shape) const;
+ object scalarize() const;
+ };
+
+ ndarray zeros(tuple const & shape, dtype const & dt);
+ ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt);
+
+ ndarray empty(tuple const & shape, dtype const & dt);
+ ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt);
+
+ ndarray array(object const & obj);
+ ndarray array(object const & obj, dtype const & dt);
+
+ template
+ ndarray from_data(void * data,dtype const & dt,Container shape,Container strides,python::object const & owner);
+ template
+ ndarray from_data(void const * data, dtype const & dt, Container shape, Container strides, object const & owner);
+
+ ndarray from_object(object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
+ ndarray from_object(object const & obj, dtype const & dt,int nd, ndarray::bitflag flags=ndarray::NONE);
+ ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE);
+ ndarray from_object(object const & obj, int nd_min, int nd_max,ndarray::bitflag flags=ndarray::NONE);
+ ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE);
+ ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE)
+
+ ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b) ;
+ ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b);
+
+ }
+
+
+constructors
+------------
+
+::
+
+ ndarray view(dtype const & dt) const;
+
+:Returns: new ndarray with old ndarray data cast as supplied dtype
+
+::
+
+ ndarray astype(dtype const & dt) const;
+
+:Returns: new ndarray with old ndarray data converted to supplied dtype
+
+::
+
+ ndarray copy() const;
+
+:Returns: Copy of calling ndarray object
+
+::
+
+ ndarray transpose() const;
+
+:Returns: An ndarray with the rows and columns interchanged
+
+::
+
+ ndarray squeeze() const;
+
+:Returns: An ndarray with all unit-shaped dimensions removed
+
+::
+
+ ndarray reshape(tuple const & shape) const;
+
+:Requirements: The new ``shape`` of the ndarray must be supplied as a tuple
+
+:Returns: An ndarray with the same data but reshaped to the ``shape`` supplied
+
+
+::
+
+ object scalarize() const;
+
+:Returns: A scalar if the ndarray has only one element, otherwise it returns the entire array
+
+::
+
+ ndarray zeros(tuple const & shape, dtype const & dt);
+ ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt);
+
+:Requirements: The following parameters must be supplied as required :
+
+ * the ``shape`` or the size of all dimensions, as a tuple
+ * the ``dtype`` of the data
+ * the ``nd`` size for a square shaped ndarray
+ * the ``shape`` Py_intptr_t
+
+:Returns: A new ndarray with the given shape and data type, with data initialized to zero.
+
+::
+
+ ndarray empty(tuple const & shape, dtype const & dt);
+ ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt);
+
+
+:Requirements: The following parameters must be supplied :
+
+ * the ``shape`` or the size of all dimensions, as a tuple
+ * the ``dtype`` of the data
+ * the ``shape`` Py_intptr_t
+
+:Returns: A new ndarray with the given shape and data type, with data left uninitialized.
+
+::
+
+ ndarray array(object const & obj);
+ ndarray array(object const & obj, dtype const & dt);
+
+:Returns: A new ndarray from an arbitrary Python sequence, with dtype of each element specified optionally
+
+::
+
+ template
+ inline ndarray from_data(void * data,dtype const & dt,Container shape,Container strides,python::object const & owner)
+
+:Requirements: The following parameters must be supplied :
+
+ * the ``data`` which is a generic C++ data container
+ * the dtype ``dt`` of the data
+ * the ``shape`` of the ndarray as Python object
+ * the ``strides`` of each dimension of the array as a Python object
+ * the ``owner`` of the data, in case it is not the ndarray itself
+
+:Returns: ndarray with attributes and data supplied
+
+:Note: The ``Container`` typename must be one that is convertible to a std::vector or python object type
+
+::
+
+ ndarray from_object(object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
+
+:Requirements: The following parameters must be supplied :
+
+ * the ``obj`` Python object to convert to ndarray
+ * the dtype ``dt`` of the data
+ * minimum number of dimensions ``nd_min`` of the ndarray as Python object
+ * maximum number of dimensions ``nd_max`` of the ndarray as Python object
+ * optional ``flags`` bitflags
+
+:Returns: ndarray constructed with dimensions and data supplied as parameters
+
+::
+
+ inline ndarray from_object(object const & obj, dtype const & dt, int nd, ndarray::bitflag flags=ndarray::NONE);
+
+:Requirements: The following parameters must be supplied :
+
+ * the ``obj`` Python object to convert to ndarray
+ * the dtype ``dt`` of the data
+ * number of dimensions ``nd`` of the ndarray as Python object
+ * optional ``flags`` bitflags
+
+:Returns: ndarray with dimensions ``nd`` x ``nd`` and suplied parameters
+
+::
+
+ inline ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE)
+
+:Requirements: The following parameters must be supplied :
+
+ * the ``obj`` Python object to convert to ndarray
+ * the dtype ``dt`` of the data
+ * optional ``flags`` bitflags
+
+:Returns: Supplied Python object as ndarray
+
+::
+
+ ndarray from_object(object const & obj, int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
+
+:Requirements: The following parameters must be supplied :
+
+ * the ``obj`` Python object to convert to ndarray
+ * minimum number of dimensions ``nd_min`` of the ndarray as Python object
+ * maximum number of dimensions ``nd_max`` of the ndarray as Python object
+ * optional ``flags`` bitflags
+
+:Returns: ndarray with supplied dimension limits and parameters
+
+:Note: dtype need not be supplied here
+
+::
+
+ inline ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE);
+
+:Requirements: The following parameters must be supplied :
+
+ * the ``obj`` Python object to convert to ndarray
+ * the dtype ``dt`` of the data
+ * number of dimensions ``nd`` of the ndarray as Python object
+ * optional ``flags`` bitflags
+
+:Returns: ndarray of ``nd`` x ``nd`` dimensions constructed from the supplied object
+
+::
+
+ inline ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE)
+
+:Requirements: The following parameters must be supplied :
+
+ * the ``obj`` Python object to convert to ndarray
+ * optional ``flags`` bitflags
+
+:Returns: ndarray of same dimensions and dtype as supplied Python object
+
+
+accessors
+---------
+
+::
+
+ int const shape(int n) const;
+
+:Returns: The size of the n-th dimension of the ndarray
+
+::
+
+ int const strides(int n) const;
+
+:Returns: The stride of the nth dimension.
+
+::
+
+ char * get_data() const;
+
+:Returns: Array's raw data pointer as a char
+
+:Note: This returns char so stride math works properly on it.User will have to reinterpret_cast it.
+
+::
+
+ dtype get_dtype() const;
+
+:Returns: Array's data-type descriptor object (dtype)
+
+
+::
+
+ object get_base() const;
+
+:Returns: Object that owns the array's data, or None if the array owns its own data.
+
+
+::
+
+ void set_base(object const & base);
+
+:Returns: Set the object that owns the array's data. Exercise caution while using this
+
+
+::
+
+ Py_intptr_t const * get_shape() const;
+
+:Returns: Shape of the array as an array of integers
+
+
+::
+
+ Py_intptr_t const * get_strides() const;
+
+:Returns: Stride of the array as an array of integers
+
+
+::
+
+ int const get_nd() const;
+
+:Returns: Number of array dimensions
+
+
+::
+
+ bitflag const get_flags() const;
+
+:Returns: Array flags
+
+::
+
+ inline ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b)
+
+:Returns: bitflag logically OR-ed as (a | b)
+
+::
+
+ inline ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b)
+
+:Returns: bitflag logically AND-ed as (a & b)
+
+
+Example(s)
+----------
+
+::
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+ p::object tu = p::make_tuple('a','b','c') ;
+ np::ndarray example_tuple = np::array (tu) ;
+
+ p::list l ;
+ np::ndarray example_list = np::array (l) ;
+
+ np::dtype dt = np::dtype::get_builtin();
+ np::ndarray example_list1 = np::array (l,dt);
+
+ int data[] = {1,2,3,4} ;
+ p::tuple shape = p::make_tuple(4) ;
+ p::tuple stride = p::make_tuple(4) ;
+ p::object own ;
+ np::ndarray data_ex = np::from_data(data,dt,shape,stride,own);
+
+ uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
+ shape = p::make_tuple(3,2) ;
+ stride = p::make_tuple(4,2) ;
+ np::dtype dt1 = np::dtype::get_builtin();
+
+ np::ndarray mul_data_ex = np::from_data(mul_data,dt1, p::make_tuple(3,4),p::make_tuple(4,1),p::object());
+ mul_data_ex = np::from_data(mul_data,dt1, shape,stride,p::object());
+
diff --git a/doc/html/numpy/_sources/reference/unary_ufunc.rst.txt b/doc/html/numpy/_sources/reference/unary_ufunc.rst.txt
new file mode 100644
index 00000000..eaec034c
--- /dev/null
+++ b/doc/html/numpy/_sources/reference/unary_ufunc.rst.txt
@@ -0,0 +1,103 @@
+unary_ufunc
+===========
+
+.. contents :: Table of Contents
+
+A ``unary_ufunc`` is a struct used as an intermediate step to broadcast a single argument so that a C++ function can be converted to a ufunc like function
+
+ ```` contains the ``unary_ufunc`` structure definitions
+
+
+synopsis
+--------
+
+::
+
+ namespace boost
+ {
+ namespace python
+ {
+ namespace numpy
+ {
+
+ template
+ struct unary_ufunc
+ {
+
+ static object call(TUnaryFunctor & self,
+ object const & input,
+ object const & output) ;
+
+ static object make();
+
+ };
+ }
+ }
+ }
+
+
+constructors
+------------
+
+::
+
+ struct example_unary_ufunc
+ {
+ typedef any_valid_type argument_type;
+ typedef any_valid_type result_type;
+ };
+
+:Requirements: The ``any_valid`` type must be defined using typedef as a valid C++ type in order to use the struct methods correctly
+
+:Note: The struct must be exposed as a Python class, and an instance of the class must be created to use the ``call`` method corresponding to the ``__call__`` attribute of the Python object
+
+accessors
+---------
+
+::
+
+ template
+ static object call(TUnaryFunctor & self,
+ object const & input,
+ object const & output);
+
+:Requires: Typenames ``TUnaryFunctor`` and optionally ``TArgument`` for argument type and ``TResult`` for result type
+
+:Effects: Passes a Python object to the underlying C++ functor after broadcasting its arguments
+
+::
+
+ template
+ static object make();
+
+:Requires: Typenames ``TUnaryFunctor`` and optionally ``TArgument`` for argument type and ``TResult`` for result type
+
+:Returns: A Python function object to call the overloaded () operator in the struct (in typical usage)
+
+
+
+Example(s)
+----------
+
+::
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+ struct UnarySquare
+ {
+ typedef double argument_type;
+ typedef double result_type;
+ double operator()(double r) const { return r * r;}
+ };
+
+ p::object ud = p::class_ >("UnarySquare").def("__call__", np::unary_ufunc::make());
+ p::object inst = ud();
+ std::cout << "Square of unary scalar 1.0 is " << p::extract (p::str(inst.attr("__call__")(1.0))) << std::endl ;
+
diff --git a/doc/html/numpy/_sources/tutorial/dtype.rst.txt b/doc/html/numpy/_sources/tutorial/dtype.rst.txt
new file mode 100644
index 00000000..557e72ba
--- /dev/null
+++ b/doc/html/numpy/_sources/tutorial/dtype.rst.txt
@@ -0,0 +1,54 @@
+How to use dtypes
+=================
+
+Here is a brief tutorial to show how to create ndarrays with built-in python data types, and extract the types and values of member variables
+
+Like before, first get the necessary headers, setup the namespaces and initialize the Python runtime and numpy module::
+
+ #include
+ #include
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+ int main(int argc, char **argv)
+ {
+ Py_Initialize();
+ np::initialize();
+
+Next, we create the shape and dtype. We use the get_builtin method to get the numpy dtype corresponding to the builtin C++ dtype
+Here, we will create a 3x3 array passing a tuple with (3,3) for the size, and double as the data type ::
+
+ p::tuple shape = p::make_tuple(3, 3);
+ np::dtype dtype = np::dtype::get_builtin();
+ np::ndarray a = np::zeros(shape, dtype);
+
+Finally, we can print the array using the extract method in the python namespace.
+Here, we first convert the variable into a string, and then extract it as a C++ character array from the python string using the template ::
+
+ std::cout << "Original array:\n" << p::extract(p::str(a)) << std::endl;
+
+We can also print the dtypes of the data members of the ndarray by using the get_dtype method for the ndarray ::
+
+ std::cout << "Datatype is:\n" << p::extract(p::str(a.get_dtype())) << std::endl ;
+
+We can also create custom dtypes and build ndarrays with the custom dtypes
+
+We use the dtype constructor to create a custom dtype. This constructor takes a list as an argument.
+
+The list should contain one or more tuples of the format (variable name, variable type)
+
+So first create a tuple with a variable name and its dtype, double, to create a custom dtype ::
+
+ p::tuple for_custom_dtype = p::make_tuple("ha",dtype) ;
+
+Next, create a list, and add this tuple to the list. Then use the list to create the custom dtype ::
+
+ p::list list_for_dtype ;
+ list_for_dtype.append(for_custom_dtype) ;
+ np::dtype custom_dtype = np::dtype(list_for_dtype) ;
+
+We are now ready to create an ndarray with dimensions specified by \*shape\* and of custom dtpye ::
+
+ np::ndarray new_array = np::zeros(shape,custom_dtype);
+ }
diff --git a/doc/html/numpy/_sources/tutorial/fromdata.rst.txt b/doc/html/numpy/_sources/tutorial/fromdata.rst.txt
new file mode 100644
index 00000000..33bcee45
--- /dev/null
+++ b/doc/html/numpy/_sources/tutorial/fromdata.rst.txt
@@ -0,0 +1,56 @@
+How to access data using raw pointers
+=====================================
+
+One of the advantages of the ndarray wrapper is that the same data can be used in both Python and C++ and changes can be made to reflect at both ends.
+The from_data method makes this possible.
+
+Like before, first get the necessary headers, setup the namespaces and initialize the Python runtime and numpy module::
+
+ #include
+ #include
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+ int main(int argc, char **argv)
+ {
+ Py_Initialize();
+ np::initialize();
+
+Create an array in C++ , and pass the pointer to it to the from_data method to create an ndarray::
+
+ int arr[] = {1,2,3,4,5};
+ np::ndarray py_array = np::from_data(arr, np::dtype::get_builtin(),
+ p::make_tuple(5),
+ p::make_tuple(sizeof(int)),
+ p::object());
+
+Print the source C++ array, as well as the ndarray, to check if they are the same::
+
+ std::cout << "C++ array :" << std::endl;
+ for (int j=0;j<4;j++)
+ {
+ std::cout << arr[j] << ' ';
+ }
+ std::cout << std::endl
+ << "Python ndarray :" << p::extract(p::str(py_array)) << std::endl;
+
+Now, change an element in the Python ndarray, and check if the value changed correspondingly in the source C++ array::
+
+ py_array[1] = 5 ;
+ std::cout << "Is the change reflected in the C++ array used to create the ndarray ? " << std::endl;
+ for (int j = 0; j < 5; j++)
+ {
+ std::cout << arr[j] << ' ';
+ }
+
+Next, change an element of the source C++ array and see if it is reflected in the Python ndarray::
+
+ arr[2] = 8;
+ std::cout << std::endl
+ << "Is the change reflected in the Python ndarray ?" << std::endl
+ << p::extract(p::str(py_array)) << std::endl;
+ }
+
+As we can see, the changes are reflected across the ends. This happens because the from_data method passes the C++ array by reference to create the ndarray, and thus uses the same locations for storing data.
+
diff --git a/doc/html/numpy/_sources/tutorial/index.rst.txt b/doc/html/numpy/_sources/tutorial/index.rst.txt
new file mode 100644
index 00000000..3de2ef53
--- /dev/null
+++ b/doc/html/numpy/_sources/tutorial/index.rst.txt
@@ -0,0 +1,12 @@
+Boost.Python NumPy extension Tutorial
+=====================================
+
+.. toctree::
+ :maxdepth: 2
+
+ simple
+ dtype
+ ndarray
+ ufunc
+ fromdata
+
diff --git a/doc/html/numpy/_sources/tutorial/ndarray.rst.txt b/doc/html/numpy/_sources/tutorial/ndarray.rst.txt
new file mode 100644
index 00000000..b270da70
--- /dev/null
+++ b/doc/html/numpy/_sources/tutorial/ndarray.rst.txt
@@ -0,0 +1,99 @@
+Creating ndarrays
+=================
+
+The Boost.Numpy library exposes quite a few methods to create ndarrays. ndarrays can be created in a variety of ways, include empty arrays and zero filled arrays.
+ndarrays can also be created from arbitrary python sequences as well as from data and dtypes.
+
+This tutorial will introduce you to some of the ways in which you can create ndarrays. The methods covered here include creating ndarrays from arbitrary Python sequences, as well as from C++ containers, using both unit and non-unit strides
+
+First, as before, initialise the necessary namepaces and runtimes ::
+
+ #include
+ #include
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+ int main(int argc, char **argv)
+ {
+ Py_Initialize();
+ np::initialize();
+
+Let's now create an ndarray from a simple tuple. We first create a tuple object, and then pass it to the array method, to generate the necessary tuple ::
+
+ p::object tu = p::make_tuple('a','b','c');
+ np::ndarray example_tuple = np::array(tu);
+
+Let's now try the same with a list. We create an empty list, add an element using the append method, and as before, call the array method ::
+
+ p::list l;
+ l.append('a');
+ np::ndarray example_list = np::array (l);
+
+Optionally, we can also specify a dtype for the array ::
+
+ np::dtype dt = np::dtype::get_builtin();
+ np::ndarray example_list1 = np::array (l,dt);
+
+We can also create an array by supplying data arrays and a few other parameters.
+
+First,create an integer array ::
+
+ int data[] = {1,2,3,4,5};
+
+Create a shape, and strides, needed by the function ::
+
+ p::tuple shape = p::make_tuple(5);
+ p::tuple stride = p::make_tuple(sizeof(int));
+
+Here, shape is (4,) , and the stride is `sizeof(int)``.
+A stride is the number of bytes that must be traveled to get to the next desired element while constructing the ndarray.
+
+The function also needs an owner, to keep track of the data array passed. Passing none is dangerous ::
+
+ p::object own;
+
+The from_data function takes the data array, datatype,shape,stride and owner as arguments and returns an ndarray ::
+
+ np::ndarray data_ex1 = np::from_data(data,dt, shape,stride,own);
+
+Now let's print the ndarray we created ::
+
+ std::cout << "Single dimensional array ::" << std::endl
+ << p::extract(p::str(data_ex)) << std::endl;
+
+Let's make it a little more interesting. Lets make an 3x2 ndarray from a multi-dimensional array using non-unit strides
+
+First lets create a 3x4 array of 8-bit integers ::
+
+ uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
+
+Now let's create an array of 3x2 elements, picking the first and third elements from each row . For that, the shape will be 3x2.
+The strides will be 4x2 i.e. 4 bytes to go to the next desired row, and 2 bytes to go to the next desired column ::
+
+ shape = p::make_tuple(3,2);
+ stride = p::make_tuple(sizeof(uint8_t)*2,sizeof(uint8_t));
+
+Get the numpy dtype for the built-in 8-bit integer data type ::
+
+ np::dtype dt1 = np::dtype::get_builtin();
+
+Now lets first create and print out the ndarray as is.
+Notice how we can pass the shape and strides in the function directly, as well as the owner. The last part can be done because we don't have any use to
+manipulate the "owner" object ::
+
+ np::ndarray mul_data_ex = np::from_data(mul_data, dt1,
+ p::make_tuple(3,4),
+ p::make_tuple(4,1),
+ p::object());
+ std::cout << "Original multi dimensional array :: " << std::endl
+ << p::extract(p::str(mul_data_ex)) << std::endl;
+
+Now create the new ndarray using the shape and strides and print out the array we created using non-unit strides ::
+
+ mul_data_ex = np::from_data(mul_data, dt1, shape, stride, p::object());
+ std::cout << "Selective multidimensional array :: "<(p::str(mul_data_ex)) << std::endl ;
+ }
+
+.. note:: The from_data method will throw ``error_already_set`` if the number of elements dictated by the shape and the corresponding strides don't match.
diff --git a/doc/html/numpy/_sources/tutorial/simple.rst.txt b/doc/html/numpy/_sources/tutorial/simple.rst.txt
new file mode 100644
index 00000000..889eea11
--- /dev/null
+++ b/doc/html/numpy/_sources/tutorial/simple.rst.txt
@@ -0,0 +1,41 @@
+A simple tutorial on Arrays
+===========================
+
+Let's start with a simple tutorial to create and modify arrays.
+
+Get the necessary headers for numpy components and set up necessary namespaces::
+
+ #include
+ #include
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+Initialise the Python runtime, and the numpy module. Failure to call these results in segmentation errors::
+
+ int main(int argc, char **argv)
+ {
+ Py_Initialize();
+ np::initialize();
+
+
+Zero filled n-dimensional arrays can be created using the shape and data-type of the array as a parameter. Here, the shape is 3x3 and the datatype is the built-in float type::
+
+ p::tuple shape = p::make_tuple(3, 3);
+ np::dtype dtype = np::dtype::get_builtin();
+ np::ndarray a = np::zeros(shape, dtype);
+
+You can also create an empty array like this ::
+
+ np::ndarray b = np::empty(shape,dtype);
+
+Print the original and reshaped array. The array a which is a list is first converted to a string, and each value in the list is extracted using extract< >::
+
+ std::cout << "Original array:\n" << p::extract(p::str(a)) << std::endl;
+
+ // Reshape the array into a 1D array
+ a = a.reshape(p::make_tuple(9));
+ // Print it again.
+ std::cout << "Reshaped array:\n" << p::extract(p::str(a)) << std::endl;
+ }
+
diff --git a/doc/html/numpy/_sources/tutorial/ufunc.rst.txt b/doc/html/numpy/_sources/tutorial/ufunc.rst.txt
new file mode 100644
index 00000000..a3571dbc
--- /dev/null
+++ b/doc/html/numpy/_sources/tutorial/ufunc.rst.txt
@@ -0,0 +1,120 @@
+Ufuncs
+======
+
+Ufuncs or universal functions operate on ndarrays element by element, and support array broadcasting, type casting, and other features.
+
+Lets try and see how we can use the binary and unary ufunc methods
+
+After the neccessary includes ::
+
+ #include
+ #include
+
+ namespace p = boost::python;
+ namespace np = boost::python::numpy;
+
+Now we create the structs necessary to implement the ufuncs. The typedefs *must* be made as the ufunc generators take these typedefs as inputs and return an error otherwise ::
+
+ struct UnarySquare
+ {
+ typedef double argument_type;
+ typedef double result_type;
+
+ double operator()(double r) const { return r * r;}
+ };
+
+ struct BinarySquare
+ {
+ typedef double first_argument_type;
+ typedef double second_argument_type;
+ typedef double result_type;
+
+ double operator()(double a,double b) const { return (a*a + b*b) ; }
+ };
+
+Initialise the Python runtime and the numpy module ::
+
+ int main(int argc, char **argv)
+ {
+ Py_Initialize();
+ np::initialize();
+
+Now expose the struct UnarySquare to Python as a class, and let ud be the class object. ::
+
+ p::object ud = p::class_ >("UnarySquare");
+ ud.def("__call__", np::unary_ufunc::make());
+
+Let inst be an instance of the class ud ::
+
+ p::object inst = ud();
+
+Use the "__call__" method to call the overloaded () operator and print the value ::
+
+ std::cout << "Square of unary scalar 1.0 is " << p::extract(p::str(inst.attr("__call__")(1.0))) << std::endl;
+
+Create an array in C++ ::
+
+ int arr[] = {1,2,3,4} ;
+
+
+..and use it to create the ndarray in Python ::
+
+ np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin(),
+ p::make_tuple(4),
+ p::make_tuple(4),
+ p::object());
+
+Print out the demo array ::
+
+ std::cout << "Demo array is " << p::extract(p::str(demo_array)) << std::endl;
+
+Call the "__call__" method to perform the operation and assign the value to result_array ::
+
+ p::object result_array = inst.attr("__call__")(demo_array);
+
+Print the resultant array ::
+
+ std::cout << "Square of demo array is " << p::extract(p::str(result_array)) << std::endl;
+
+Lets try the same with a list ::
+
+ p::list li;
+ li.append(3);
+ li.append(7);
+
+Print out the demo list ::
+
+ std::cout << "Demo list is " << p::extract(p::str(li)) << std::endl;
+
+Call the ufunc for the list ::
+
+ result_array = inst.attr("__call__")(li);
+
+And print the list out ::
+
+ std::cout << "Square of demo list is " << p::extract(p::str(result_array)) << std::endl;
+
+Now lets try Binary ufuncs. Again, expose the struct BinarySquare to Python as a class, and let ud be the class object ::
+
+ ud = p::class_ >("BinarySquare");
+ ud.def("__call__", np::binary_ufunc::make());
+
+And initialise ud ::
+
+ inst = ud();
+
+Print the two input lists ::
+
+ std::cout << "The two input list for binary ufunc are " << std::endl
+ << p::extract(p::str(demo_array)) << std::endl
+ << p::extract(p::str(demo_array)) << std::endl;
+
+Call the binary ufunc taking demo_array as both inputs ::
+
+ result_array = inst.attr("__call__")(demo_array,demo_array);
+
+And print the output ::
+
+ std::cout << "Square of list with binary ufunc is " << p::extract(p::str(result_array)) << std::endl;
+ }
+
diff --git a/doc/html/numpy/_static/basic.css b/doc/html/numpy/_static/basic.css
new file mode 100644
index 00000000..0807176e
--- /dev/null
+++ b/doc/html/numpy/_static/basic.css
@@ -0,0 +1,676 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+ width: 100%;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+ word-wrap: break-word;
+ overflow-wrap : break-word;
+}
+
+div.sphinxsidebar ul {
+ list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox form.search {
+ overflow: hidden;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+ float: left;
+ width: 80%;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+ float: left;
+ width: 20%;
+ border-left: none;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+
+img {
+ border: 0;
+ max-width: 100%;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li div.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+ width: 90%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable ul {
+ margin-top: 0;
+ margin-bottom: 0;
+ list-style-type: none;
+}
+
+table.indextable > tbody > tr > td > ul {
+ padding-left: 0em;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+div.modindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+/* -- domain module index --------------------------------------------------- */
+
+table.modindextable td {
+ padding: 2px;
+ border-collapse: collapse;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+div.body {
+ min-width: 450px;
+ max-width: 800px;
+}
+
+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;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6: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;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.align-right {
+ text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px 7px 0 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+ border: 1px solid #ccc;
+ padding: 7px 7px 0 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.align-center {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+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;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+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 {
+}
+
+/* -- field list styles ----------------------------------------------------- */
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+.field-name {
+ -moz-hyphens: manual;
+ -ms-hyphens: manual;
+ -webkit-hyphens: manual;
+ hyphens: manual;
+}
+
+/* -- hlist styles ---------------------------------------------------------- */
+
+table.hlist td {
+ vertical-align: top;
+}
+
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+ list-style: decimal;
+}
+
+ol.loweralpha {
+ list-style: lower-alpha;
+}
+
+ol.upperalpha {
+ list-style: upper-alpha;
+}
+
+ol.lowerroman {
+ list-style: lower-roman;
+}
+
+ol.upperroman {
+ list-style: upper-roman;
+}
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd p {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+dt:target, span.highlighted {
+ background-color: #fbe54e;
+}
+
+rect.highlighted {
+ fill: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.sig-paren {
+ font-size: larger;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+.footnote:target {
+ background-color: #ffa;
+}
+
+.line-block {
+ display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.line-block .line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+ font-family: sans-serif;
+}
+
+.accelerator {
+ text-decoration: underline;
+}
+
+.classifier {
+ font-style: oblique;
+}
+
+abbr, acronym {
+ border-bottom: dotted 1px;
+ cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+ overflow-y: hidden; /* fixes display issues on Chrome browsers */
+}
+
+span.pre {
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ -webkit-hyphens: none;
+ hyphens: none;
+}
+
+td.linenos pre {
+ padding: 5px 0px;
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ margin-left: 0.5em;
+}
+
+table.highlighttable td {
+ padding: 0 0.5em 0 0.5em;
+}
+
+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;
+}
+
+code.descclassname {
+ background-color: transparent;
+}
+
+code.xref, a code {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
+ background-color: transparent;
+}
+
+.viewcode-link {
+ float: right;
+}
+
+.viewcode-back {
+ float: right;
+ font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+ margin: -1px -10px;
+ padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+ vertical-align: middle;
+}
+
+div.body div.math p {
+ text-align: center;
+}
+
+span.eqno {
+ float: right;
+}
+
+span.eqno a.headerlink {
+ position: relative;
+ left: 0px;
+ z-index: 1;
+}
+
+div.math:hover a.headerlink {
+ visibility: visible;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ #top-link {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/doc/html/numpy/_static/boost.css b/doc/html/numpy/_static/boost.css
new file mode 100644
index 00000000..28f89359
--- /dev/null
+++ b/doc/html/numpy/_static/boost.css
@@ -0,0 +1,716 @@
+
+/*=============================================================================
+Copyright (c) 2004 Joel de Guzman
+http://spirit.sourceforge.net/
+
+Copyright 2013 Niall Douglas additions for colors and alignment.
+Copyright 2013 Paul A. Bristow additions for more colors and alignments.
+
+Distributed under the Boost Software License, Version 1.0. (See accompany-
+ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+/*=============================================================================
+Body defaults
+=============================================================================*/
+
+ body
+ {
+ margin: 1em;
+ font-family: sans-serif;
+ }
+
+/*=============================================================================
+Paragraphs
+=============================================================================*/
+
+ p
+ {
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.15;
+ }
+
+/*=============================================================================
+Program listings
+=============================================================================*/
+
+ /* Code on paragraphs */
+ p tt.computeroutput
+ {
+ font-size: 9pt;
+ }
+
+ pre.synopsis
+ {
+ font-size: 9pt;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ .programlisting,
+ .screen
+ {
+ font-size: 9pt;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ /* Program listings in tables don't get borders */
+ td .programlisting,
+ td .screen
+ {
+ margin: 0pc 0pc 0pc 0pc;
+ padding: 0pc 0pc 0pc 0pc;
+ }
+
+/*=============================================================================
+Headings
+=============================================================================*/
+
+ h1, h2, h3, h4, h5, h6
+ {
+ text-align: left;
+ margin: 1em 0em 0.5em 0em;
+ font-weight: bold;
+ }
+
+ h1 { font-size: 140%; }
+ h2 { font-weight: bold; font-size: 140%; }
+ h3 { font-weight: bold; font-size: 130%; }
+ h4 { font-weight: bold; font-size: 120%; }
+ h5 { font-weight: normal; font-style: italic; font-size: 110%; }
+ h6 { font-weight: normal; font-style: italic; font-size: 100%; }
+
+ /* Top page titles */
+ title,
+ h1.title,
+ h2.title
+ h3.title,
+ h4.title,
+ h5.title,
+ h6.title,
+ .refentrytitle
+ {
+ font-weight: bold;
+ margin-bottom: 1pc;
+ }
+
+ h1.title { font-size: 140% }
+ h2.title { font-size: 140% }
+ h3.title { font-size: 130% }
+ h4.title { font-size: 120% }
+ h5.title { font-size: 110% }
+ h6.title { font-size: 100% }
+
+ .section h1
+ {
+ margin: 0em 0em 0.5em 0em;
+ font-size: 140%;
+ }
+
+ .section h2 { font-size: 140% }
+ .section h3 { font-size: 130% }
+ .section h4 { font-size: 120% }
+ .section h5 { font-size: 110% }
+ .section h6 { font-size: 100% }
+
+ /* Code on titles */
+ h1 tt.computeroutput { font-size: 140% }
+ h2 tt.computeroutput { font-size: 140% }
+ h3 tt.computeroutput { font-size: 130% }
+ h4 tt.computeroutput { font-size: 130% }
+ h5 tt.computeroutput { font-size: 130% }
+ h6 tt.computeroutput { font-size: 130% }
+
+
+/*=============================================================================
+Author
+=============================================================================*/
+
+ h3.author
+ {
+ font-size: 100%
+ }
+
+/*=============================================================================
+Lists
+=============================================================================*/
+
+ li
+ {
+ font-size: 10pt;
+ line-height: 1.3;
+ }
+
+ /* Unordered lists */
+ ul
+ {
+ text-align: left;
+ }
+
+ /* Ordered lists */
+ ol
+ {
+ text-align: left;
+ }
+
+/*=============================================================================
+Links
+=============================================================================*/
+
+ a
+ {
+ text-decoration: none; /* no underline */
+ }
+
+ a:hover
+ {
+ text-decoration: underline;
+ }
+
+/*=============================================================================
+Spirit style navigation
+=============================================================================*/
+
+ .spirit-nav
+ {
+ text-align: right;
+ }
+
+ .spirit-nav a
+ {
+ color: white;
+ padding-left: 0.5em;
+ }
+
+ .spirit-nav img
+ {
+ border-width: 0px;
+ }
+
+/*=============================================================================
+Copyright footer
+=============================================================================*/
+ .copyright-footer
+ {
+ text-align: right;
+ font-size: 70%;
+ }
+
+ .copyright-footer p
+ {
+ text-align: right;
+ font-size: 80%;
+ }
+
+/*=============================================================================
+Table of contents
+=============================================================================*/
+
+ div.toc
+ {
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.1pc 1pc 0.1pc 1pc;
+ font-size: 80%;
+ line-height: 1.15;
+ }
+
+ .boost-toc
+ {
+ float: right;
+ padding: 0.5pc;
+ }
+
+ /* Code on toc */
+ .toc .computeroutput { font-size: 120% }
+
+ /* No margin on nested menus */
+
+ .toc dl dl { margin: 0; }
+
+/*=============================================================================
+Tables
+=============================================================================*/
+
+ .table-title,
+ div.table p.title
+ {
+ margin-left: 4%;
+ padding-right: 0.5em;
+ padding-left: 0.5em;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ width: 92%;
+ margin-left: 4%;
+ margin-right: 4%;
+ }
+
+ div.informaltable table,
+ div.table table
+ {
+ padding: 4px;
+ }
+
+ /* Table Cells */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ padding: 0.5em;
+ text-align: left;
+ font-size: 9pt;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ padding: 0.5em 0.5em 0.5em 0.5em;
+ border: 1pt solid white;
+ font-size: 80%;
+ }
+
+ table.simplelist
+ {
+ width: auto !important;
+ margin: 0em !important;
+ padding: 0em !important;
+ border: none !important;
+ }
+ table.simplelist td
+ {
+ margin: 0em !important;
+ padding: 0em !important;
+ text-align: left !important;
+ font-size: 9pt !important;
+ border: none !important;
+ }
+
+/*=============================================================================
+Suppress margins in tables
+=============================================================================*/
+
+ table th > *:first-child,
+ table td > *:first-child
+ {
+ margin-top: 0;
+ }
+
+ table th > *:last-child,
+ table td > *:last-child
+ {
+ margin-bottom: 0;
+ }
+
+/*=============================================================================
+Blurbs
+=============================================================================*/
+
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ p.blurb
+ {
+ font-size: 9pt; /* A little bit smaller than the main text */
+ line-height: 1.2;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ p.blurb img
+ {
+ padding: 1pt;
+ }
+
+/*=============================================================================
+Variable Lists
+=============================================================================*/
+
+ div.variablelist
+ {
+ margin: 1em 0;
+ }
+
+ /* Make the terms in definition lists bold */
+ div.variablelist dl dt,
+ span.term
+ {
+ font-weight: bold;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td
+ {
+ text-align: left;
+ vertical-align: top;
+ padding: 0em 2em 0em 0em;
+ font-size: 10pt;
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+ div.variablelist dl dt
+ {
+ margin-bottom: 0.2em;
+ }
+
+ div.variablelist dl dd
+ {
+ margin: 0em 0em 0.5em 2em;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td p,
+ div.variablelist dl dd p
+ {
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+/*=============================================================================
+Misc
+=============================================================================*/
+
+ /* Title of books and articles in bibliographies */
+ span.title
+ {
+ font-style: italic;
+ }
+
+ span.underline
+ {
+ text-decoration: underline;
+ }
+
+ span.strikethrough
+ {
+ text-decoration: line-through;
+ }
+
+ /* Copyright, Legal Notice */
+ div div.legalnotice p
+ {
+ text-align: left
+ }
+
+/*=============================================================================
+Colors
+=============================================================================*/
+
+ @media screen
+ {
+ body {
+ background-color: #FFFFFF;
+ color: #000000;
+ }
+
+ /* Syntax Highlighting */
+ .keyword { color: #0000AA; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #402080; }
+ .char { color: teal; }
+ .comment { color: #800000; }
+ .string { color: teal; }
+ .number { color: teal; }
+ .white_bkd { background-color: #FFFFFF; }
+ .dk_grey_bkd { background-color: #999999; }
+
+ /* Links */
+ a, a .keyword, a .identifier, a .special, a .preprocessor
+ a .char, a .comment, a .string, a .number
+ {
+ color: #005a9c;
+ }
+
+ a:visited, a:visited .keyword, a:visited .identifier,
+ a:visited .special, a:visited .preprocessor a:visited .char,
+ a:visited .comment, a:visited .string, a:visited .number
+ {
+ color: #9c5a9c;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ {
+ text-decoration: none; /* no underline */
+ color: #000000;
+ }
+
+ /* Copyright, Legal Notice */
+ .copyright
+ {
+ color: #666666;
+ font-size: small;
+ }
+
+ div div.legalnotice p
+ {
+ color: #666666;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Blurbs */
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ p.blurb
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ div.toc
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ background-color: #F0F0F0;
+ border: 1px solid #DCDCDC;
+ }
+
+ .copyright-footer
+ {
+ color: #8F8F8F;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ color: #00A000;
+ }
+ }
+
+ @media print
+ {
+ /* Links */
+ a
+ {
+ color: black;
+ }
+
+ a:visited
+ {
+ color: black;
+ }
+
+ .spirit-nav
+ {
+ display: none;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid gray;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid gray;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ div.toc
+ {
+ border: 1px solid gray;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ border: 1px solid gray;
+ border-collapse: collapse;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid gray;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ border: 1px solid gray;
+ }
+
+ table.simplelist tr td
+ {
+ border: none !important;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ font-weight: bold;
+ }
+ }
+
+/*=============================================================================
+Images
+=============================================================================*/
+
+ span.inlinemediaobject img
+ {
+ vertical-align: middle;
+ }
+
+/*==============================================================================
+Super and Subscript: style so that line spacing isn't effected, see
+http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341
+==============================================================================*/
+
+sup,
+sub {
+height: 0;
+line-height: 1;
+vertical-align: baseline;
+position: relative;
+
+}
+
+/* For internet explorer: */
+
+* html sup,
+* html sub {
+vertical-align: bottom;
+}
+
+sup {
+bottom: 1ex;
+}
+
+sub {
+top: .5ex;
+}
+
+/*==============================================================================
+Indexes: pretty much the same as the TOC.
+==============================================================================*/
+
+ .index
+ {
+ font-size: 80%;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ margin-left: 0px;
+ }
+
+ .index ul
+ {
+ padding-left: 3em;
+ }
+
+ .index p
+ {
+ padding: 2px;
+ margin: 2px;
+ }
+
+ .index-entry-level-0
+ {
+ font-weight: bold;
+ }
+
+ .index em
+ {
+ font-weight: bold;
+ }
+
+
+/*==============================================================================
+Alignment and coloring use 'role' feature, available from Quickbook 1.6 up.
+Added from Niall Douglas for role color and alignment.
+http://article.gmane.org/gmane.comp.lib.boost.devel/243318
+*/
+
+/* Add text alignment (see http://www.w3schools.com/cssref/pr_text_text-align.asp) */
+span.aligncenter
+{
+ display: inline-block; width: 100%; text-align: center;
+}
+span.alignright
+{
+ display: inline-block; width: 100%; text-align: right;
+}
+/* alignleft is the default. */
+span.alignleft
+{
+ display: inline-block; width: 100%; text-align: left;
+}
+
+/* alignjustify stretches the word spacing so that each line has equal width
+within a chosen fraction of page width (here arbitrarily 20%).
+*Not* useful inside table items as the column width remains the total string width.
+Nor very useful, except to temporarily restrict the width.
+*/
+span.alignjustify
+{
+ display: inline-block; width: 20%; text-align: justify;
+}
+
+/* Text colors.
+Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywords.
+Quickbook Usage: [role red Some red text]
+
+*/
+span.red { inline-block; color: red; }
+span.green { color: green; }
+span.lime { color: #00FF00; }
+span.blue { color: blue; }
+span.navy { color: navy; }
+span.yellow { color: yellow; }
+span.magenta { color: magenta; }
+span.indigo { color: #4B0082; }
+span.cyan { color: cyan; }
+span.purple { color: purple; }
+span.gold { color: gold; }
+span.silver { color: silver; } /* lighter gray */
+span.gray { color: #808080; } /* light gray */
diff --git a/doc/html/numpy/_static/boost.png b/doc/html/numpy/_static/boost.png
new file mode 100644
index 00000000..b4d51fcd
Binary files /dev/null and b/doc/html/numpy/_static/boost.png differ
diff --git a/doc/html/numpy/_static/bpl.png b/doc/html/numpy/_static/bpl.png
new file mode 100644
index 00000000..c2d8c69e
Binary files /dev/null and b/doc/html/numpy/_static/bpl.png differ
diff --git a/doc/html/numpy/_static/classic.css b/doc/html/numpy/_static/classic.css
new file mode 100644
index 00000000..8c6dae44
--- /dev/null
+++ b/doc/html/numpy/_static/classic.css
@@ -0,0 +1,261 @@
+/*
+ * classic.css_t
+ * ~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- classic theme.
+ *
+ * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+ font-family: sans-serif;
+ font-size: 100%;
+ background-color: #11303d;
+ color: #000;
+ margin: 0;
+ padding: 0;
+}
+
+div.document {
+ background-color: #1c4e63;
+}
+
+div.documentwrapper {
+ float: left;
+ width: 100%;
+}
+
+div.bodywrapper {
+ margin: 0 0 0 230px;
+}
+
+div.body {
+ background-color: #ffffff;
+ color: #000000;
+ padding: 0 20px 30px 20px;
+}
+
+div.footer {
+ color: #ffffff;
+ width: 100%;
+ padding: 9px 0 9px 0;
+ text-align: center;
+ font-size: 75%;
+}
+
+div.footer a {
+ color: #ffffff;
+ text-decoration: underline;
+}
+
+div.related {
+ background-color: #133f52;
+ line-height: 30px;
+ color: #ffffff;
+}
+
+div.related a {
+ color: #ffffff;
+}
+
+div.sphinxsidebar {
+}
+
+div.sphinxsidebar h3 {
+ font-family: 'Trebuchet MS', sans-serif;
+ color: #ffffff;
+ font-size: 1.4em;
+ font-weight: normal;
+ margin: 0;
+ padding: 0;
+}
+
+div.sphinxsidebar h3 a {
+ color: #ffffff;
+}
+
+div.sphinxsidebar h4 {
+ font-family: 'Trebuchet MS', sans-serif;
+ color: #ffffff;
+ font-size: 1.3em;
+ font-weight: normal;
+ margin: 5px 0 0 0;
+ padding: 0;
+}
+
+div.sphinxsidebar p {
+ color: #ffffff;
+}
+
+div.sphinxsidebar p.topless {
+ margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+ margin: 10px;
+ padding: 0;
+ color: #ffffff;
+}
+
+div.sphinxsidebar a {
+ color: #98dbcc;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+
+
+/* -- hyperlink styles ------------------------------------------------------ */
+
+a {
+ color: #355f7c;
+ text-decoration: none;
+}
+
+a:visited {
+ color: #355f7c;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+
+
+/* -- body styles ----------------------------------------------------------- */
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+ font-family: 'Trebuchet MS', sans-serif;
+ background-color: #f2f2f2;
+ font-weight: normal;
+ color: #20435c;
+ border-bottom: 1px solid #ccc;
+ margin: 20px -20px 10px -20px;
+ padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+ color: #c60f0f;
+ font-size: 0.8em;
+ padding: 0 4px 0 4px;
+ text-decoration: none;
+}
+
+a.headerlink:hover {
+ background-color: #c60f0f;
+ color: white;
+}
+
+div.body p, div.body dd, div.body li, div.body blockquote {
+ text-align: justify;
+ line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+ display: inline;
+}
+
+div.admonition p {
+ margin-bottom: 5px;
+}
+
+div.admonition pre {
+ margin-bottom: 5px;
+}
+
+div.admonition ul, div.admonition ol {
+ margin-bottom: 5px;
+}
+
+div.note {
+ background-color: #eee;
+ border: 1px solid #ccc;
+}
+
+div.seealso {
+ background-color: #ffc;
+ border: 1px solid #ff6;
+}
+
+div.topic {
+ background-color: #eee;
+}
+
+div.warning {
+ background-color: #ffe4e4;
+ border: 1px solid #f66;
+}
+
+p.admonition-title {
+ display: inline;
+}
+
+p.admonition-title:after {
+ content: ":";
+}
+
+pre {
+ padding: 5px;
+ background-color: #eeffcc;
+ color: #333333;
+ line-height: 120%;
+ border: 1px solid #ac9;
+ border-left: none;
+ border-right: none;
+}
+
+code {
+ background-color: #ecf0f3;
+ padding: 0 1px 0 1px;
+ font-size: 0.95em;
+}
+
+th {
+ background-color: #ede;
+}
+
+.warning code {
+ background: #efc2c2;
+}
+
+.note code {
+ background: #d6d6d6;
+}
+
+.viewcode-back {
+ font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+ background-color: #f4debf;
+ border-top: 1px solid #ac9;
+ border-bottom: 1px solid #ac9;
+}
+
+div.code-block-caption {
+ color: #efefef;
+ background-color: #1c4e63;
+}
\ No newline at end of file
diff --git a/doc/html/numpy/_static/default.css b/doc/html/numpy/_static/default.css
new file mode 100644
index 00000000..81b93636
--- /dev/null
+++ b/doc/html/numpy/_static/default.css
@@ -0,0 +1 @@
+@import url("classic.css");
diff --git a/doc/html/numpy/_static/doctools.js b/doc/html/numpy/_static/doctools.js
new file mode 100644
index 00000000..344db17d
--- /dev/null
+++ b/doc/html/numpy/_static/doctools.js
@@ -0,0 +1,315 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+ "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+ "profile", "profileEnd"];
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+ return decodeURIComponent(x).replace(/\+/g, ' ');
+};
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+ if (typeof s === 'undefined')
+ s = document.location.search;
+ var parts = s.substr(s.indexOf('?') + 1).split('&');
+ var result = {};
+ for (var i = 0; i < parts.length; i++) {
+ var tmp = parts[i].split('=', 2);
+ var key = jQuery.urldecode(tmp[0]);
+ var value = jQuery.urldecode(tmp[1]);
+ if (key in result)
+ result[key].push(value);
+ else
+ result[key] = [value];
+ }
+ return result;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+ function highlight(node, addItems) {
+ if (node.nodeType === 3) {
+ var val = node.nodeValue;
+ var pos = val.toLowerCase().indexOf(text);
+ if (pos >= 0 &&
+ !jQuery(node.parentNode).hasClass(className) &&
+ !jQuery(node.parentNode).hasClass("nohighlight")) {
+ var span;
+ var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
+ if (isInSVG) {
+ span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+ } else {
+ span = document.createElement("span");
+ span.className = className;
+ }
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+ document.createTextNode(val.substr(pos + text.length)),
+ node.nextSibling));
+ node.nodeValue = val.substr(0, pos);
+ if (isInSVG) {
+ var bbox = span.getBBox();
+ var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+ rect.x.baseVal.value = bbox.x;
+ rect.y.baseVal.value = bbox.y;
+ rect.width.baseVal.value = bbox.width;
+ rect.height.baseVal.value = bbox.height;
+ rect.setAttribute('class', className);
+ var parentOfText = node.parentNode.parentNode;
+ addItems.push({
+ "parent": node.parentNode,
+ "target": rect});
+ }
+ }
+ }
+ else if (!jQuery(node).is("button, select, textarea")) {
+ jQuery.each(node.childNodes, function() {
+ highlight(this, addItems);
+ });
+ }
+ }
+ var addItems = [];
+ var result = this.each(function() {
+ highlight(this, addItems);
+ });
+ for (var i = 0; i < addItems.length; ++i) {
+ jQuery(addItems[i].parent).before(addItems[i].target);
+ }
+ return result;
+};
+
+/*
+ * 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.
+ */
+var Documentation = {
+
+ init : function() {
+ this.fixFirefoxAnchorBug();
+ this.highlightSearchWords();
+ this.initIndexTable();
+ if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
+ this.initOnKeyListeners();
+ }
+ },
+
+ /**
+ * i18n support
+ */
+ TRANSLATIONS : {},
+ PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
+ LOCALE : 'unknown',
+
+ // gettext and ngettext don't access this so that the functions
+ // can safely bound to a different name (_ = Documentation.gettext)
+ gettext : function(string) {
+ var translated = Documentation.TRANSLATIONS[string];
+ if (typeof translated === 'undefined')
+ return string;
+ return (typeof translated === 'string') ? translated : translated[0];
+ },
+
+ ngettext : function(singular, plural, n) {
+ var translated = Documentation.TRANSLATIONS[singular];
+ if (typeof translated === 'undefined')
+ return (n == 1) ? singular : plural;
+ return translated[Documentation.PLURALEXPR(n)];
+ },
+
+ addTranslations : function(catalog) {
+ for (var key in catalog.messages)
+ this.TRANSLATIONS[key] = catalog.messages[key];
+ this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+ this.LOCALE = catalog.locale;
+ },
+
+ /**
+ * add context elements like header anchor links
+ */
+ addContextElements : function() {
+ $('div[id] > :header:first').each(function() {
+ $('').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this headline')).
+ appendTo(this);
+ });
+ $('dt[id]').each(function() {
+ $('').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this definition')).
+ appendTo(this);
+ });
+ },
+
+ /**
+ * workaround a firefox stupidity
+ * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
+ */
+ fixFirefoxAnchorBug : function() {
+ if (document.location.hash && $.browser.mozilla)
+ window.setTimeout(function() {
+ document.location.href += '';
+ }, 10);
+ },
+
+ /**
+ * highlight the search words provided in the url in the text
+ */
+ highlightSearchWords : function() {
+ var params = $.getQueryParameters();
+ var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+ if (terms.length) {
+ var body = $('div.body');
+ if (!body.length) {
+ body = $('body');
+ }
+ window.setTimeout(function() {
+ $.each(terms, function() {
+ body.highlightText(this.toLowerCase(), 'highlighted');
+ });
+ }, 10);
+ $('' + _('Hide Search Matches') + '
')
+ .appendTo($('#searchbox'));
+ }
+ },
+
+ /**
+ * init the domain index toggle buttons
+ */
+ initIndexTable : function() {
+ var togglers = $('img.toggler').click(function() {
+ var src = $(this).attr('src');
+ var idnum = $(this).attr('id').substr(7);
+ $('tr.cg-' + idnum).toggle();
+ if (src.substr(-9) === 'minus.png')
+ $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+ else
+ $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+ }).css('display', '');
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+ togglers.click();
+ }
+ },
+
+ /**
+ * helper function to hide the search marks again
+ */
+ hideSearchWords : function() {
+ $('#searchbox .highlight-link').fadeOut(300);
+ $('span.highlighted').removeClass('highlighted');
+ },
+
+ /**
+ * make the url absolute
+ */
+ makeURL : function(relativeURL) {
+ return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+ },
+
+ /**
+ * get the current relative url
+ */
+ getCurrentURL : function() {
+ var path = document.location.pathname;
+ var parts = path.split(/\//);
+ $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+ if (this === '..')
+ parts.pop();
+ });
+ 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;
+ }
+ }
+ }
+ });
+ }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+ Documentation.init();
+});
diff --git a/doc/html/numpy/_static/documentation_options.js b/doc/html/numpy/_static/documentation_options.js
new file mode 100644
index 00000000..1925df3b
--- /dev/null
+++ b/doc/html/numpy/_static/documentation_options.js
@@ -0,0 +1,10 @@
+var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
+ VERSION: '1.0',
+ LANGUAGE: 'None',
+ COLLAPSE_INDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true,
+ SOURCELINK_SUFFIX: '.txt',
+ NAVIGATION_WITH_KEYS: false,
+};
\ No newline at end of file
diff --git a/doc/html/numpy/_static/file.png b/doc/html/numpy/_static/file.png
new file mode 100644
index 00000000..a858a410
Binary files /dev/null and b/doc/html/numpy/_static/file.png differ
diff --git a/doc/html/numpy/_static/home.png b/doc/html/numpy/_static/home.png
new file mode 100644
index 00000000..5584aacb
Binary files /dev/null and b/doc/html/numpy/_static/home.png differ
diff --git a/doc/html/numpy/_static/jquery.js b/doc/html/numpy/_static/jquery.js
new file mode 100644
index 00000000..7e329108
--- /dev/null
+++ b/doc/html/numpy/_static/jquery.js
@@ -0,0 +1,10365 @@
+/*!
+ * jQuery JavaScript Library v3.3.1-dfsg
+ * https://jquery.com/
+ *
+ * Includes Sizzle.js
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2019-04-19T06:52Z
+ */
+( function( global, factory ) {
+
+ "use strict";
+
+ 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 have a `window` with a `document`
+ // (such as Node.js), expose a 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 ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+
+
+var arr = [];
+
+var document = window.document;
+
+var getProto = Object.getPrototypeOf;
+
+var slice = arr.slice;
+
+var concat = arr.concat;
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var fnToString = hasOwn.toString;
+
+var ObjectFunctionString = fnToString.call( Object );
+
+var support = {};
+
+var isFunction = function isFunction( obj ) {
+
+ // Support: Chrome <=57, Firefox <=52
+ // In some browsers, typeof returns "function" for HTML elements
+ // (i.e., `typeof document.createElement( "object" ) === "function"`).
+ // We don't want to classify *any* DOM node as a function.
+ return typeof obj === "function" && typeof obj.nodeType !== "number";
+ };
+
+
+var isWindow = function isWindow( obj ) {
+ return obj != null && obj === obj.window;
+ };
+
+
+
+
+ var preservedScriptAttributes = {
+ type: true,
+ src: true,
+ noModule: true
+ };
+
+ function DOMEval( code, doc, node ) {
+ doc = doc || document;
+
+ var i,
+ script = doc.createElement( "script" );
+
+ script.text = code;
+ if ( node ) {
+ for ( i in preservedScriptAttributes ) {
+ if ( node[ i ] ) {
+ script[ i ] = node[ i ];
+ }
+ }
+ }
+ doc.head.appendChild( script ).parentNode.removeChild( script );
+ }
+
+
+function toType( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+
+ // Support: Android <=2.3 only (functionish RegExp)
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ toString.call( obj ) ] || "object" :
+ typeof obj;
+}
+/* global Symbol */
+// Defining this global in .eslintrc.json would create a danger of using the global
+// unguarded in another place, it seems safer to define global only for this module
+
+
+
+var
+ version = "3.3.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.0 only
+ // Make sure we trim BOM and NBSP
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
+
+jQuery.fn = jQuery.prototype = {
+
+ // The current version of jQuery being used
+ jquery: version,
+
+ constructor: jQuery,
+
+ // 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 all the elements in a clean array
+ if ( num == null ) {
+ return slice.call( this );
+ }
+
+ // Return just the one element from the set
+ return num < 0 ? this[ num + this.length ] : this[ num ];
+ },
+
+ // 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;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ each: function( callback ) {
+ return jQuery.each( this, callback );
+ },
+
+ 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();
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: arr.sort,
+ splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, 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" && !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 Object.prototype pollution
+ // Prevent never-ending loop
+ if ( name === "__proto__" || target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+ ( copyIsArray = Array.isArray( copy ) ) ) ) {
+
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && Array.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() {},
+
+ isPlainObject: function( obj ) {
+ var proto, Ctor;
+
+ // Detect obvious negatives
+ // Use toString instead of jQuery.type to catch host objects
+ if ( !obj || toString.call( obj ) !== "[object Object]" ) {
+ return false;
+ }
+
+ proto = getProto( obj );
+
+ // Objects with no prototype (e.g., `Object.create( null )`) are plain
+ if ( !proto ) {
+ return true;
+ }
+
+ // Objects with prototype are plain iff they were constructed by a global Object function
+ Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+ return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
+ },
+
+ isEmptyObject: function( obj ) {
+
+ /* eslint-disable no-unused-vars */
+ // See https://github.com/eslint/eslint/issues/6125
+ var name;
+
+ for ( name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ // Evaluates a script in a global context
+ globalEval: function( code ) {
+ DOMEval( code );
+ },
+
+ each: function( obj, callback ) {
+ var length, i = 0;
+
+ if ( isArrayLike( obj ) ) {
+ length = obj.length;
+ for ( ; i < length; i++ ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ }
+
+ return obj;
+ },
+
+ // Support: Android <=4.0 only
+ 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 ) {
+ return arr == null ? -1 : indexOf.call( arr, elem, i );
+ },
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ merge: function( first, second ) {
+ var len = +second.length,
+ j = 0,
+ i = first.length;
+
+ for ( ; j < len; j++ ) {
+ 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 length, value,
+ i = 0,
+ ret = [];
+
+ // Go through the array, translating each of the items to their new values
+ if ( isArrayLike( elems ) ) {
+ length = elems.length;
+ 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,
+
+ // jQuery.support is not used in Core but other projects attach their
+ // properties to it so it needs to exist.
+ support: support
+} );
+
+if ( typeof Symbol === "function" ) {
+ jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+}
+
+// Populate the class2type map
+jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+function( i, name ) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+} );
+
+function isArrayLike( obj ) {
+
+ // Support: real iOS 8.2 only (not reproducible in simulator)
+ // `in` check used to prevent JIT error (gh-2145)
+ // hasOwn isn't used here due to false negatives
+ // regarding Nodelist length in IE
+ var length = !!obj && "length" in obj && obj.length,
+ type = toType( obj );
+
+ if ( isFunction( obj ) || isWindow( obj ) ) {
+ return false;
+ }
+
+ return type === "array" || length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v2.3.3
+ * https://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-08-08
+ */
+(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" + 1 * 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;
+ },
+
+ // Instance methods
+ hasOwn = ({}).hasOwnProperty,
+ arr = [],
+ pop = arr.pop,
+ push_native = arr.push,
+ push = arr.push,
+ slice = arr.slice,
+ // Use a stripped-down indexOf as it's faster than native
+ // https://jsperf.com/thor-indexof-vs-for/5
+ indexOf = function( list, elem ) {
+ var i = 0,
+ len = list.length;
+ for ( ; i < len; i++ ) {
+ if ( list[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
+
+ // http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+
+ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
+
+ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+ // Operator (capture 2)
+ "*([*^$|!~]?=)" + whitespace +
+ // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+ "*\\]",
+
+ pseudos = ":(" + identifier + ")(?:\\((" +
+ // 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
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
+ 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( "^#(" + identifier + ")" ),
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
+ "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 = /[+~]/,
+
+ // 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 );
+ },
+
+ // CSS string/identifier serialization
+ // https://drafts.csswg.org/cssom/#common-serializing-idioms
+ rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+ fcssescape = function( ch, asCodePoint ) {
+ if ( asCodePoint ) {
+
+ // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+ if ( ch === "\0" ) {
+ return "\uFFFD";
+ }
+
+ // Control characters and (dependent upon position) numbers get escaped as code points
+ return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+ }
+
+ // Other potentially-special ASCII characters get backslash-escaped
+ return "\\" + ch;
+ },
+
+ // Used for iframes
+ // See setDocument()
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE
+ unloadHandler = function() {
+ setDocument();
+ },
+
+ disabledAncestor = addCombinator(
+ function( elem ) {
+ return elem.disabled === true && ("form" in elem || "label" in elem);
+ },
+ { dir: "parentNode", next: "legend" }
+ );
+
+// 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 m, i, elem, nid, match, groups, newSelector,
+ newContext = context && context.ownerDocument,
+
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
+
+ results = results || [];
+
+ // Return early from calls with invalid selector or context
+ if ( typeof selector !== "string" || !selector ||
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+ return results;
+ }
+
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
+ if ( !seed ) {
+
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+ setDocument( context );
+ }
+ context = context || document;
+
+ if ( documentIsHTML ) {
+
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+ // ID selector
+ if ( (m = match[1]) ) {
+
+ // Document context
+ if ( nodeType === 9 ) {
+ if ( (elem = context.getElementById( m )) ) {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+
+ // Element context
+ } else {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( newContext && (elem = newContext.getElementById( m )) &&
+ contains( context, elem ) &&
+ elem.id === m ) {
+
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Type selector
+ } else if ( match[2] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
+ return results;
+
+ // Class selector
+ } else if ( (m = match[3]) && support.getElementsByClassName &&
+ context.getElementsByClassName ) {
+
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
+ }
+ }
+
+ // Take advantage of querySelectorAll
+ if ( support.qsa &&
+ !compilerCache[ selector + " " ] &&
+ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+ if ( nodeType !== 1 ) {
+ newContext = context;
+ newSelector = selector;
+
+ // qSA looks outside Element context, which is not what we want
+ // Thanks to Andrew Dupont for this workaround technique
+ // Support: IE <=8
+ // Exclude object elements
+ } else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+ // Capture the context ID, setting it first if necessary
+ if ( (nid = context.getAttribute( "id" )) ) {
+ nid = nid.replace( rcssescape, fcssescape );
+ } else {
+ context.setAttribute( "id", (nid = expando) );
+ }
+
+ // Prefix every selector in the list
+ groups = tokenize( selector );
+ i = groups.length;
+ while ( i-- ) {
+ groups[i] = "#" + nid + " " + toSelector( groups[i] );
+ }
+ newSelector = groups.join( "," );
+
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+ context;
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ } finally {
+ if ( nid === expando ) {
+ 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 element and returns a boolean result
+ */
+function assert( fn ) {
+ var el = document.createElement("fieldset");
+
+ try {
+ return !!fn( el );
+ } catch (e) {
+ return false;
+ } finally {
+ // Remove from its parent by default
+ if ( el.parentNode ) {
+ el.parentNode.removeChild( el );
+ }
+ // release memory in IE
+ el = 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 = arr.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 &&
+ a.sourceIndex - b.sourceIndex;
+
+ // 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 :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+function createDisabledPseudo( disabled ) {
+
+ // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+ return function( elem ) {
+
+ // Only certain elements can match :enabled or :disabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+ if ( "form" in elem ) {
+
+ // Check for inherited disabledness on relevant non-disabled elements:
+ // * listed form-associated elements in a disabled fieldset
+ // https://html.spec.whatwg.org/multipage/forms.html#category-listed
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+ // * option elements in a disabled optgroup
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+ // All such elements have a "form" property.
+ if ( elem.parentNode && elem.disabled === false ) {
+
+ // Option elements defer to a parent optgroup if present
+ if ( "label" in elem ) {
+ if ( "label" in elem.parentNode ) {
+ return elem.parentNode.disabled === disabled;
+ } else {
+ return elem.disabled === disabled;
+ }
+ }
+
+ // Support: IE 6 - 11
+ // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+ return elem.isDisabled === disabled ||
+
+ // Where there is no isDisabled, check manually
+ /* jshint -W018 */
+ elem.isDisabled !== !disabled &&
+ disabledAncestor( elem ) === disabled;
+ }
+
+ return elem.disabled === disabled;
+
+ // Try to winnow out elements that can't be disabled before trusting the disabled property.
+ // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+ // even exist on them, let alone have a boolean value.
+ } else if ( "label" in elem ) {
+ return elem.disabled === disabled;
+ }
+
+ // Remaining elements are neither :enabled nor :disabled
+ return false;
+ };
+}
+
+/**
+ * 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 !== "undefined" && 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, subWindow,
+ doc = node ? node.ownerDocument || node : preferredDoc;
+
+ // Return early if doc is invalid or already selected
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+ return document;
+ }
+
+ // Update global variables
+ document = doc;
+ docElem = document.documentElement;
+ documentIsHTML = !isXML( document );
+
+ // Support: IE 9-11, Edge
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+ if ( preferredDoc !== document &&
+ (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
+
+ // Support: IE 11, Edge
+ if ( subWindow.addEventListener ) {
+ subWindow.addEventListener( "unload", unloadHandler, false );
+
+ // Support: IE 9 - 10 only
+ } else if ( subWindow.attachEvent ) {
+ subWindow.attachEvent( "onunload", unloadHandler );
+ }
+ }
+
+ /* Attributes
+ ---------------------------------------------------------------------- */
+
+ // Support: IE<8
+ // Verify that getAttribute really returns attributes and not properties
+ // (excepting IE8 booleans)
+ support.attributes = assert(function( el ) {
+ el.className = "i";
+ return !el.getAttribute("className");
+ });
+
+ /* getElement(s)By*
+ ---------------------------------------------------------------------- */
+
+ // Check if getElementsByTagName("*") returns only elements
+ support.getElementsByTagName = assert(function( el ) {
+ el.appendChild( document.createComment("") );
+ return !el.getElementsByTagName("*").length;
+ });
+
+ // Support: IE<9
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+ // Support: IE<10
+ // Check if getElementById returns elements by name
+ // The broken getElementById methods don't pick up programmatically-set names,
+ // so use a roundabout getElementsByName test
+ support.getById = assert(function( el ) {
+ docElem.appendChild( el ).id = expando;
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
+ });
+
+ // ID filter and find
+ if ( support.getById ) {
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ return elem.getAttribute("id") === attrId;
+ };
+ };
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var elem = context.getElementById( id );
+ return elem ? [ elem ] : [];
+ }
+ };
+ } else {
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== "undefined" &&
+ elem.getAttributeNode("id");
+ return node && node.value === attrId;
+ };
+ };
+
+ // Support: IE 6 - 7 only
+ // getElementById is not reliable as a find shortcut
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var node, i, elems,
+ elem = context.getElementById( id );
+
+ if ( elem ) {
+
+ // Verify the id attribute
+ node = elem.getAttributeNode("id");
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+
+ // Fall back on getElementsByName
+ elems = context.getElementsByName( id );
+ i = 0;
+ while ( (elem = elems[i++]) ) {
+ node = elem.getAttributeNode("id");
+ if ( node && node.value === id ) {
+ return [ elem ];
+ }
+ }
+ }
+
+ return [];
+ }
+ };
+ }
+
+ // Tag
+ Expr.find["TAG"] = support.getElementsByTagName ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( tag );
+
+ // DocumentFragment nodes don't have gEBTN
+ } else if ( support.qsa ) {
+ return context.querySelectorAll( tag );
+ }
+ } :
+
+ function( tag, context ) {
+ var elem,
+ tmp = [],
+ i = 0,
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+ 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 !== "undefined" && 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 https://bugs.jquery.com/ticket/13378
+ rbuggyQSA = [];
+
+ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( el ) {
+ // 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
+ // https://bugs.jquery.com/ticket/12359
+ docElem.appendChild( el ).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
+ // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+ if ( el.querySelectorAll("[msallowcapture^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+ }
+
+ // Support: IE8
+ // Boolean attributes and "value" are not treated correctly
+ if ( !el.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+ }
+
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+ rbuggyQSA.push("~=");
+ }
+
+ // 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 ( !el.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+
+ // Support: Safari 8+, iOS 8+
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
+ // In-page `selector#id sibling-combinator selector` fails
+ if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
+ rbuggyQSA.push(".#.+[+~]");
+ }
+ });
+
+ assert(function( el ) {
+ el.innerHTML = " " +
+ " ";
+
+ // Support: Windows 8 Native Apps
+ // The type and name attributes are restricted during .innerHTML assignment
+ var input = document.createElement("input");
+ input.setAttribute( "type", "hidden" );
+ el.appendChild( input ).setAttribute( "name", "D" );
+
+ // Support: IE8
+ // Enforce case-sensitivity of name attribute
+ if ( el.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 ( el.querySelectorAll(":enabled").length !== 2 ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Support: IE9-11+
+ // IE's :disabled selector does not pick up the children of disabled fieldsets
+ docElem.appendChild( el ).disabled = true;
+ if ( el.querySelectorAll(":disabled").length !== 2 ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+ el.querySelectorAll("*,:x");
+ rbuggyQSA.push(",.*:");
+ });
+ }
+
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+ docElem.webkitMatchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector) )) ) {
+
+ assert(function( el ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call( el, "*" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( el, "[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 self-exclusive
+ // 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 === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+ return -1;
+ }
+ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+ return 1;
+ }
+
+ // Maintain original order
+ return sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( 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 === document ? -1 :
+ b === document ? 1 :
+ aup ? -1 :
+ bup ? 1 :
+ sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( 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 document;
+};
+
+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 &&
+ !compilerCache[ expr + " " ] &&
+ ( !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.escape = function( sel ) {
+ return (sel + "").replace( rcssescape, fcssescape );
+};
+
+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 !== "undefined" && 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.replace( rwhitespace, " " ) + " " ).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, uniqueCache, outerCache, node, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType,
+ diff = false;
+
+ 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
+
+ // ...in a gzip-friendly way
+ node = parent;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex && 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 ) {
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
+
+ } else {
+ // Use previously-cached element index if available
+ if ( useCache ) {
+ // ...in a gzip-friendly way
+ node = elem;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex;
+ }
+
+ // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ if ( diff === false ) {
+ // 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 ) {
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ uniqueCache[ 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( 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 );
+ // Don't keep the element (issue #299)
+ input[0] = null;
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ text = text.replace( runescape, funescape );
+ 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": createDisabledPseudo( false ),
+ "disabled": createDisabledPseudo( 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,
+ skip = combinator.next,
+ key = skip || dir,
+ checkNonElements = base && key === "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 );
+ }
+ }
+ return false;
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var oldCache, uniqueCache, outerCache,
+ newCache = [ dirruns, doneName ];
+
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator 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 ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+
+ if ( skip && skip === elem.nodeName.toLowerCase() ) {
+ elem = elem[ dir ] || elem;
+ } else if ( (oldCache = uniqueCache[ key ]) &&
+ 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
+ uniqueCache[ key ] = newCache;
+
+ // A match means we're done; a fail means we have to keep checking
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ };
+}
+
+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( 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( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ // Avoid hanging onto element (issue #299)
+ checkContext = null;
+ return ret;
+ } ];
+
+ 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 || outermost;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ // 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;
+ if ( !context && elem.ownerDocument !== document ) {
+ setDocument( elem );
+ xml = !documentIsHTML;
+ }
+ while ( (matcher = elementMatchers[j++]) ) {
+ if ( matcher( elem, context || document, 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 );
+ }
+ }
+ }
+
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
+ matchedCount += i;
+
+ // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
+ 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 only one selector in the list and no seed
+ // (the latter of which guarantees us context)
+ if ( match.length === 1 ) {
+
+ // Reduce context if the leading compound selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ 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,
+ !context || 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-35+
+// 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( el ) {
+ // Should return 1, but returns 4 (following)
+ return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( el ) {
+ el.innerHTML = " ";
+ return el.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( el ) {
+ el.innerHTML = " ";
+ el.firstChild.setAttribute( "value", "" );
+ return el.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( el ) {
+ return el.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;
+
+// Deprecated
+jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+jQuery.escapeSelector = Sizzle.escape;
+
+
+
+
+var dir = function( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
+ }
+ matched.push( elem );
+ }
+ }
+ return matched;
+};
+
+
+var siblings = function( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
+ }
+ }
+
+ return matched;
+};
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+
+
+function nodeName( elem, name ) {
+
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+
+};
+var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
+
+
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+ if ( isFunction( qualifier ) ) {
+ return jQuery.grep( elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) !== not;
+ } );
+ }
+
+ // Single element
+ if ( qualifier.nodeType ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( elem === qualifier ) !== not;
+ } );
+ }
+
+ // Arraylike of elements (jQuery, arguments, Array)
+ if ( typeof qualifier !== "string" ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+ } );
+ }
+
+ // Filtered directly for both simple and complex selectors
+ return jQuery.filter( qualifier, elements, not );
+}
+
+jQuery.filter = function( expr, elems, not ) {
+ var elem = elems[ 0 ];
+
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ if ( elems.length === 1 && elem.nodeType === 1 ) {
+ return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+ }
+
+ return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ } ) );
+};
+
+jQuery.fn.extend( {
+ find: function( selector ) {
+ var i, ret,
+ len = this.length,
+ self = this;
+
+ 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;
+ }
+ }
+ } ) );
+ }
+
+ ret = this.pushStack( [] );
+
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, self[ i ], ret );
+ }
+
+ return len > 1 ? jQuery.uniqueSort( ret ) : 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,
+
+ // 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 <)
+ // Shortcut simple #id case for speed
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
+
+ init = jQuery.fn.init = function( selector, context, root ) {
+ var match, elem;
+
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Method init() accepts an alternate rootjQuery
+ // so migrate can support jQuery.sub (gh-2101)
+ root = root || rootjQuery;
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ if ( selector[ 0 ] === "<" &&
+ selector[ 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;
+
+ // Option to run 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 ( 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 ] );
+
+ if ( elem ) {
+
+ // Inject the element directly into the jQuery object
+ this[ 0 ] = elem;
+ this.length = 1;
+ }
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || root ).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[ 0 ] = selector;
+ this.length = 1;
+ return this;
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( isFunction( selector ) ) {
+ return root.ready !== undefined ?
+ root.ready( selector ) :
+
+ // Execute immediately if ready is not present
+ selector( jQuery );
+ }
+
+ 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.fn.extend( {
+ has: function( target ) {
+ var targets = jQuery( target, this ),
+ l = targets.length;
+
+ return this.filter( function() {
+ var i = 0;
+ for ( ; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[ i ] ) ) {
+ return true;
+ }
+ }
+ } );
+ },
+
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ targets = typeof selectors !== "string" && jQuery( selectors );
+
+ // Positional selectors never match, since there's no _selection_ context
+ if ( !rneedsContext.test( selectors ) ) {
+ for ( ; i < l; i++ ) {
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+ // Always skip document fragments
+ if ( cur.nodeType < 11 && ( targets ?
+ targets.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.uniqueSort( matched ) : matched );
+ },
+
+ // Determine the position of an element within the set
+ 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 indexOf.call( jQuery( elem ), this[ 0 ] );
+ }
+
+ // Locate the position of the desired element
+ return indexOf.call( this,
+
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[ 0 ] : elem
+ );
+ },
+
+ add: function( selector, context ) {
+ return this.pushStack(
+ jQuery.uniqueSort(
+ 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 ) {
+ while ( ( cur = cur[ dir ] ) && 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 dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return siblings( elem.firstChild );
+ },
+ contents: function( elem ) {
+ if ( nodeName( elem, "iframe" ) ) {
+ return elem.contentDocument;
+ }
+
+ // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+ // Treat the template element as a regular one in browsers that
+ // don't support it.
+ if ( nodeName( elem, "template" ) ) {
+ elem = elem.content || elem;
+ }
+
+ return jQuery.merge( [], elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var matched = jQuery.map( this, fn, until );
+
+ if ( name.slice( -5 ) !== "Until" ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ matched = jQuery.filter( selector, matched );
+ }
+
+ if ( this.length > 1 ) {
+
+ // Remove duplicates
+ if ( !guaranteedUnique[ name ] ) {
+ jQuery.uniqueSort( matched );
+ }
+
+ // Reverse order for parents* and prev-derivatives
+ if ( rparentsprev.test( name ) ) {
+ matched.reverse();
+ }
+ }
+
+ return this.pushStack( matched );
+ };
+} );
+var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
+
+
+
+// Convert String-formatted options into Object-formatted ones
+function createOptions( options ) {
+ var object = {};
+ jQuery.each( options.match( rnothtmlwhite ) || [], 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" ?
+ 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,
+
+ // Flag to prevent firing
+ locked,
+
+ // Actual callback list
+ list = [],
+
+ // Queue of execution data for repeatable lists
+ queue = [],
+
+ // Index of currently firing callback (modified by add/remove as needed)
+ firingIndex = -1,
+
+ // Fire callbacks
+ fire = function() {
+
+ // Enforce single-firing
+ locked = locked || options.once;
+
+ // Execute callbacks for all pending executions,
+ // respecting firingIndex overrides and runtime changes
+ fired = firing = true;
+ for ( ; queue.length; firingIndex = -1 ) {
+ memory = queue.shift();
+ while ( ++firingIndex < list.length ) {
+
+ // Run callback and check for early termination
+ if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
+ options.stopOnFalse ) {
+
+ // Jump to end and forget the data so .add doesn't re-fire
+ firingIndex = list.length;
+ memory = false;
+ }
+ }
+ }
+
+ // Forget the data if we're done with it
+ if ( !options.memory ) {
+ memory = false;
+ }
+
+ firing = false;
+
+ // Clean up if we're done firing for good
+ if ( locked ) {
+
+ // Keep an empty list if we have data for future add calls
+ if ( memory ) {
+ list = [];
+
+ // Otherwise, this object is spent
+ } else {
+ list = "";
+ }
+ }
+ },
+
+ // Actual Callbacks object
+ self = {
+
+ // Add a callback or a collection of callbacks to the list
+ add: function() {
+ if ( list ) {
+
+ // If we have memory from a past run, we should fire after adding
+ if ( memory && !firing ) {
+ firingIndex = list.length - 1;
+ queue.push( memory );
+ }
+
+ ( function add( args ) {
+ jQuery.each( args, function( _, arg ) {
+ if ( isFunction( arg ) ) {
+ if ( !options.unique || !self.has( arg ) ) {
+ list.push( arg );
+ }
+ } else if ( arg && arg.length && toType( arg ) !== "string" ) {
+
+ // Inspect recursively
+ add( arg );
+ }
+ } );
+ } )( arguments );
+
+ if ( memory && !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Remove a callback from the list
+ remove: function() {
+ jQuery.each( arguments, function( _, arg ) {
+ var index;
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+ list.splice( index, 1 );
+
+ // Handle firing indexes
+ 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.length > 0;
+ },
+
+ // Remove all callbacks from the list
+ empty: function() {
+ if ( list ) {
+ list = [];
+ }
+ return this;
+ },
+
+ // Disable .fire and .add
+ // Abort any current/pending executions
+ // Clear all callbacks and values
+ disable: function() {
+ locked = queue = [];
+ list = memory = "";
+ return this;
+ },
+ disabled: function() {
+ return !list;
+ },
+
+ // Disable .fire
+ // Also disable .add unless we have memory (since it would have no effect)
+ // Abort any pending executions
+ lock: function() {
+ locked = queue = [];
+ if ( !memory && !firing ) {
+ list = memory = "";
+ }
+ return this;
+ },
+ locked: function() {
+ return !!locked;
+ },
+
+ // Call all callbacks with the given context and arguments
+ fireWith: function( context, args ) {
+ if ( !locked ) {
+ args = args || [];
+ args = [ context, args.slice ? args.slice() : args ];
+ queue.push( args );
+ if ( !firing ) {
+ fire();
+ }
+ }
+ 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;
+};
+
+
+function Identity( v ) {
+ return v;
+}
+function Thrower( ex ) {
+ throw ex;
+}
+
+function adoptValue( value, resolve, reject, noValue ) {
+ var method;
+
+ try {
+
+ // Check for promise aspect first to privilege synchronous behavior
+ if ( value && isFunction( ( method = value.promise ) ) ) {
+ method.call( value ).done( resolve ).fail( reject );
+
+ // Other thenables
+ } else if ( value && isFunction( ( method = value.then ) ) ) {
+ method.call( value, resolve, reject );
+
+ // Other non-thenables
+ } else {
+
+ // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
+ // * false: [ value ].slice( 0 ) => resolve( value )
+ // * true: [ value ].slice( 1 ) => resolve()
+ resolve.apply( undefined, [ value ].slice( noValue ) );
+ }
+
+ // For Promises/A+, convert exceptions into rejections
+ // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+ // Deferred#then to conditionally suppress rejection.
+ } catch ( value ) {
+
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ reject.apply( undefined, [ value ] );
+ }
+}
+
+jQuery.extend( {
+
+ Deferred: function( func ) {
+ var tuples = [
+
+ // action, add listener, callbacks,
+ // ... .then handlers, argument index, [final state]
+ [ "notify", "progress", jQuery.Callbacks( "memory" ),
+ jQuery.Callbacks( "memory" ), 2 ],
+ [ "resolve", "done", jQuery.Callbacks( "once memory" ),
+ jQuery.Callbacks( "once memory" ), 0, "resolved" ],
+ [ "reject", "fail", jQuery.Callbacks( "once memory" ),
+ jQuery.Callbacks( "once memory" ), 1, "rejected" ]
+ ],
+ state = "pending",
+ promise = {
+ state: function() {
+ return state;
+ },
+ always: function() {
+ deferred.done( arguments ).fail( arguments );
+ return this;
+ },
+ "catch": function( fn ) {
+ return promise.then( null, fn );
+ },
+
+ // Keep pipe for back-compat
+ pipe: function( /* fnDone, fnFail, fnProgress */ ) {
+ var fns = arguments;
+
+ return jQuery.Deferred( function( newDefer ) {
+ jQuery.each( tuples, function( i, tuple ) {
+
+ // Map tuples (progress, done, fail) to arguments (done, fail, progress)
+ var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
+
+ // deferred.progress(function() { bind to newDefer or newDefer.notify })
+ // deferred.done(function() { bind to newDefer or newDefer.resolve })
+ // deferred.fail(function() { bind to newDefer or newDefer.reject })
+ deferred[ tuple[ 1 ] ]( function() {
+ var returned = fn && fn.apply( this, arguments );
+ if ( returned && isFunction( returned.promise ) ) {
+ returned.promise()
+ .progress( newDefer.notify )
+ .done( newDefer.resolve )
+ .fail( newDefer.reject );
+ } else {
+ newDefer[ tuple[ 0 ] + "With" ](
+ this,
+ fn ? [ returned ] : arguments
+ );
+ }
+ } );
+ } );
+ fns = null;
+ } ).promise();
+ },
+ then: function( onFulfilled, onRejected, onProgress ) {
+ var maxDepth = 0;
+ function resolve( depth, deferred, handler, special ) {
+ return function() {
+ var that = this,
+ args = arguments,
+ mightThrow = function() {
+ var returned, then;
+
+ // Support: Promises/A+ section 2.3.3.3.3
+ // https://promisesaplus.com/#point-59
+ // Ignore double-resolution attempts
+ if ( depth < maxDepth ) {
+ return;
+ }
+
+ returned = handler.apply( that, args );
+
+ // Support: Promises/A+ section 2.3.1
+ // https://promisesaplus.com/#point-48
+ if ( returned === deferred.promise() ) {
+ throw new TypeError( "Thenable self-resolution" );
+ }
+
+ // Support: Promises/A+ sections 2.3.3.1, 3.5
+ // https://promisesaplus.com/#point-54
+ // https://promisesaplus.com/#point-75
+ // Retrieve `then` only once
+ then = returned &&
+
+ // Support: Promises/A+ section 2.3.4
+ // https://promisesaplus.com/#point-64
+ // Only check objects and functions for thenability
+ ( typeof returned === "object" ||
+ typeof returned === "function" ) &&
+ returned.then;
+
+ // Handle a returned thenable
+ if ( isFunction( then ) ) {
+
+ // Special processors (notify) just wait for resolution
+ if ( special ) {
+ then.call(
+ returned,
+ resolve( maxDepth, deferred, Identity, special ),
+ resolve( maxDepth, deferred, Thrower, special )
+ );
+
+ // Normal processors (resolve) also hook into progress
+ } else {
+
+ // ...and disregard older resolution values
+ maxDepth++;
+
+ then.call(
+ returned,
+ resolve( maxDepth, deferred, Identity, special ),
+ resolve( maxDepth, deferred, Thrower, special ),
+ resolve( maxDepth, deferred, Identity,
+ deferred.notifyWith )
+ );
+ }
+
+ // Handle all other returned values
+ } else {
+
+ // Only substitute handlers pass on context
+ // and multiple values (non-spec behavior)
+ if ( handler !== Identity ) {
+ that = undefined;
+ args = [ returned ];
+ }
+
+ // Process the value(s)
+ // Default process is resolve
+ ( special || deferred.resolveWith )( that, args );
+ }
+ },
+
+ // Only normal processors (resolve) catch and reject exceptions
+ process = special ?
+ mightThrow :
+ function() {
+ try {
+ mightThrow();
+ } catch ( e ) {
+
+ if ( jQuery.Deferred.exceptionHook ) {
+ jQuery.Deferred.exceptionHook( e,
+ process.stackTrace );
+ }
+
+ // Support: Promises/A+ section 2.3.3.3.4.1
+ // https://promisesaplus.com/#point-61
+ // Ignore post-resolution exceptions
+ if ( depth + 1 >= maxDepth ) {
+
+ // Only substitute handlers pass on context
+ // and multiple values (non-spec behavior)
+ if ( handler !== Thrower ) {
+ that = undefined;
+ args = [ e ];
+ }
+
+ deferred.rejectWith( that, args );
+ }
+ }
+ };
+
+ // Support: Promises/A+ section 2.3.3.3.1
+ // https://promisesaplus.com/#point-57
+ // Re-resolve promises immediately to dodge false rejection from
+ // subsequent errors
+ if ( depth ) {
+ process();
+ } else {
+
+ // Call an optional hook to record the stack, in case of exception
+ // since it's otherwise lost when execution goes async
+ if ( jQuery.Deferred.getStackHook ) {
+ process.stackTrace = jQuery.Deferred.getStackHook();
+ }
+ window.setTimeout( process );
+ }
+ };
+ }
+
+ return jQuery.Deferred( function( newDefer ) {
+
+ // progress_handlers.add( ... )
+ tuples[ 0 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ isFunction( onProgress ) ?
+ onProgress :
+ Identity,
+ newDefer.notifyWith
+ )
+ );
+
+ // fulfilled_handlers.add( ... )
+ tuples[ 1 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ isFunction( onFulfilled ) ?
+ onFulfilled :
+ Identity
+ )
+ );
+
+ // rejected_handlers.add( ... )
+ tuples[ 2 ][ 3 ].add(
+ resolve(
+ 0,
+ newDefer,
+ isFunction( onRejected ) ?
+ onRejected :
+ Thrower
+ )
+ );
+ } ).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 = {};
+
+ // Add list-specific methods
+ jQuery.each( tuples, function( i, tuple ) {
+ var list = tuple[ 2 ],
+ stateString = tuple[ 5 ];
+
+ // promise.progress = list.add
+ // promise.done = list.add
+ // promise.fail = list.add
+ promise[ tuple[ 1 ] ] = list.add;
+
+ // Handle state
+ if ( stateString ) {
+ list.add(
+ function() {
+
+ // state = "resolved" (i.e., fulfilled)
+ // state = "rejected"
+ state = stateString;
+ },
+
+ // rejected_callbacks.disable
+ // fulfilled_callbacks.disable
+ tuples[ 3 - i ][ 2 ].disable,
+
+ // rejected_handlers.disable
+ // fulfilled_handlers.disable
+ tuples[ 3 - i ][ 3 ].disable,
+
+ // progress_callbacks.lock
+ tuples[ 0 ][ 2 ].lock,
+
+ // progress_handlers.lock
+ tuples[ 0 ][ 3 ].lock
+ );
+ }
+
+ // progress_handlers.fire
+ // fulfilled_handlers.fire
+ // rejected_handlers.fire
+ list.add( tuple[ 3 ].fire );
+
+ // deferred.notify = function() { deferred.notifyWith(...) }
+ // deferred.resolve = function() { deferred.resolveWith(...) }
+ // deferred.reject = function() { deferred.rejectWith(...) }
+ deferred[ tuple[ 0 ] ] = function() {
+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
+ return this;
+ };
+
+ // deferred.notifyWith = list.fireWith
+ // deferred.resolveWith = list.fireWith
+ // deferred.rejectWith = list.fireWith
+ 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( singleValue ) {
+ var
+
+ // count of uncompleted subordinates
+ remaining = arguments.length,
+
+ // count of unprocessed arguments
+ i = remaining,
+
+ // subordinate fulfillment data
+ resolveContexts = Array( i ),
+ resolveValues = slice.call( arguments ),
+
+ // the master Deferred
+ master = jQuery.Deferred(),
+
+ // subordinate callback factory
+ updateFunc = function( i ) {
+ return function( value ) {
+ resolveContexts[ i ] = this;
+ resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+ if ( !( --remaining ) ) {
+ master.resolveWith( resolveContexts, resolveValues );
+ }
+ };
+ };
+
+ // Single- and empty arguments are adopted like Promise.resolve
+ if ( remaining <= 1 ) {
+ adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
+ !remaining );
+
+ // Use .then() to unwrap secondary thenables (cf. gh-3000)
+ if ( master.state() === "pending" ||
+ isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+
+ return master.then();
+ }
+ }
+
+ // Multiple arguments are aggregated like Promise.all array elements
+ while ( i-- ) {
+ adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
+ }
+
+ return master.promise();
+ }
+} );
+
+
+// These usually indicate a programmer mistake during development,
+// warn about them ASAP rather than swallowing them by default.
+var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
+
+jQuery.Deferred.exceptionHook = function( error, stack ) {
+
+ // Support: IE 8 - 9 only
+ // Console exists when dev tools are open, which can happen at any time
+ if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
+ window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
+ }
+};
+
+
+
+
+jQuery.readyException = function( error ) {
+ window.setTimeout( function() {
+ throw error;
+ } );
+};
+
+
+
+
+// The deferred used on DOM ready
+var readyList = jQuery.Deferred();
+
+jQuery.fn.ready = function( fn ) {
+
+ readyList
+ .then( fn )
+
+ // Wrap jQuery.readyException in a function so that the lookup
+ // happens at the time of error handling instead of callback
+ // registration.
+ .catch( function( error ) {
+ jQuery.readyException( error );
+ } );
+
+ 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,
+
+ // 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;
+ }
+
+ // 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 ] );
+ }
+} );
+
+jQuery.ready.then = readyList.then;
+
+// The ready event handler and self cleanup method
+function completed() {
+ document.removeEventListener( "DOMContentLoaded", completed );
+ window.removeEventListener( "load", completed );
+ jQuery.ready();
+}
+
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE <=9 - 10 only
+// Older IE sometimes signals "interactive" too soon
+if ( document.readyState === "complete" ||
+ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout( jQuery.ready );
+
+} else {
+
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed );
+}
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ len = elems.length,
+ bulk = key == null;
+
+ // Sets many values
+ if ( toType( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ access( elems, fn, i, key[ i ], true, emptyGet, raw );
+ }
+
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
+
+ if ( !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 < len; i++ ) {
+ fn(
+ elems[ i ], key, raw ?
+ value :
+ value.call( elems[ i ], i, fn( elems[ i ], key ) )
+ );
+ }
+ }
+ }
+
+ if ( chainable ) {
+ return elems;
+ }
+
+ // Gets
+ if ( bulk ) {
+ return fn.call( elems );
+ }
+
+ return len ? fn( elems[ 0 ], key ) : emptyGet;
+};
+
+
+// Matches dashed string for camelizing
+var rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([a-z])/g;
+
+// Used by camelCase as callback to replace()
+function fcamelCase( all, letter ) {
+ return letter.toUpperCase();
+}
+
+// Convert dashed to camelCase; used by the css and data modules
+// Support: IE <=9 - 11, Edge 12 - 15
+// Microsoft forgot to hump their vendor prefix (#9572)
+function camelCase( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+}
+var acceptData = function( owner ) {
+
+ // Accepts only:
+ // - Node
+ // - Node.ELEMENT_NODE
+ // - Node.DOCUMENT_NODE
+ // - Object
+ // - Any
+ return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+
+
+function Data() {
+ this.expando = jQuery.expando + Data.uid++;
+}
+
+Data.uid = 1;
+
+Data.prototype = {
+
+ cache: function( owner ) {
+
+ // Check if the owner object already has a cache
+ var value = owner[ this.expando ];
+
+ // If not, create one
+ if ( !value ) {
+ value = {};
+
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return an empty object.
+ if ( acceptData( owner ) ) {
+
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = value;
+
+ // Otherwise secure it in a non-enumerable property
+ // configurable must be true to allow the property to be
+ // deleted when data is removed
+ } else {
+ Object.defineProperty( owner, this.expando, {
+ value: value,
+ configurable: true
+ } );
+ }
+ }
+ }
+
+ return value;
+ },
+ set: function( owner, data, value ) {
+ var prop,
+ cache = this.cache( owner );
+
+ // Handle: [ owner, key, value ] args
+ // Always use camelCase key (gh-2257)
+ if ( typeof data === "string" ) {
+ cache[ camelCase( data ) ] = value;
+
+ // Handle: [ owner, { properties } ] args
+ } else {
+
+ // Copy the properties one-by-one to the cache object
+ for ( prop in data ) {
+ cache[ camelCase( prop ) ] = data[ prop ];
+ }
+ }
+ return cache;
+ },
+ get: function( owner, key ) {
+ return key === undefined ?
+ this.cache( owner ) :
+
+ // Always use camelCase key (gh-2257)
+ owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
+ },
+ access: function( owner, key, value ) {
+
+ // In cases where either:
+ //
+ // 1. No key was specified
+ // 2. A string key was specified, but no value provided
+ //
+ // Take the "read" path and allow the get method to determine
+ // which value to return, respectively either:
+ //
+ // 1. The entire cache object
+ // 2. The data stored at the key
+ //
+ if ( key === undefined ||
+ ( ( key && typeof key === "string" ) && value === undefined ) ) {
+
+ return this.get( owner, key );
+ }
+
+ // When the key is not a string, or both a key and value
+ // are specified, set or extend (existing objects) with either:
+ //
+ // 1. An object of properties
+ // 2. A key and value
+ //
+ this.set( owner, key, value );
+
+ // Since the "set" path can have two possible entry points
+ // return the expected data based on which path was taken[*]
+ return value !== undefined ? value : key;
+ },
+ remove: function( owner, key ) {
+ var i,
+ cache = owner[ this.expando ];
+
+ if ( cache === undefined ) {
+ return;
+ }
+
+ if ( key !== undefined ) {
+
+ // Support array or space separated string of keys
+ if ( Array.isArray( key ) ) {
+
+ // If key is an array of keys...
+ // We always set camelCase keys, so remove that.
+ key = key.map( camelCase );
+ } else {
+ key = camelCase( key );
+
+ // If a key with the spaces exists, use it.
+ // Otherwise, create an array by matching non-whitespace
+ key = key in cache ?
+ [ key ] :
+ ( key.match( rnothtmlwhite ) || [] );
+ }
+
+ i = key.length;
+
+ while ( i-- ) {
+ delete cache[ key[ i ] ];
+ }
+ }
+
+ // Remove the expando if there's no more data
+ if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+ // Support: Chrome <=35 - 45
+ // Webkit & Blink performance suffers when deleting properties
+ // from DOM nodes, so set to undefined instead
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = undefined;
+ } else {
+ delete owner[ this.expando ];
+ }
+ }
+ },
+ hasData: function( owner ) {
+ var cache = owner[ this.expando ];
+ return cache !== undefined && !jQuery.isEmptyObject( cache );
+ }
+};
+var dataPriv = new Data();
+
+var dataUser = new Data();
+
+
+
+// Implementation Summary
+//
+// 1. Enforce API surface and semantic compatibility with 1.9.x branch
+// 2. Improve the module's maintainability by reducing the storage
+// paths to a single mechanism.
+// 3. Use the same single mechanism to support "private" and "user" data.
+// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+// 5. Avoid exposing implementation details on user objects (eg. expando properties)
+// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+ rmultiDash = /[A-Z]/g;
+
+function getData( data ) {
+ if ( data === "true" ) {
+ return true;
+ }
+
+ if ( data === "false" ) {
+ return false;
+ }
+
+ if ( data === "null" ) {
+ return null;
+ }
+
+ // Only convert to a number if it doesn't change the string
+ if ( data === +data + "" ) {
+ return +data;
+ }
+
+ if ( rbrace.test( data ) ) {
+ return JSON.parse( data );
+ }
+
+ return data;
+}
+
+function dataAttr( elem, key, data ) {
+ var name;
+
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = getData( data );
+ } catch ( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ dataUser.set( elem, key, data );
+ } else {
+ data = undefined;
+ }
+ }
+ return data;
+}
+
+jQuery.extend( {
+ hasData: function( elem ) {
+ return dataUser.hasData( elem ) || dataPriv.hasData( elem );
+ },
+
+ data: function( elem, name, data ) {
+ return dataUser.access( elem, name, data );
+ },
+
+ removeData: function( elem, name ) {
+ dataUser.remove( elem, name );
+ },
+
+ // TODO: Now that all calls to _data and _removeData have been replaced
+ // with direct calls to dataPriv methods, these can be deprecated.
+ _data: function( elem, name, data ) {
+ return dataPriv.access( elem, name, data );
+ },
+
+ _removeData: function( elem, name ) {
+ dataPriv.remove( elem, name );
+ }
+} );
+
+jQuery.fn.extend( {
+ data: function( key, value ) {
+ var i, name, data,
+ elem = this[ 0 ],
+ attrs = elem && elem.attributes;
+
+ // Gets all values
+ if ( key === undefined ) {
+ if ( this.length ) {
+ data = dataUser.get( elem );
+
+ if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+ i = attrs.length;
+ while ( i-- ) {
+
+ // Support: IE 11 only
+ // The attrs elements can be null (#14894)
+ if ( attrs[ i ] ) {
+ name = attrs[ i ].name;
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = camelCase( name.slice( 5 ) );
+ dataAttr( elem, name, data[ name ] );
+ }
+ }
+ }
+ dataPriv.set( elem, "hasDataAttrs", true );
+ }
+ }
+
+ return data;
+ }
+
+ // Sets multiple values
+ if ( typeof key === "object" ) {
+ return this.each( function() {
+ dataUser.set( this, key );
+ } );
+ }
+
+ return access( this, function( value ) {
+ var data;
+
+ // The calling jQuery object (element matches) is not empty
+ // (and therefore has an element appears at this[ 0 ]) and the
+ // `value` parameter was not undefined. An empty jQuery object
+ // will result in `undefined` for elem = this[ 0 ] which will
+ // throw an exception if an attempt to read a data cache is made.
+ if ( elem && value === undefined ) {
+
+ // Attempt to get data from the cache
+ // The key will always be camelCased in Data
+ data = dataUser.get( elem, key );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // Attempt to "discover" the data in
+ // HTML5 custom data-* attrs
+ data = dataAttr( elem, key );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // We tried really hard, but the data doesn't exist.
+ return;
+ }
+
+ // Set the data...
+ this.each( function() {
+
+ // We always store the camelCased key
+ dataUser.set( this, key, value );
+ } );
+ }, null, value, arguments.length > 1, null, true );
+ },
+
+ removeData: function( key ) {
+ return this.each( function() {
+ dataUser.remove( this, key );
+ } );
+ }
+} );
+
+
+jQuery.extend( {
+ queue: function( elem, type, data ) {
+ var queue;
+
+ if ( elem ) {
+ type = ( type || "fx" ) + "queue";
+ queue = dataPriv.get( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !queue || Array.isArray( data ) ) {
+ queue = dataPriv.access( 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 public - generate a queueHooks object, or return the current one
+ _queueHooks: function( elem, type ) {
+ var key = type + "queueHooks";
+ return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
+ empty: jQuery.Callbacks( "once memory" ).add( function() {
+ dataPriv.remove( elem, [ type + "queue", 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 = dataPriv.get( 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 rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHiddenWithinTree = function( elem, el ) {
+
+ // isHiddenWithinTree might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+
+ // Inline style trumps all
+ return elem.style.display === "none" ||
+ elem.style.display === "" &&
+
+ // Otherwise, check computed style
+ // Support: Firefox <=43 - 45
+ // Disconnected elements can have computed display: none, so first confirm that elem is
+ // in the document.
+ jQuery.contains( elem.ownerDocument, elem ) &&
+
+ jQuery.css( elem, "display" ) === "none";
+ };
+
+var swap = function( elem, options, callback, args ) {
+ var ret, name,
+ old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ ret = callback.apply( elem, args || [] );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+
+ return ret;
+};
+
+
+
+
+function adjustCSS( elem, prop, valueParts, tween ) {
+ var adjusted, scale,
+ maxIterations = 20,
+ currentValue = tween ?
+ function() {
+ return tween.cur();
+ } :
+ function() {
+ return jQuery.css( elem, prop, "" );
+ },
+ initial = currentValue(),
+ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+ // Starting value computation is required for potential unit mismatches
+ initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+ rcssNum.exec( jQuery.css( elem, prop ) );
+
+ if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+ // Support: Firefox <=54
+ // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
+ initial = initial / 2;
+
+ // Trust units reported by jQuery.css
+ unit = unit || initialInUnit[ 3 ];
+
+ // Iteratively approximate from a nonzero starting point
+ initialInUnit = +initial || 1;
+
+ while ( maxIterations-- ) {
+
+ // Evaluate and update our best guess (doubling guesses that zero out).
+ // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
+ jQuery.style( elem, prop, initialInUnit + unit );
+ if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
+ maxIterations = 0;
+ }
+ initialInUnit = initialInUnit / scale;
+
+ }
+
+ initialInUnit = initialInUnit * 2;
+ jQuery.style( elem, prop, initialInUnit + unit );
+
+ // Make sure we update the tween properties later on
+ valueParts = valueParts || [];
+ }
+
+ if ( valueParts ) {
+ initialInUnit = +initialInUnit || +initial || 0;
+
+ // Apply relative offset (+=/-=) if specified
+ adjusted = valueParts[ 1 ] ?
+ initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+ +valueParts[ 2 ];
+ if ( tween ) {
+ tween.unit = unit;
+ tween.start = initialInUnit;
+ tween.end = adjusted;
+ }
+ }
+ return adjusted;
+}
+
+
+var defaultDisplayMap = {};
+
+function getDefaultDisplay( elem ) {
+ var temp,
+ doc = elem.ownerDocument,
+ nodeName = elem.nodeName,
+ display = defaultDisplayMap[ nodeName ];
+
+ if ( display ) {
+ return display;
+ }
+
+ temp = doc.body.appendChild( doc.createElement( nodeName ) );
+ display = jQuery.css( temp, "display" );
+
+ temp.parentNode.removeChild( temp );
+
+ if ( display === "none" ) {
+ display = "block";
+ }
+ defaultDisplayMap[ nodeName ] = display;
+
+ return display;
+}
+
+function showHide( elements, show ) {
+ var display, elem,
+ values = [],
+ index = 0,
+ length = elements.length;
+
+ // Determine new display value for elements that need to change
+ for ( ; index < length; index++ ) {
+ elem = elements[ index ];
+ if ( !elem.style ) {
+ continue;
+ }
+
+ display = elem.style.display;
+ if ( show ) {
+
+ // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
+ // check is required in this first loop unless we have a nonempty display value (either
+ // inline or about-to-be-restored)
+ if ( display === "none" ) {
+ values[ index ] = dataPriv.get( elem, "display" ) || null;
+ if ( !values[ index ] ) {
+ elem.style.display = "";
+ }
+ }
+ if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
+ values[ index ] = getDefaultDisplay( elem );
+ }
+ } else {
+ if ( display !== "none" ) {
+ values[ index ] = "none";
+
+ // Remember what we're overwriting
+ dataPriv.set( elem, "display", display );
+ }
+ }
+ }
+
+ // Set the display of the elements in a second loop to avoid constant reflow
+ for ( index = 0; index < length; index++ ) {
+ if ( values[ index ] != null ) {
+ elements[ index ].style.display = values[ index ];
+ }
+ }
+
+ return elements;
+}
+
+jQuery.fn.extend( {
+ show: function() {
+ return showHide( this, true );
+ },
+ hide: function() {
+ return showHide( this );
+ },
+ toggle: function( state ) {
+ if ( typeof state === "boolean" ) {
+ return state ? this.show() : this.hide();
+ }
+
+ return this.each( function() {
+ if ( isHiddenWithinTree( this ) ) {
+ jQuery( this ).show();
+ } else {
+ jQuery( this ).hide();
+ }
+ } );
+ }
+} );
+var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
+
+var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
+
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+
+ // Support: IE <=9 only
+ option: [ 1, "", " " ],
+
+ // XHTML parsers do not magically insert elements in the
+ // same way that tag soup parsers do. So we cannot shorten
+ // this by omitting or other required elements.
+ thead: [ 1, "" ],
+ col: [ 2, "" ],
+ tr: [ 2, "" ],
+ td: [ 3, "" ],
+
+ _default: [ 0, "", "" ]
+};
+
+// Support: IE <=9 only
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function getAll( context, tag ) {
+
+ // Support: IE <=9 - 11 only
+ // Use typeof to avoid zero-argument method invocation on host objects (#15151)
+ var ret;
+
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ ret = context.getElementsByTagName( tag || "*" );
+
+ } else if ( typeof context.querySelectorAll !== "undefined" ) {
+ ret = context.querySelectorAll( tag || "*" );
+
+ } else {
+ ret = [];
+ }
+
+ if ( tag === undefined || tag && nodeName( context, tag ) ) {
+ return jQuery.merge( [ context ], ret );
+ }
+
+ return ret;
+}
+
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ dataPriv.set(
+ elems[ i ],
+ "globalEval",
+ !refElements || dataPriv.get( refElements[ i ], "globalEval" )
+ );
+ }
+}
+
+
+var rhtml = /<|?\w+;/;
+
+function buildFragment( elems, context, scripts, selection, ignored ) {
+ var elem, tmp, tag, wrap, contains, j,
+ fragment = context.createDocumentFragment(),
+ nodes = [],
+ i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ elem = elems[ i ];
+
+ if ( elem || elem === 0 ) {
+
+ // Add nodes directly
+ if ( toType( elem ) === "object" ) {
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ 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 || fragment.appendChild( context.createElement( "div" ) );
+
+ // Deserialize a standard representation
+ tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+ wrap = wrapMap[ tag ] || wrapMap._default;
+ tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+ // Descend through wrappers to the right content
+ j = wrap[ 0 ];
+ while ( j-- ) {
+ tmp = tmp.lastChild;
+ }
+
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Remember the top-level container
+ tmp = fragment.firstChild;
+
+ // Ensure the created nodes are orphaned (#12392)
+ tmp.textContent = "";
+ }
+ }
+ }
+
+ // Remove wrapper from fragment
+ fragment.textContent = "";
+
+ i = 0;
+ while ( ( elem = nodes[ i++ ] ) ) {
+
+ // Skip elements already in the context collection (trac-4087)
+ if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+ if ( ignored ) {
+ ignored.push( elem );
+ }
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+
+ // Append to fragment
+ tmp = getAll( fragment.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 );
+ }
+ }
+ }
+ }
+
+ return fragment;
+}
+
+
+( function() {
+ var fragment = document.createDocumentFragment(),
+ div = fragment.appendChild( document.createElement( "div" ) ),
+ input = document.createElement( "input" );
+
+ // Support: Android 4.0 - 4.3 only
+ // Check state lost if the name is set (#11217)
+ // Support: Windows Web Apps (WWA)
+ // `name` and `type` must use .setAttribute for WWA (#14901)
+ input.setAttribute( "type", "radio" );
+ input.setAttribute( "checked", "checked" );
+ input.setAttribute( "name", "t" );
+
+ div.appendChild( input );
+
+ // Support: Android <=4.1 only
+ // Older WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Support: IE <=11 only
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+ div.innerHTML = "";
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+} )();
+var documentElement = document.documentElement;
+
+
+
+var
+ rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+function returnTrue() {
+ return true;
+}
+
+function returnFalse() {
+ return false;
+}
+
+// Support: IE <=9 only
+// See #13393 for more info
+function safeActiveElement() {
+ try {
+ return document.activeElement;
+ } catch ( err ) { }
+}
+
+function on( elem, types, selector, data, fn, one ) {
+ var origFn, type;
+
+ // 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 ) {
+ on( elem, type, selector, data, types[ type ], one );
+ }
+ return elem;
+ }
+
+ 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 elem;
+ }
+
+ 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 elem.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ } );
+}
+
+/*
+ * 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 handleObjIn, eventHandle, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.get( 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;
+ }
+
+ // Ensure that invalid selectors throw exceptions at attach time
+ // Evaluate against documentElement in case elem is a non-element node (e.g., document)
+ if ( selector ) {
+ jQuery.find.matchesSelector( documentElement, 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 !== "undefined" && jQuery.event.triggered !== e.type ?
+ jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+ };
+ }
+
+ // Handle multiple events separated by a space
+ types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+ 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 if the special events handler returns false
+ if ( !special.setup ||
+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
+ if ( elem.addEventListener ) {
+ elem.addEventListener( 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;
+ }
+
+ },
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, selector, mappedTypes ) {
+
+ var j, origCount, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+
+ if ( !elemData || !( events = elemData.events ) ) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+ 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 data and the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ dataPriv.remove( elem, "handle events" );
+ }
+ },
+
+ dispatch: function( nativeEvent ) {
+
+ // Make a writable jQuery.Event from the native event object
+ var event = jQuery.event.fix( nativeEvent );
+
+ var i, j, ret, matched, handleObj, handlerQueue,
+ args = new Array( arguments.length ),
+ handlers = ( dataPriv.get( 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;
+
+ for ( i = 1; i < arguments.length; i++ ) {
+ args[ i ] = arguments[ i ];
+ }
+
+ 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.rnamespace || event.rnamespace.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 i, handleObj, sel, matchedHandlers, matchedSelectors,
+ handlerQueue = [],
+ delegateCount = handlers.delegateCount,
+ cur = event.target;
+
+ // Find delegate handlers
+ if ( delegateCount &&
+
+ // Support: IE <=9
+ // Black-hole SVG instance trees (trac-13180)
+ cur.nodeType &&
+
+ // Support: Firefox <=42
+ // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+ // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+ // Support: IE 11 only
+ // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+ !( event.type === "click" && event.button >= 1 ) ) {
+
+ for ( ; cur !== this; cur = cur.parentNode || this ) {
+
+ // Don't check non-elements (#13208)
+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+ if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
+ matchedHandlers = [];
+ matchedSelectors = {};
+ for ( i = 0; i < delegateCount; i++ ) {
+ handleObj = handlers[ i ];
+
+ // Don't conflict with Object.prototype properties (#13203)
+ sel = handleObj.selector + " ";
+
+ if ( matchedSelectors[ sel ] === undefined ) {
+ matchedSelectors[ sel ] = handleObj.needsContext ?
+ jQuery( sel, this ).index( cur ) > -1 :
+ jQuery.find( sel, this, null, [ cur ] ).length;
+ }
+ if ( matchedSelectors[ sel ] ) {
+ matchedHandlers.push( handleObj );
+ }
+ }
+ if ( matchedHandlers.length ) {
+ handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
+ }
+ }
+ }
+ }
+
+ // Add the remaining (directly-bound) handlers
+ cur = this;
+ if ( delegateCount < handlers.length ) {
+ handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
+ }
+
+ return handlerQueue;
+ },
+
+ addProp: function( name, hook ) {
+ Object.defineProperty( jQuery.Event.prototype, name, {
+ enumerable: true,
+ configurable: true,
+
+ get: isFunction( hook ) ?
+ function() {
+ if ( this.originalEvent ) {
+ return hook( this.originalEvent );
+ }
+ } :
+ function() {
+ if ( this.originalEvent ) {
+ return this.originalEvent[ name ];
+ }
+ },
+
+ set: function( value ) {
+ Object.defineProperty( this, name, {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: value
+ } );
+ }
+ } );
+ },
+
+ fix: function( originalEvent ) {
+ return originalEvent[ jQuery.expando ] ?
+ originalEvent :
+ new jQuery.Event( originalEvent );
+ },
+
+ 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 ) {
+ this.focus();
+ return false;
+ }
+ },
+ 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 ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
+ this.click();
+ return false;
+ }
+ },
+
+ // For cross-browser consistency, don't fire native .click() on links
+ _default: function( event ) {
+ return 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;
+ }
+ }
+ }
+ }
+};
+
+jQuery.removeEvent = function( elem, type, handle ) {
+
+ // This "if" is needed for plain objects
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, 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: Android <=2.3 only
+ src.returnValue === false ?
+ returnTrue :
+ returnFalse;
+
+ // Create target properties
+ // Support: Safari <=6 - 7 only
+ // Target should not be a text node (#504, #13143)
+ this.target = ( src.target && src.target.nodeType === 3 ) ?
+ src.target.parentNode :
+ src.target;
+
+ this.currentTarget = src.currentTarget;
+ this.relatedTarget = src.relatedTarget;
+
+ // 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 || Date.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ constructor: jQuery.Event,
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse,
+ isSimulated: false,
+
+ preventDefault: function() {
+ var e = this.originalEvent;
+
+ this.isDefaultPrevented = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.preventDefault();
+ }
+ },
+ stopPropagation: function() {
+ var e = this.originalEvent;
+
+ this.isPropagationStopped = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.stopPropagation();
+ }
+ },
+ stopImmediatePropagation: function() {
+ var e = this.originalEvent;
+
+ this.isImmediatePropagationStopped = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.stopImmediatePropagation();
+ }
+
+ this.stopPropagation();
+ }
+};
+
+// Includes all common event props including KeyEvent and MouseEvent specific props
+jQuery.each( {
+ altKey: true,
+ bubbles: true,
+ cancelable: true,
+ changedTouches: true,
+ ctrlKey: true,
+ detail: true,
+ eventPhase: true,
+ metaKey: true,
+ pageX: true,
+ pageY: true,
+ shiftKey: true,
+ view: true,
+ "char": true,
+ charCode: true,
+ key: true,
+ keyCode: true,
+ button: true,
+ buttons: true,
+ clientX: true,
+ clientY: true,
+ offsetX: true,
+ offsetY: true,
+ pointerId: true,
+ pointerType: true,
+ screenX: true,
+ screenY: true,
+ targetTouches: true,
+ toElement: true,
+ touches: true,
+
+ which: function( event ) {
+ var button = event.button;
+
+ // Add which for key events
+ if ( event.which == null && rkeyEvent.test( event.type ) ) {
+ return event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
+ if ( button & 1 ) {
+ return 1;
+ }
+
+ if ( button & 2 ) {
+ return 3;
+ }
+
+ if ( button & 4 ) {
+ return 2;
+ }
+
+ return 0;
+ }
+
+ return event.which;
+ }
+}, jQuery.event.addProp );
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+// so that event delegation works in jQuery.
+// Do the same for pointerenter/pointerleave and pointerover/pointerout
+//
+// Support: Safari 7 only
+// Safari sends mouseenter too often; see:
+// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
+// for the description of the bug (it existed in older Chrome versions as well).
+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 mouseenter/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;
+ }
+ };
+} );
+
+jQuery.fn.extend( {
+
+ on: function( types, selector, data, fn ) {
+ return on( this, types, selector, data, fn );
+ },
+ one: function( types, selector, data, fn ) {
+ return on( this, 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 );
+ } );
+ }
+} );
+
+
+var
+
+ /* eslint-disable max-len */
+
+ // See https://github.com/eslint/eslint/issues/3229
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
+
+ /* eslint-enable */
+
+ // Support: IE <=10 - 11, Edge 12 - 13 only
+ // In IE/Edge using regex groups here causes severe slowdowns.
+ // See https://connect.microsoft.com/IE/feedback/details/1736512/
+ rnoInnerhtml = /
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index
+
+
+
+
+
+
+
+
+
+
+
+
+
+