diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/latest/.buildinfo b/latest/.buildinfo new file mode 100644 index 000000000..73ba20d22 --- /dev/null +++ b/latest/.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: 3262fcfec6335e15746c56e18b284589 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/latest/API_specification/array_object.html b/latest/API_specification/array_object.html new file mode 100644 index 000000000..ba42cbfde --- /dev/null +++ b/latest/API_specification/array_object.html @@ -0,0 +1,10684 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Array object — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ + +

+ Array object + + ¶ + +

+
+
+

+ Array API specification for array object attributes and methods. +

+
+
+

+ A conforming implementation of the array API standard must provide and support an array object having the following attributes and methods adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a method accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Broadcasting semantics must follow the semantics defined in + + + Broadcasting + + + . +

    +
  • +
  • +

    + Unless stated otherwise, methods must support the data types defined in + + + Data Types + + + . +

    +
  • +
  • +

    + Unless stated otherwise, methods must adhere to the type promotion rules defined in + + + Type Promotion Rules + + + . +

    +
  • +
  • +

    + Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. +

    +
  • +
+
+
+ + +

+ Operators + + ¶ + +

+

+ A conforming implementation of the array API standard must provide and support an array object supporting the following Python operators: +

+ +
+

+ In-place Operators + + ¶ + +

+

+ A conforming implementation of the array API standard must provide and support +an array object supporting the following in-place Python operators: +

+
    +
  • +

    + + + += + + + . May be implemented via + + + __iadd__ + + + . +

    +
  • +
  • +

    + + + -= + + + . May be implemented via + + + __isub__ + + + . +

    +
  • +
  • +

    + + + *= + + + . May be implemented via + + + __imul__ + + + . +

    +
  • +
  • +

    + + + /= + + + . May be implemented via + + + __itruediv__ + + + . +

    +
  • +
  • +

    + + + //= + + + . May be implemented via + + + __ifloordiv__ + + + . +

    +
  • +
  • +

    + + + **= + + + . May be implemented via + + + __ipow__ + + + . +

    +
  • +
  • +

    + + + @= + + + . May be implemented via + + + __imatmul__ + + + . +

    +
  • +
  • +

    + + + %= + + + . May be implemented via + + + __imod__ + + + . +

    +
  • +
  • +

    + + + &= + + + . May be implemented via + + + __iand__ + + + . +

    +
  • +
  • +

    + + + |= + + + . May be implemented via + + + __ior__ + + + . +

    +
  • +
  • +

    + + + ^= + + + . May be implemented via + + + __ixor__ + + + . +

    +
  • +
  • +

    + + + <<= + + + . May be implemented via + + + __ilshift__ + + + . +

    +
  • +
  • +

    + + + >>= + + + . May be implemented via + + + __irshift__ + + + . +

    +
  • +
+
+

+ Note +

+

+ In-place operators must be supported as discussed in + + + Copy-view behaviour and mutability + + + . +

+
+
+
+

+ Reflected Operators + + ¶ + +

+

+ A conforming implementation of the array API standard must provide and support +an array object supporting the following reflected operators: +

+
    +
  • +

    + + + __radd__ + + +

    +
  • +
  • +

    + + + __rsub__ + + +

    +
  • +
  • +

    + + + __rmul__ + + +

    +
  • +
  • +

    + + + __rtruediv__ + + +

    +
  • +
  • +

    + + + __rfloordiv__ + + +

    +
  • +
  • +

    + + + __rpow__ + + +

    +
  • +
  • +

    + + + __rmatmul__ + + +

    +
  • +
  • +

    + + + __rmod__ + + +

    +
  • +
  • +

    + + + __rand__ + + +

    +
  • +
  • +

    + + + __ror__ + + +

    +
  • +
  • +

    + + + __rxor__ + + +

    +
  • +
  • +

    + + + __rlshift__ + + +

    +
  • +
  • +

    + + + __rrshift__ + + +

    +
  • +
+

+ The results of applying reflected operators must match their non-reflected equivalents. +

+
+

+ Note +

+

+ All operators for which + + + array + + + <op> + + + scalar + + + is implemented must have an equivalent reflected operator implementation. +

+
+
+
+
+
+

+ Attributes + + ¶ + +

+ +
+ + +

+ dtype + + ¶ + +

+

+ Data type of the array elements. +

+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <dtype> + +

    +
      +
    • +

      + array data type. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ device + + ¶ + +

+

+ Hardware device the array data resides on. +

+
+

+ Returns + + ¶ + +

+ +
+
+
+ + +

+ ndim + + ¶ + +

+

+ Number of array dimensions (axes). +

+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + int + +

    +
      +
    • +

      + number of array dimensions (axes). +

      +
    • +
    +
  • +
+

+ + TODO: need to more carefully consider this in order to accommodate, e.g., graph tensors where the number of dimensions may be dynamic. + +

+
+
+
+ + +

+ shape + + ¶ + +

+

+ Array dimensions. +

+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + Union[ Tuple[ int, …], <shape> ] + +

    +
      +
    • +

      + array dimensions as either a tuple or a custom shape object. If a shape object, the object must be immutable and must support indexing for dimension retrieval. +

      +
    • +
    +
  • +
+

+ + TODO: need to more carefully consider this in order to accommodate, e.g., graph tensors where a shape may be dynamic. + +

+
+
+
+ + +

+ size + + ¶ + +

+

+ Number of elements in an array. This must equal the product of the array’s dimensions. +

+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + int + +

    +
      +
    • +

      + number of elements in an array. +

      +
    • +
    +
  • +
+

+ + TODO: need to more carefully consider this in order to accommodate, e.g., graph tensors where the number of elements may be dynamic. + +

+
+
+
+ + +

+ T + + ¶ + +

+

+ Transpose of the array. +

+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + array whose dimensions (axes) are permuted in reverse order relative to original array. The returned array must have the same data type as the original array. +

      +
    • +
    +
  • +
+
+
+
+
+
+

+ Methods + + ¶ + +

+ +
+ + +

+ __abs__(self, /) + + ¶ + +

+

+ Calculates the absolute value for each element of an array instance (i.e., the element-wise result has the same magnitude as the respective element but has positive sign). +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, let + + + self + + + equal + + + x + + + . +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise absolute value. The returned array must have the same data type as + + + self + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + abs(x) + + + + + . +

+
+
+
+
+ + +

+ __add__(self, other, /) + + ¶ + +

+

+ Calculates the sum for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, let + + + self + + + equal + + + x1 + + + and + + + other + + + equal + + + x2 + + + . +

+
    +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is a finite number, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is a finite number, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a finite number and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a finite number and + + + x2_i + + + is + + + -infinity + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +0 + + + or + + + -0 + + + and + + + x2_i + + + is a nonzero finite number, the result is + + + x2_i + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a nonzero finite number and + + + x2_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + x1_i + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a nonzero finite number and + + + x2_i + + + is + + + -x1_i + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + In the remaining cases, when neither + + + infinity + + + , + + + +0 + + + , + + + -0 + + + , nor a + + + NaN + + + is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an + + + infinity + + + of appropriate mathematical sign. +

    +
  • +
+
+

+ Note +

+

+ Floating-point addition is a commutative operation, but not always associative. +

+
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance (augend array). +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + add(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __and__(self, other, /) + + ¶ + +

+

+ Evaluates + + + self_i + + + & + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. Must have an integer or boolean data type. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    +
      +
    • +

      + other array. Must be compatible with + + + self + + + (see + + + Broadcasting + + + ). Must have an integer or boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + bitwise_and(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __array_namespace__(self, /, *, api_version=None) + + ¶ + +

+

+ Returns an object that has all the array API functions on it. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + api_version + + : + + <Optional[str]> + +

    +
      +
    • +

      + string representing the version of the array API specification to be returned, in + + + 'YYYY.MM' + + + form, for example, + + + '2020.10' + + + . If it is + + + None + + + , it should return the namespace corresponding to latest version of the array API specification. If the given version is invalid or not implemented for the given module, an error should be raised. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <object> + +

    +
      +
    • +

      + an object representing the array API namespace. It should have every top-level function defined in the specification as an attribute. It may contain other public names as well, but it is recommended to only include those names that are part of the specification. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ __bool__(self, /) + + ¶ + +

+

+ Converts a zero-dimensional boolean array to a Python + + + bool + + + object. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + zero-dimensional array instance. Must have a boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <bool> + +

    +
      +
    • +

      + a Python + + + bool + + + object representing the single element of the array. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ __dlpack__(self, /, *, stream=None) + + ¶ + +

+

+ Exports the array for consumption by + + + from_dlpack(x, /) + + + as a DLPack capsule. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + stream + + : + + Optional[ int ] + +

    +
      +
    • +

      + a Python integer representing a pointer to a stream. + + + stream + + + is provided by the consumer to the producer to instruct the producer to ensure that operations can safely be performed on the array. The pointer must be a positive integer or + + + -1 + + + . If + + + stream + + + is + + + -1 + + + , the value may be used by the consumer to signal “producer must not perform any synchronization”. Device-specific notes: +

      +
      +

      + CUDA +

      +
        +
      • +

        + + + None + + + : producer must assume the legacy default stream (default). +

        +
      • +
      • +

        + + + 1 + + + : the legacy default stream. +

        +
      • +
      • +

        + + + 2 + + + : the per-thread default stream. +

        +
      • +
      • +

        + + + > + + + 2 + + + : stream number represented as a Python integer. +

        +
      • +
      +

      + + + 0 + + + is disallowed due to its ambiguity: + + + 0 + + + could mean either + + + None + + + , + + + 1 + + + , or + + + 2 + + + . +

      +
      +
      +

      + ROCm +

      +
        +
      • +

        + + + None + + + : producer must assume the legacy default stream (default). +

        +
      • +
      • +

        + + + 0 + + + : the default stream. +

        +
      • +
      • +

        + + + > + + + 2 + + + : stream number represented as a Python integer. +

        +
      • +
      +

      + Using + + + 1 + + + and + + + 2 + + + is not supported. +

      +
      +
      +

      + Tip +

      +

      + It is recommended that implementers explicitly handle streams. If +they use the legacy default stream, specifying + + + 1 + + + (CUDA) or + + + 0 + + + (ROCm) is preferred. + + + None + + + is a safe default for developers who do +not want to think about stream handling at all, potentially at the +cost of more synchronization than necessary. +

      +
      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+ +
+
+
+ + +

+ __dlpack_device__(self, /) + + ¶ + +

+

+ Returns device type and device ID in DLPack format. Meant for use within + + + from_dlpack(x, /) + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + device + + : + + Tuple[enum.IntEnum, int] + +

    +
      +
    • +

      + a tuple + + + (device_type, + + + device_id) + + + in DLPack format. Valid device type enum members are: +

      +
      +
      +
      CPU = 1
      +CUDA = 2
      +CPU_PINNED = 3
      +OPENCL = 4
      +VULKAN = 7
      +METAL = 8
      +VPI = 9
      +ROCM = 10
      +
      +
      +
      +
    • +
    +
  • +
+
+
+
+ + +

+ __eq__(self, other, /) + + ¶ + +

+

+ Computes the truth value of + + + self_i + + + == + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + equal(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __float__(self, /) + + ¶ + +

+

+ Converts a zero-dimensional floating-point array to a Python + + + float + + + object. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + zero-dimensional array instance. Must have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <float> + +

    +
      +
    • +

      + a Python + + + float + + + object representing the single element of the array instance. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ __floordiv__(self, other, /) + + ¶ + +

+

+ Evaluates + + + self_i + + + // + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + floor_divide(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __ge__(self, other, /) + + ¶ + +

+

+ Computes the truth value of + + + self_i + + + >= + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + greater_equal(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __getitem__(self, key, /) + + ¶ + +

+

+ Returns + + + self[key] + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array;> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + key + + : + + Union[ int, slice, ellipsis, Tuple[ Union[ int, slice, ellipsis ], … ], <array> ] + +

    +
      +
    • +

      + index key. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the accessed value(s). The returned array must have the same data type as + + + self + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ __gt__(self, other, /) + + ¶ + +

+

+ Computes the truth value of + + + self_i + + + > + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + greater(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __int__(self, /) + + ¶ + +

+

+ Converts a zero-dimensional integer array to a Python + + + int + + + object. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + zero-dimensional array instance. Must have an integer data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <int> + +

    +
      +
    • +

      + a Python + + + int + + + object representing the single element of the array instance. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ __invert__(self, /) + + ¶ + +

+

+ Evaluates + + + ~self_i + + + for each element of an array instance. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. Must have an integer or boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have the same data type as + + + self + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + bitwise_invert(x) + + + + + . +

+
+
+
+
+ + +

+ __le__(self, other, /) + + ¶ + +

+

+ Computes the truth value of + + + self_i + + + <= + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + less_equal(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __len__(self, /) + + ¶ + +

+

+ + TODO: need to more carefully consider this in order to accommodate, e.g., graph tensors where a shape may be dynamic. Furthermore, not clear whether this should be implemented, as, e.g., NumPy’s behavior of returning the size of the first dimension is not necessarily intuitive, as opposed to, say, the total number of elements. + +

+
+
+ + +

+ __lshift__(self, other, /) + + ¶ + +

+

+ Evaluates + + + self_i + + + << + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. Must have an integer data type. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    +
      +
    • +

      + other array. Must be compatible with + + + self + + + (see + + + Broadcasting + + + ). Must have an integer data type. Each element must be greater than or equal to + + + 0 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have the same data type as + + + self + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + less_equal(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __lt__(self, other, /) + + ¶ + +

+

+ Computes the truth value of + + + self_i + + + < + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + less(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __matmul__(self, other, /) + + ¶ + +

+

+ + TODO: awaiting + + + matmul + + + functional equivalent. + +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + + TODO + +

      +
    • +
    +
  • +
+
+
+
+ + +

+ __mod__(self, other, /) + + ¶ + +

+

+ Evaluates + + + self_i + + + % + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. Each element-wise result must have the same sign as the respective element + + + other_i + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + remainder(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __mul__(self, other, /) + + ¶ + +

+

+ Calculates the product for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, let + + + self + + + equal + + + x1 + + + and + + + other + + + equal + + + x2 + + + . +

+
    +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +infinity + + + or + + + -infinity + + + and + + + x2_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +0 + + + or + + + -0 + + + and + + + x2_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + and + + + x2_i + + + have the same mathematical sign, the result has a positive mathematical sign, unless the result is + + + NaN + + + . If the result is + + + NaN + + + , the “sign” of + + + NaN + + + is implementation-defined. +

    +
  • +
  • +

    + If + + + x1_i + + + and + + + x2_i + + + have different mathematical signs, the result has a negative mathematical sign, unless the result is + + + NaN + + + . If the result is + + + NaN + + + , the “sign” of + + + NaN + + + is implementation-defined. +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +infinity + + + or + + + -infinity + + + and + + + x2_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is a signed infinity with the mathematical sign determined by the rule already stated above. +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +infinity + + + or + + + -infinity + + + and + + + x2_i + + + is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. +

    +
  • +
  • +

    + If + + + x1_i + + + is a nonzero finite number and + + + x2_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is a signed infinity with the mathematical sign determined by the rule already stated above. +

    +
  • +
  • +

    + In the remaining cases, where neither + + + infinity + + + nor + + + NaN + + + is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an + + + infinity + + + of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. +

    +
  • +
+
+

+ Note +

+

+ Floating-point multiplication is not always associative due to finite precision. +

+
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise products. The returned array must have a data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + multiply(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __ne__(self, other, /) + + ¶ + +

+

+ Computes the truth value of + + + self_i + + + != + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + (i.e., must be a boolean array). +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + not_equal(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __neg__(self, /) + + ¶ + +

+

+ Evaluates + + + -self_i + + + for each element of an array instance. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated result for each element in + + + self + + + . The returned array must have a data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + negative(x) + + + + + . +

+
+
+
+
+ + +

+ __or__(self, other, /) + + ¶ + +

+

+ Evaluates + + + self_i + + + | + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. Must have an integer or boolean data type. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    +
      +
    • +

      + other array. Must be compatible with + + + self + + + (see + + + Broadcasting + + + ). Must have an integer or boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + positive(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __pos__(self, /) + + ¶ + +

+

+ Evaluates + + + +self_i + + + for each element of an array instance. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated result for each element. The returned array must have the same data type as + + + self + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + positive(x) + + + + + . +

+
+
+
+
+ + +

+ __pow__(self, other, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation of exponentiation by raising each element (the base) of an array instance to the power of + + + other_i + + + (the exponent), where + + + other_i + + + is the corresponding element of the array + + + other + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, let + + + self + + + equal + + + x1 + + + and + + + other + + + equal + + + x2 + + + . +

+
    +
  • +

    + If + + + x1_i + + + is not equal to + + + 1 + + + and + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x2_i + + + is + + + +0 + + + , the result is + + + 1 + + + , even if + + + x1_i + + + is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x2_i + + + is + + + -0 + + + , the result is + + + 1 + + + , even if + + + x1_i + + + is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + NaN + + + and + + + x2_i + + + is not equal to + + + 0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is greater than + + + 1 + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is greater than + + + 1 + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is + + + 1 + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is + + + 1 + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + 1 + + + and + + + x2_i + + + is not + + + NaN + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is less than + + + 1 + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is less than + + + 1 + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + , + + + x2_i + + + is greater than + + + 0 + + + , and + + + x2_i + + + is not an odd integer value, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + , + + + x2_i + + + is less than + + + 0 + + + , and + + + x2_i + + + is an odd integer value, the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + , + + + x2_i + + + is less than + + + 0 + + + , and + + + x2_i + + + is not an odd integer value, the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + , + + + x2_i + + + is greater than + + + 0 + + + , and + + + x2_i + + + is an odd integer value, the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + , + + + x2_i + + + is greater than + + + 0 + + + , and + + + x2_i + + + is not an odd integer value, the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + , + + + x2_i + + + is less than + + + 0 + + + , and + + + x2_i + + + is an odd integer value, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + , + + + x2_i + + + is less than + + + 0 + + + , and + + + x2_i + + + is not an odd integer value, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + , + + + x1_i + + + is a finite number, + + + x2_i + + + is a finite number, and + + + x2_i + + + is not an integer value, the result is + + + NaN + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance whose elements correspond to the exponentiation base. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    +
      +
    • +

      + other array whose elements correspond to the exponentiation exponent. Must be compatible with + + + self + + + (see + + + Broadcasting + + + ). +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + pow(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __rshift__(self, other, /) + + ¶ + +

+

+ Evaluates + + + self_i + + + >> + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. Must have an integer data type. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    +
      +
    • +

      + other array. Must be compatible with + + + self + + + (see + + + Broadcasting + + + ). Must have an integer data type. Each element must be greater than or equal to + + + 0 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have the same data type as + + + self + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + bitwise_right_shift(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __setitem__(self, key, value, /) + + ¶ + +

+

+ + TODO: dependent on the indexing specification. + +

+
+
+ + +

+ __sub__(self, other, /) + + ¶ + +

+

+ Calculates the difference for each element of an array instance with the respective element of the array + + + other + + + . The result of + + + self_i + + + - + + + other_i + + + must be the same as + + + self_i + + + + + + + (-other_i) + + + and must be governed by the same floating-point rules as addition (see + + + + + __add__() + + + + + ). +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance (minuend array). +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise differences. The returned array must have a data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + subtract(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __truediv__(self, other, /) + + ¶ + +

+

+ Evaluates + + + self_i + + + / + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, let + + + self + + + equal + + + x1 + + + and + + + other + + + equal + + + x2 + + + . +

+
    +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +infinity + + + or + + + -infinity + + + and + + + x2_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +0 + + + or + + + -0 + + + and + + + x2_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is greater than + + + 0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is greater than + + + 0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is a positive (i.e., greater than + + + 0 + + + ) finite number, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is a negative (i.e., less than + + + 0 + + + ) finite number, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is a positive (i.e., greater than + + + 0 + + + ) finite number, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is a negative (i.e., less than + + + 0 + + + ) finite number, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a positive (i.e., greater than + + + 0 + + + ) finite number and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a positive (i.e., greater than + + + 0 + + + ) finite number and + + + x2_i + + + is + + + -infinity + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a negative (i.e., less than + + + 0 + + + ) finite number and + + + x2_i + + + is + + + +infinity + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a negative (i.e., less than + + + 0 + + + ) finite number and + + + x2_i + + + is + + + -infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + and + + + x2_i + + + have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. +

    +
  • +
  • +

    + If + + + x1_i + + + and + + + x2_i + + + have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. +

    +
  • +
  • +

    + In the remaining cases, where neither + + + -infinity + + + , + + + +0 + + + , + + + -0 + + + , nor + + + NaN + + + is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an + + + infinity + + + of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + divide(x1, + + + x2) + + + + + . +

+
+
+
+
+ + +

+ __xor__(self, other, /) + + ¶ + +

+

+ Evaluates + + + self_i + + + ^ + + + other_i + + + for each element of an array instance with the respective element of the array + + + other + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + self + + : + + <array> + +

    +
      +
    • +

      + array instance. Must have an integer or boolean data type. +

      +
    • +
    +
  • +
  • +

    + + other + + : + + <array> + +

    +
      +
    • +

      + other array. Must be compatible with + + + self + + + (see + + + Broadcasting + + + ). Must have an integer or boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+

+ Note +

+

+ Element-wise results must equal the results returned by the equivalent element-wise function + + + + + bitwise_xor(x1, + + + x2) + + + + + . +

+
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/broadcasting.html b/latest/API_specification/broadcasting.html new file mode 100644 index 000000000..d0cd469c1 --- /dev/null +++ b/latest/API_specification/broadcasting.html @@ -0,0 +1,1136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Broadcasting — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +

+ Broadcasting + + ¶ + +

+
+
+

+ Array API specification for broadcasting semantics. +

+
+
+
+

+ Overview + + ¶ + +

+

+ + Broadcasting + + refers to the automatic (implicit) expansion of array dimensions to be of equal sizes without copying array data for the purpose of making arrays with different shapes have compatible shapes for element-wise operations. +

+

+ Broadcasting facilitates user ergonomics by encouraging users to avoid unnecessary copying of array data and can + + potentially + + enable more memory-efficient element-wise operations through vectorization, reduced memory consumption, and cache locality. +

+
+
+

+ Algorithm + + ¶ + +

+

+ Given an element-wise operation involving two compatible arrays, an array having a singleton dimension (i.e., a dimension whose size is one) is broadcast (i.e., virtually repeated) across an array having a corresponding non-singleton dimension. +

+

+ If two arrays are of unequal rank, the array having a lower rank is promoted to a higher rank by (virtually) prepending singleton dimensions until the number of dimensions matches that of the array having a higher rank. +

+

+ The results of the element-wise operation must be stored in an array having a shape determined by the following algorithm. +

+
    +
  1. +

    + Let + + + A + + + and + + + B + + + both be arrays. +

    +
  2. +
  3. +

    + Let + + + shape1 + + + be a tuple describing the shape of array + + + A + + + . +

    +
  4. +
  5. +

    + Let + + + shape2 + + + be a tuple describing the shape of array + + + B + + + . +

    +
  6. +
  7. +

    + Let + + + N1 + + + be the number of dimensions of array + + + A + + + (i.e., the result of + + + len(shape1) + + + ). +

    +
  8. +
  9. +

    + Let + + + N2 + + + be the number of dimensions of array + + + B + + + (i.e., the result of + + + len(shape2) + + + ). +

    +
  10. +
  11. +

    + Let + + + N + + + be the maximum value of + + + N1 + + + and + + + N2 + + + (i.e., the result of + + + max(N1, + + + N2) + + + ). +

    +
  12. +
  13. +

    + Let + + + shape + + + be a temporary list of length + + + N + + + for storing the shape of the result array. +

    +
  14. +
  15. +

    + Let + + + i + + + be + + + N-1 + + + . +

    +
  16. +
  17. +

    + Repeat, while + + + i + + + >= + + + 0 + + +

    +
      +
    1. +

      + Let + + + n1 + + + be + + + N1 + + + - + + + N + + + + + + + i + + + . +

      +
    2. +
    3. +

      + If + + + n1 + + + >= + + + 0 + + + , let + + + d1 + + + be the size of dimension + + + n1 + + + for array + + + A + + + (i.e., the result of + + + shape1[n1] + + + ); else, let + + + d1 + + + be + + + 1 + + + . +

      +
    4. +
    5. +

      + Let + + + n2 + + + be + + + N2 + + + - + + + N + + + + + + + i + + + . +

      +
    6. +
    7. +

      + If + + + n2 + + + >= + + + 0 + + + , let + + + d2 + + + be the size of dimension + + + n2 + + + for array + + + B + + + (i.e., the result of + + + shape2[n2] + + + ); else, let + + + d2 + + + be + + + 1 + + + . +

      +
    8. +
    9. +

      + If + + + d1 + + + == + + + 1 + + + , then +

      +
        +
      • +

        + set the + + + i + + + th element of + + + shape + + + to + + + d2 + + + . +

        +
      • +
      +
    10. +
    11. +

      + Else, if + + + d2 + + + == + + + 1 + + + , then +

      +
        +
      • +

        + set the + + + i + + + th element of + + + shape + + + to + + + d1 + + + . +

        +
      • +
      +
    12. +
    13. +

      + Else, if + + + d1 + + + == + + + d2 + + + , then +

      +
        +
      • +

        + set the + + + i + + + th element of + + + shape + + + to + + + d1 + + + . +

        +
      • +
      +
    14. +
    15. +

      + Else, throw an exception. +

      +
    16. +
    17. +

      + Set + + + i + + + to + + + i-1 + + + . +

      +
    18. +
    +
  18. +
  19. +

    + Let + + + tuple(shape) + + + be the shape of the result array. +

    +
  20. +
+
+

+ Examples + + ¶ + +

+

+ The following examples demonstrate the application of the broadcasting algorithm for two compatible arrays. +

+
+
+
A      (4d array):  8 x 1 x 6 x 1
+B      (3d array):      7 x 1 x 5
+---------------------------------
+Result (4d array):  8 x 7 x 6 x 5
+
+A      (2d array):  5 x 4
+B      (1d array):      1
+-------------------------
+Result (2d array):  5 x 4
+
+A      (2d array):  5 x 4
+B      (1d array):      4
+-------------------------
+Result (2d array):  5 x 4
+
+A      (3d array):  15 x 3 x 5
+B      (3d array):  15 x 1 x 5
+------------------------------
+Result (3d array):  15 x 3 x 5
+
+A      (3d array):  15 x 3 x 5
+B      (2d array):       3 x 5
+------------------------------
+Result (3d array):  15 x 3 x 5
+
+A      (3d array):  15 x 3 x 5
+B      (2d array):       3 x 1
+------------------------------
+Result (3d array):  15 x 3 x 5
+
+
+
+

+ The following examples demonstrate array shapes which do + + not + + broadcast. +

+
+
+
A      (1d array):  3
+B      (1d array):  4           # dimension does not match
+
+A      (2d array):      2 x 1
+B      (3d array):  8 x 4 x 3   # second dimension does not match
+
+A      (3d array):  15 x 3 x 5
+B      (2d array):  15 x 3      # singleton dimensions can only be prepended, not appended
+
+
+
+
+
+
+

+ In-place Semantics + + ¶ + +

+

+ As implied by the broadcasting algorithm, in-place element-wise operations must not change the shape of the in-place array as a result of broadcasting. +

+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/constants.html b/latest/API_specification/constants.html new file mode 100644 index 000000000..f0ac691bd --- /dev/null +++ b/latest/API_specification/constants.html @@ -0,0 +1,612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Constants — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+

+ Constants + + ¶ + +

+
+
+

+ Array API specification for constants. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following constants. +

+ +
+

+ Objects in API + + ¶ + +

+
+ + +

+ e + + ¶ + +

+

+ Euler’s constant. +

+
+
+
e = 2.71828182845904523536028747135266249775724709369995...
+
+
+
+
+
+ + +

+ inf + + ¶ + +

+

+ IEEE 754 floating-point representation of (positive) infinity. +

+
+
+ + +

+ nan + + ¶ + +

+

+ IEEE 754 floating-point representation of Not a Number ( + + + NaN + + + ). +

+
+
+ + +

+ pi + + ¶ + +

+

+ The mathematical constant + + + π + + + . +

+
+
+
pi = 3.1415926535897932384626433...
+
+
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/creation_functions.html b/latest/API_specification/creation_functions.html new file mode 100644 index 000000000..2c3e7e839 --- /dev/null +++ b/latest/API_specification/creation_functions.html @@ -0,0 +1,3343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Creation Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+

+ Creation Functions + + ¶ + +

+
+
+

+ Array API specification for creating arrays. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ arange(start, /, *, stop=None, step=1, dtype=None, device=None) + + ¶ + +

+

+ Returns evenly spaced values within the half-open interval + + + [start, + + + stop) + + + as a one-dimensional array. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + start + + : + + Union[ int, float ] + +

    +
      +
    • +

      + if + + + stop + + + is specified, the start of interval (inclusive); otherwise, the end of the interval (exclusive). If + + + stop + + + is not specified, the default starting value is + + + 0 + + + . +

      +
    • +
    +
  • +
  • +

    + + stop + + : + + Optional[ Union[ int, float ] ] + +

    +
      +
    • +

      + the end of the interval. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+

+ Note +

+

+ This function cannot guarantee that the interval does not include the + + + stop + + + value in those cases where + + + step + + + is not an integer and floating-point rounding errors affect the length of the output array. +

+
+
    +
  • +

    + + step + + : + + Union[ int, float ] + +

    +
      +
    • +

      + the distance between two adjacent elements ( + + + out[i+1] + + + - + + + out[i] + + + ). Default: + + + 1 + + + . +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be the default floating-point data type. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + a one-dimensional array containing evenly spaced values. The length of the output array must be + + + ceil((stop-start)/step) + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ asarray(obj, /, *, dtype=None, device=None, copy=None) + + ¶ + +

+

+ Convert the input to an array. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + obj + + : + + Union[ float, NestedSequence[ bool | int | float ], SupportsDLPack, SupportsBufferProtocol ] + +

    +
      +
    • +

      + Object to be converted to an array. Can be a Python scalar, a (possibly nested) sequence of Python scalars, or an object supporting DLPack or the Python buffer protocol. +

      +
    • +
    +
    +

    + Tip +

    +

    + An object supporting DLPack has + + + __dlpack__ + + + and + + + __dlpack_device__ + + + methods. +An object supporting the buffer protocol can be turned into a memoryview through + + + memoryview(obj) + + + . +

    +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be inferred from the data type(s) in + + + obj + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + copy + + : + + Optional[ bool ] + +

    +
      +
    • +

      + Whether or not to make a copy of the input. If + + + True + + + , always copies. If + + + False + + + , never copies for input which supports DLPack or the buffer protocol, and raises + + + ValueError + + + in case that would be necessary. If + + + None + + + , reuses existing memory buffer if possible, copies otherwise. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + An array containing the data from + + + obj + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ empty(shape, /, *, dtype=None, device=None) + + ¶ + +

+

+ Returns an uninitialized array having a specified + + + shape + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + shape + + : + + Union[ int, Tuple[ int, … ] ] + +

    +
      +
    • +

      + output array shape. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be the default floating-point data type. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing uninitialized data. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ empty_like(x, /, *, dtype=None, device=None) + + ¶ + +

+

+ Returns an uninitialized array with the same + + + shape + + + as an input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array from which to derive the output array shape. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be inferred from + + + x + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. If + + + device + + + is + + + None + + + , the default device must be used, not + + + x.device + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array having the same shape as + + + x + + + and containing uninitialized data. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ eye(N, /, *, M=None, k=0, dtype=None, device=None) + + ¶ + +

+

+ Returns a two-dimensional array with ones on the + + + k + + + th diagonal and zeros elsewhere. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + N + + : + + int + +

    +
      +
    • +

      + number of rows in the output array. +

      +
    • +
    +
  • +
  • +

    + + M + + : + + Optional[ int ] + +

    +
      +
    • +

      + number of columns in the output array. If + + + None + + + , the default number of columns in the output array is + + + N + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + k + + : + + Optional[ int ] + +

    +
      +
    • +

      + index of the diagonal. A positive value refers to an upper diagonal, a negative value to a lower diagonal, and + + + 0 + + + to the main diagonal. Default: + + + 0 + + + . +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be the default floating-point data type. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array where all elements are equal to zero, except for the + + + k + + + th diagonal, whose values are equal to one. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ from_dlpack(x, /) + + ¶ + +

+

+ Returns a new array containing the data from another (array) object with a + + + __dlpack__ + + + method. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + object + +

    +
      +
    • +

      + input (array) object. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the data in + + + x + + + . +

      +
      +

      + Note +

      +

      + The returned array may be either a copy or a view. See + + + Data interchange mechanisms + + + for details. +

      +
      +
    • +
    +
  • +
+
+
+
+ + +

+ full(shape, fill_value, /, *, dtype=None, device=None) + + ¶ + +

+

+ Returns a new array having a specified + + + shape + + + and filled with + + + fill_value + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + shape + + : + + Union[ int, Tuple[ int, … ] ] + +

    +
      +
    • +

      + output array shape. +

      +
    • +
    +
  • +
  • +

    + + fill_value + + : + + Union[ int, float ] + +

    +
      +
    • +

      + fill value. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be the default floating-point data type. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array where every element is equal to + + + fill_value + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ full_like(x, fill_value, /, *, dtype=None, device=None) + + ¶ + +

+

+ Returns a new array filled with + + + fill_value + + + and having the same + + + shape + + + as an input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array from which to derive the output array shape. +

      +
    • +
    +
  • +
  • +

    + + fill_value + + : + + Union[ int, float ] + +

    +
      +
    • +

      + fill value. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be inferred from + + + x + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. If + + + device + + + is + + + None + + + , the default device must be used, not + + + x.device + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array having the same shape as + + + x + + + and where every element is equal to + + + fill_value + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ linspace(start, stop, num, /, *, dtype=None, device=None, endpoint=True) + + ¶ + +

+

+ Returns evenly spaced numbers over a specified interval. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + start + + : + + Union[ int, float ] + +

    +
      +
    • +

      + the start of the interval. +

      +
    • +
    +
  • +
  • +

    + + stop + + : + + Union[ int, float ] + +

    +
      +
    • +

      + the end of the interval. If + + + endpoint + + + is + + + False + + + , the function must generate a sequence of + + + num+1 + + + evenly spaced numbers starting with + + + start + + + and ending with + + + stop + + + and exclude the + + + stop + + + from the returned array such that the returned array consists of evenly spaced numbers over the half-open interval + + + [start, + + + stop) + + + . If + + + endpoint + + + is + + + True + + + , the output array must consist of evenly spaced numbers over the closed interval + + + [start, + + + stop] + + + . Default: + + + True + + + . +

      +
      +

      + Note +

      +

      + The step size changes when + + + endpoint + + + is + + + False + + + . +

      +
      +
    • +
    +
  • +
  • +

    + + num + + : + + int + +

    +
      +
    • +

      + number of samples. Must be a non-negative integer value; otherwise, the function must raise an exception. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be the default floating-point data type. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + endpoint + + : + + bool + +

    +
      +
    • +

      + boolean indicating whether to include + + + stop + + + in the interval. Default: + + + True + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + a one-dimensional array containing evenly spaced values. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ ones(shape, /, *, dtype=None, device=None) + + ¶ + +

+

+ Returns a new array having a specified + + + shape + + + and filled with ones. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + shape + + : + + Union[ int, Tuple[ int, … ] ] + +

    +
      +
    • +

      + output array shape. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be the default floating-point data type. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing ones. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ ones_like(x, /, *, dtype=None, device=None) + + ¶ + +

+

+ Returns a new array filled with ones and having the same + + + shape + + + as an input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array from which to derive the output array shape. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be inferred from + + + x + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. If + + + device + + + is + + + None + + + , the default device must be used, not + + + x.device + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array having the same shape as + + + x + + + and filled with ones. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ zeros(shape, /, *, dtype=None, device=None) + + ¶ + +

+

+ Returns a new array having a specified + + + shape + + + and filled with zeros. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + shape + + : + + Union[ int, Tuple[ int, … ] ] + +

    +
      +
    • +

      + output array shape. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be the default floating-point data type. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing zeros. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ zeros_like(x, /, *, dtype=None, device=None) + + ¶ + +

+

+ Returns a new array filled with zeros and having the same + + + shape + + + as an input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array from which to derive the output array shape. +

      +
    • +
    +
  • +
  • +

    + + dtype + + : + + Optional[ <dtype> ] + +

    +
      +
    • +

      + output array data type. If + + + dtype + + + is + + + None + + + , the output array data type must be inferred from + + + x + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + device + + : + + Optional[ <device> ] + +

    +
      +
    • +

      + device to place the created array on, if given. If + + + device + + + is + + + None + + + , the default device must be used, not + + + x.device + + + . Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array having the same shape as + + + x + + + and filled with zeros. +

      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/data_type_functions.html b/latest/API_specification/data_type_functions.html new file mode 100644 index 000000000..839391004 --- /dev/null +++ b/latest/API_specification/data_type_functions.html @@ -0,0 +1,962 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Data type functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+

+ Data type functions + + ¶ + +

+
+
+

+ Array API specification for data type functions. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following data type functions. +

+ +
+

+ Objects in API + + ¶ + +

+
+ + +

+ finfo(type, /) + + ¶ + +

+

+ Machine limits for floating-point data types. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + type + + : + + Union[ <dtype>, <array> ] + +

    +
      +
    • +

      + the kind of floating-point data-type about which to get information. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <finfo object> + +

    +
      +
    • +

      + an object having the following attributes: +

      +
        +
      • +

        + + bits + + : + + int + +

        +
          +
        • +

          + number of bits occupied by the floating-point data type. +

          +
        • +
        +
      • +
      • +

        + + eps + + : + + float + +

        +
          +
        • +

          + difference between 1.0 and the next smallest representable floating-point number larger than 1.0 according to the IEEE-754 standard. +

          +
        • +
        +
      • +
      • +

        + + max + + : + + float + +

        +
          +
        • +

          + largest representable number. +

          +
        • +
        +
      • +
      • +

        + + min + + : + + float + +

        +
          +
        • +

          + smallest representable number. +

          +
        • +
        +
      • +
      +
    • +
    +
  • +
+
+
+
+ + +

+ iinfo(type, /) + + ¶ + +

+

+ Machine limits for integer data types. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + type + + : + + Union[ <dtype>, <array> ] + +

    +
      +
    • +

      + the kind of integer data-type about which to get information. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <iinfo object> + +

    +
      +
    • +

      + a class with that encapsules the following attributes: +

      +
        +
      • +

        + + bits + + : + + int + +

        +
          +
        • +

          + number of bits occupied by the type +

          +
        • +
        +
      • +
      • +

        + + max + + : + + int + +

        +
          +
        • +

          + largest representable number. +

          +
        • +
        +
      • +
      • +

        + + min + + : + + int + +

        +
          +
        • +

          + smallest representable number. +

          +
        • +
        +
      • +
      +
    • +
    +
  • +
+
+
+
+ + +

+ result_type(*arrays_and_dtypes) + + ¶ + +

+

+ Returns the dtype that results from applying the type promotion rules +(see + + + Type Promotion Rules + + + ) to the arguments. +

+
+

+ Note +

+

+ If provided mixed dtypes (e.g., integer and floating-point), the returned dtype will be implementation-specific. +

+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + arrays_and_dtypes + + : + + Sequence[ Union[ <array>, <dtype> ] ] + +

    +
      +
    • +

      + input arrays and dtypes. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <dtype> + +

    +
      +
    • +

      + the dtype resulting from an operation involving the input arrays and dtypes. +

      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/data_types.html b/latest/API_specification/data_types.html new file mode 100644 index 000000000..1f2c6a365 --- /dev/null +++ b/latest/API_specification/data_types.html @@ -0,0 +1,1147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Data Types — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Data Types + + ¶ + +

+
+
+

+ Array API specification for supported data types. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following data types. +

+

+ A conforming implementation of the array API standard must define a default floating-point data type (either + + + float32 + + + or + + + float64 + + + ), as well as a default data type for an array index (either + + + int32 + + + or + + + int64 + + + ). +

+
+

+ Note +

+

+ The default floating-point and array index integer data types should be clearly defined in a conforming library’s documentation. +

+
+
+

+ bool + + ¶ + +

+

+ Boolean ( + + + True + + + or + + + False + + + ). +

+
+
+

+ int8 + + ¶ + +

+

+ An 8-bit signed integer whose values exist on the interval + + + [-128, + + + +127] + + + . +

+
+
+

+ int16 + + ¶ + +

+

+ A 16-bit signed integer whose values exist on the interval + + + [−32,767, + + + +32,767] + + + . +

+
+
+

+ int32 + + ¶ + +

+

+ A 32-bit signed integer whose values exist on the interval + + + [−2,147,483,647, + + + +2,147,483,647] + + + . +

+
+
+

+ int64 + + ¶ + +

+

+ A 64-bit signed integer whose values exist on the interval + + + [−9,223,372,036,854,775,807, + + + +9,223,372,036,854,775,807] + + + . +

+
+
+

+ uint8 + + ¶ + +

+

+ An 8-bit unsigned integer whose values exist on the interval + + + [0, + + + +255] + + + . +

+
+
+

+ uint16 + + ¶ + +

+

+ A 16-bit unsigned integer whose values exist on the interval + + + [0, + + + +65,535] + + + . +

+
+
+

+ uint32 + + ¶ + +

+

+ A 32-bit unsigned integer whose values exist on the interval + + + [0, + + + +4,294,967,295] + + + . +

+
+
+

+ uint64 + + ¶ + +

+

+ A 64-bit unsigned integer whose values exist on the interval + + + [0, + + + +18,446,744,073,709,551,615] + + + . +

+
+
+

+ float32 + + ¶ + +

+

+ IEEE 754 single-precision (32-bit) binary floating-point number (see IEEE 754-2019). +

+
+
+

+ float64 + + ¶ + +

+

+ IEEE 754 double-precision (64-bit) binary floating-point number (see IEEE 754-2019). +

+
+

+ Future extension +

+

+ It is expected that in the next version of this standard, + + + complex64 + + + and + + + complex128 + + + dtypes will be added, with these casting rules (will be added to + + + Type Promotion Rules + + + ): +

+

+ Type promotion diagram for complex dtypes in next version +

+

+ See + + array-api/issues/102 + + for more details. +

+
+
+

+ Note +

+

+ Data types (“dtypes”) are objects that can be used as + + + dtype + + + specifiers in functions and methods (e.g., + + + zeros((2, + + + 3), + + + dtype=float32) + + + ). A conforming implementation may add methods or attributes to data type objects; however, these methods and attributes are not included in this specification. +

+

+ Implementations may provide other ways to specify data types (e.g., + + + zeros((2, + + + 3), + + + dtype='f4') + + + ); however, these are not included in this specification. +

+

+ A conforming implementation of the array API standard may provide and support additional data types beyond those described in this specification. +

+
+
+
+ + +

+ Data Type Categories + + ¶ + +

+

+ For the purposes of this specification, the following data type categories are defined. +Libraries do not need to organize dtypes according to these categories. These +are only for organizing the functions in this specification itself. Future versions of +the specification will include additional categories for complex data types. +

+
+

+ Numeric Data Types + + ¶ + +

+

+ + + int8 + + + , + + + int16 + + + , + + + int32 + + + , + + + int64 + + + , + + + uint8 + + + , + + + uint16 + + + , + + + uint32 + + + , + + + uint64 + + + , + + + float32 + + + , and + + + float64 + + + (i.e., all dtypes except for + + + bool + + + ). +

+
+
+

+ Integer Data Types + + ¶ + +

+

+ + + int8 + + + , + + + int16 + + + , + + + int32 + + + , + + + int64 + + + , + + + uint8 + + + , + + + uint16 + + + , + + + uint32 + + + , and + + + uint64 + + + . +

+
+
+

+ Floating-point Data Types + + ¶ + +

+

+ + + float32 + + + and + + + float64 + + + . +

+
+
+

+ Boolean Data Types + + ¶ + +

+

+ + + bool + + + . +

+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/elementwise_functions.html b/latest/API_specification/elementwise_functions.html new file mode 100644 index 000000000..2a8a2190d --- /dev/null +++ b/latest/API_specification/elementwise_functions.html @@ -0,0 +1,16208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Element-wise Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ + +

+ Element-wise Functions + + ¶ + +

+
+
+

+ Array API specification for element-wise functions. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Broadcasting semantics must follow the semantics defined in + + + Broadcasting + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must support the data types defined in + + + Data Types + + + . +

    +
  • +
  • +

    + Functions may only be required for a subset of input data type. Libraries may choose to implement functions for additional data types, but that behavior is not required by the specification. See + + + Data Type Categories + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must adhere to the type promotion rules defined in + + + Type Promotion Rules + + + . +

    +
  • +
  • +

    + Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. +

    +
  • +
  • +

    + Unless stated otherwise, element-wise mathematical functions must satisfy the minimum accuracy requirements defined in + + + Accuracy + + + . +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ abs(x, /) + + ¶ + +

+

+ Calculates the absolute value for each element + + + x_i + + + of the input array + + + x + + + (i.e., the element-wise result has the same magnitude as the respective element in + + + x + + + but has positive sign). +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the absolute value of each element in + + + x + + + . The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ acos(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation of the principal value of the inverse cosine, having domain + + + [-1, + + + +1] + + + and codomain + + + [+0, + + + +π] + + + , for each element + + + x_i + + + of the input array + + + x + + + . Each element-wise result is expressed in radians. +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is greater than + + + 1 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + -1 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + 1 + + + , the result is + + + +0 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the inverse cosine of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ acosh(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the inverse hyperbolic cosine, having domain + + + [+1, + + + +infinity] + + + and codomain + + + [+0, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + 1 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + 1 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements each represent the area of a hyperbolic sector. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the inverse hyperbolic cosine of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ add(x1, x2, /) + + ¶ + +

+

+ Calculates the sum for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is a finite number, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is a finite number, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a finite number and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a finite number and + + + x2_i + + + is + + + -infinity + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +0 + + + or + + + -0 + + + and + + + x2_i + + + is a nonzero finite number, the result is + + + x2_i + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a nonzero finite number and + + + x2_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + x1_i + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a nonzero finite number and + + + x2_i + + + is + + + -x1_i + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + In the remaining cases, when neither + + + infinity + + + , + + + +0 + + + , + + + -0 + + + , nor a + + + NaN + + + is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an + + + infinity + + + of appropriate mathematical sign. +

    +
  • +
+
+

+ Note +

+

+ Floating-point addition is a commutative operation, but not always associative. +

+
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+
+
+ + +

+ asin(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation of the principal value of the inverse sine, having domain + + + [-1, + + + +1] + + + and codomain + + + [-π/2, + + + +π/2] + + + for each element + + + x_i + + + of the input array + + + x + + + . Each element-wise result is expressed in radians. +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is greater than + + + 1 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + -1 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the inverse sine of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ asinh(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the inverse hyperbolic sine, having domain + + + [-infinity, + + + +infinity] + + + and codomain + + + [-infinity, + + + +infinity] + + + , for each element + + + x_i + + + in the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + -infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements each represent the area of a hyperbolic sector. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the inverse hyperbolic sine of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ atan(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation of the principal value of the inverse tangent, having domain + + + [-infinity, + + + +infinity] + + + and codomain + + + [-π/2, + + + +π/2] + + + , for each element + + + x_i + + + of the input array + + + x + + + . Each element-wise result is expressed in radians. +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is an implementation-dependent approximation to + + + +π/2 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is an implementation-dependent approximation to + + + -π/2 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the inverse tangent of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ atan2(x1, x2, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation of the inverse tangent of the quotient + + + x1/x2 + + + , having domain + + + [-infinity, + + + +infinity] + + + x + + + [-infinity, + + + +infinity] + + + (where the + + + x + + + notation denotes the set of ordered pairs of elements + + + (x1_i, + + + x2_i) + + + ) and codomain + + + [-π, + + + +π] + + + , for each pair of elements + + + (x1_i, + + + x2_i) + + + of the input arrays + + + x1 + + + and + + + x2 + + + , respectively. Each element-wise result is expressed in radians. +

+

+ The mathematical signs of + + + x1_i + + + and + + + x2_i + + + determine the quadrant of each element-wise result. The quadrant (i.e., branch) is chosen such that each element-wise result is the signed angle in radians between the ray ending at the origin and passing through the point + + + (1,0) + + + and the ray ending at the origin and passing through the point + + + (x2_i, + + + x1_i) + + + . +

+
+

+ Note +

+

+ Note the role reversal: the “y-coordinate” is the first function parameter; the “x-coordinate” is the second function parameter. The parameter order is intentional and traditional for the two-argument inverse tangent function where the y-coordinate argument is first and the x-coordinate argument is second. +

+
+

+ By IEEE 754 convention, the inverse tangent of the quotient + + + x1/x2 + + + is defined for + + + x2_i + + + equal to positive or negative zero and for either or both of + + + x1_i + + + and + + + x2_i + + + equal to positive or negative + + + infinity + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is greater than + + + 0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is an implementation-dependent approximation to + + + +π/2 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is greater than + + + 0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is an implementation-dependent approximation to + + + +π/2 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is an implementation-dependent approximation to + + + +π + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is an implementation-dependent approximation to + + + +π + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is an implementation-dependent approximation to + + + -π + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is an implementation-dependent approximation to + + + -π + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is an implementation-dependent approximation to + + + -π/2 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is an implementation-dependent approximation to + + + -π/2 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is greater than + + + 0 + + + , + + + x1_i + + + is a finite number, and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is greater than + + + 0 + + + , + + + x1_i + + + is a finite number, and + + + x2_i + + + is + + + -infinity + + + , the result is an implementation-dependent approximation to + + + +π + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + , + + + x1_i + + + is a finite number, and + + + x2_i + + + is + + + +infinity + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + , + + + x1_i + + + is a finite number, and + + + x2_i + + + is + + + -infinity + + + , the result is an implementation-dependent approximation to + + + -π + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is finite, the result is an implementation-dependent approximation to + + + +π/2 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is finite, the result is an implementation-dependent approximation to + + + -π/2 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is + + + +infinity + + + , the result is an implementation-dependent approximation to + + + +π/4 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is + + + -infinity + + + , the result is an implementation-dependent approximation to + + + +3π/4 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is + + + +infinity + + + , the result is an implementation-dependent approximation to + + + -π/4 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is + + + -infinity + + + , the result is an implementation-dependent approximation to + + + -3π/4 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + input array corresponding to the y-coordinates. Should have a floating-point data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + input array corresponding to the x-coordinates. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the inverse tangent of the quotient + + + x1/x2 + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ atanh(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the inverse hyperbolic tangent, having domain + + + [-1, + + + +1] + + + and codomain + + + [-infinity, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + -1 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is greater than + + + 1 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -1 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +1 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements each represent the area of a hyperbolic sector. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the inverse hyperbolic tangent of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ bitwise_and(x1, x2, /) + + ¶ + +

+

+ Computes the bitwise AND of the underlying binary representation of each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have an integer or boolean data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have an integer or boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+
+
+ + +

+ bitwise_left_shift(x1, x2, /) + + ¶ + +

+

+ Shifts the bits of each element + + + x1_i + + + of the input array + + + x1 + + + to the left by appending + + + x2_i + + + (i.e., the respective element in the input array + + + x2 + + + ) zeros to the right of + + + x1_i + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have an integer data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have an integer data type. Each element must be greater than or equal to + + + 0 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have the same data type as + + + x1 + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ bitwise_invert(x, /) + + ¶ + +

+

+ Inverts (flips) each bit for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have an integer or boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ bitwise_or(x1, x2, /) + + ¶ + +

+

+ Computes the bitwise OR of the underlying binary representation of each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have an integer or boolean data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have an integer or boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+
+
+ + +

+ bitwise_right_shift(x1, x2, /) + + ¶ + +

+

+ Shifts the bits of each element + + + x1_i + + + of the input array + + + x1 + + + to the right according to the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have an integer data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have an integer data type. Each element must be greater than or equal to + + + 0 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have the same data type as + + + x1 + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ bitwise_xor(x1, x2, /) + + ¶ + +

+

+ Computes the bitwise XOR of the underlying binary representation of each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have an integer or boolean data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have an integer or boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+
+
+ + +

+ ceil(x, /) + + ¶ + +

+

+ Rounds each element + + + x_i + + + of the input array + + + x + + + to the smallest (i.e., closest to + + + -infinity + + + ) integer-valued number that is not less than + + + x_i + + + . +

+
+

+ Special Cases + + ¶ + +

+
    +
  • +

    + If + + + x_i + + + is already integer-valued, the result is + + + x_i + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the rounded result for each element in + + + x + + + . The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ cos(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the cosine, having domain + + + (-infinity, + + + +infinity) + + + and codomain + + + [-1, + + + +1] + + + , for each element + + + x_i + + + of the input array + + + x + + + . Each element + + + x_i + + + is assumed to be expressed in radians. +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements are each expressed in radians. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the cosine of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ cosh(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the hyperbolic cosine, having domain + + + [-infinity, + + + +infinity] + + + and codomain + + + [-infinity, + + + +infinity] + + + , for each element + + + x_i + + + in the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements each represent a hyperbolic angle. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the hyperbolic cosine of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ divide(x1, x2, /) + + ¶ + +

+

+ Calculates the division for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +infinity + + + or + + + -infinity + + + and + + + x2_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +0 + + + or + + + -0 + + + and + + + x2_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is greater than + + + 0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is greater than + + + 0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + and + + + x2_i + + + is + + + +0 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + and + + + x2_i + + + is + + + -0 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is a positive (i.e., greater than + + + 0 + + + ) finite number, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is a negative (i.e., less than + + + 0 + + + ) finite number, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is a positive (i.e., greater than + + + 0 + + + ) finite number, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + and + + + x2_i + + + is a negative (i.e., less than + + + 0 + + + ) finite number, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a positive (i.e., greater than + + + 0 + + + ) finite number and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a positive (i.e., greater than + + + 0 + + + ) finite number and + + + x2_i + + + is + + + -infinity + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a negative (i.e., less than + + + 0 + + + ) finite number and + + + x2_i + + + is + + + +infinity + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is a negative (i.e., less than + + + 0 + + + ) finite number and + + + x2_i + + + is + + + -infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + and + + + x2_i + + + have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. +

    +
  • +
  • +

    + If + + + x1_i + + + and + + + x2_i + + + have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. +

    +
  • +
  • +

    + In the remaining cases, where neither + + + -infinity + + + , + + + +0 + + + , + + + -0 + + + , nor + + + NaN + + + is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an + + + infinity + + + of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + dividend input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + divisor input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ equal(x1, x2, /) + + ¶ + +

+

+ Computes the truth value of + + + x1_i + + + == + + + x2_i + + + for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. May have any data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ exp(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the exponential function, having domain + + + [-infinity, + + + +infinity] + + + and codomain + + + [+0, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + ( + + + e + + + raised to the power of + + + x_i + + + , where + + + e + + + is the base of the natural logarithm). +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + +0 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated exponential function result for each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ expm1(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to + + + exp(x)-1 + + + , having domain + + + [-infinity, + + + +infinity] + + + and codomain + + + [-1, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Note +

+

+ The purpose of this function is to calculate + + + exp(x)-1.0 + + + more accurately when + + + x + + + is close to zero. Accordingly, conforming implementations should avoid implementing this function as simply + + + exp(x)-1.0 + + + . See FDLIBM, or some other IEEE 754-2019 compliant mathematical library, for a potential reference implementation. +

+
+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + -1 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated result for each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ floor(x, /) + + ¶ + +

+

+ Rounds each element + + + x_i + + + of the input array + + + x + + + to the greatest (i.e., closest to + + + +infinity + + + ) integer-valued number that is not greater than + + + x_i + + + . +

+
+

+ Special Cases + + ¶ + +

+
    +
  • +

    + If + + + x_i + + + is already integer-valued, the result is + + + x_i + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the rounded result for each element in + + + x + + + . The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ floor_divide(x1, x2, /) + + ¶ + +

+

+ Rounds the result of dividing each element + + + x1_i + + + of the input array + + + x1 + + + by the respective element + + + x2_i + + + of the input array + + + x2 + + + to the greatest (i.e., closest to + + + +infinity + + + ) integer-value number that is not greater than the division result. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + dividend input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + divisor input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+
+
+ + +

+ greater(x1, x2, /) + + ¶ + +

+

+ Computes the truth value of + + + x1_i + + + > + + + x2_i + + + for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ greater_equal(x1, x2, /) + + ¶ + +

+

+ Computes the truth value of + + + x1_i + + + >= + + + x2_i + + + for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ isfinite(x, /) + + ¶ + +

+

+ Tests each element + + + x_i + + + of the input array + + + x + + + to determine if finite (i.e., not + + + NaN + + + and not equal to positive or negative infinity). +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing test results. An element + + + out_i + + + is + + + True + + + if + + + x_i + + + is finite and + + + False + + + otherwise. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ isinf(x, /) + + ¶ + +

+

+ Tests each element + + + x_i + + + of the input array + + + x + + + to determine if equal to positive or negative infinity. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing test results. An element + + + out_i + + + is + + + True + + + if + + + x_i + + + is either positive or negative infinity and + + + False + + + otherwise. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ isnan(x, /) + + ¶ + +

+

+ Tests each element + + + x_i + + + of the input array + + + x + + + to determine whether the element is + + + NaN + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing test results. An element + + + out_i + + + is + + + True + + + if + + + x_i + + + is + + + NaN + + + and + + + False + + + otherwise. The returned array should have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ less(x1, x2, /) + + ¶ + +

+

+ Computes the truth value of + + + x1_i + + + < + + + x2_i + + + for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ less_equal(x1, x2, /) + + ¶ + +

+

+ Computes the truth value of + + + x1_i + + + <= + + + x2_i + + + for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ log(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the natural (base + + + e + + + ) logarithm, having domain + + + [0, + + + +infinity] + + + and codomain + + + [-infinity, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + 0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + 1 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated natural logarithm for each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ log1p(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to + + + log(1+x) + + + , where + + + log + + + refers to the natural (base + + + e + + + ) logarithm, having domain + + + [-1, + + + +infinity] + + + and codomain + + + [-infinity, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Note +

+

+ The purpose of this function is to calculate + + + log(1+x) + + + more accurately when + + + x + + + is close to zero. Accordingly, conforming implementations should avoid implementing this function as simply + + + log(1+x) + + + . See FDLIBM, or some other IEEE 754-2019 compliant mathematical library, for a potential reference implementation. +

+
+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + -1 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -1 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated result for each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ log2(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the base + + + 2 + + + logarithm, having domain + + + [0, + + + +infinity] + + + and codomain + + + [-infinity, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + 0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + 1 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated base + + + 2 + + + logarithm for each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ log10(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the base + + + 10 + + + logarithm, having domain + + + [0, + + + +infinity] + + + and codomain + + + [-infinity, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + 0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + 1 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated base + + + 10 + + + logarithm for each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ logaddexp(x1, x2) + + ¶ + +

+

+ Calculates the logarithm of the sum of exponentiations + + + log(exp(x1) + + + + + + + exp(x2)) + + + for +each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a floating-point +data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ logical_and(x1, x2, /) + + ¶ + +

+

+ Computes the logical AND for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . Zeros are considered the equivalent of + + + False + + + , while non-zeros are considered the equivalent of + + + True + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a boolean data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ logical_not(x, /) + + ¶ + +

+

+ Computes the logical NOT for each element + + + x_i + + + of the input array + + + x + + + . Zeros are considered the equivalent of + + + False + + + , while non-zeros are considered the equivalent of + + + True + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ logical_or(x1, x2, /) + + ¶ + +

+

+ Computes the logical OR for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . Zeros are considered the equivalent of + + + False + + + , while non-zeros are considered the equivalent of + + + True + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a boolean data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ logical_xor(x1, x2, /) + + ¶ + +

+

+ Computes the logical XOR for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . Zeros are considered the equivalent of + + + False + + + , while non-zeros are considered the equivalent of + + + True + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a boolean data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a boolean data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ multiply(x1, x2, /) + + ¶ + +

+

+ Calculates the product for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If either + + + x1_i + + + or + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +infinity + + + or + + + -infinity + + + and + + + x2_i + + + is either + + + +0 + + + or + + + -0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +0 + + + or + + + -0 + + + and + + + x2_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + and + + + x2_i + + + have the same mathematical sign, the result has a positive mathematical sign, unless the result is + + + NaN + + + . If the result is + + + NaN + + + , the “sign” of + + + NaN + + + is implementation-defined. +

    +
  • +
  • +

    + If + + + x1_i + + + and + + + x2_i + + + have different mathematical signs, the result has a negative mathematical sign, unless the result is + + + NaN + + + . If the result is + + + NaN + + + , the “sign” of + + + NaN + + + is implementation-defined. +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +infinity + + + or + + + -infinity + + + and + + + x2_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is a signed infinity with the mathematical sign determined by the rule already stated above. +

    +
  • +
  • +

    + If + + + x1_i + + + is either + + + +infinity + + + or + + + -infinity + + + and + + + x2_i + + + is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. +

    +
  • +
  • +

    + If + + + x1_i + + + is a nonzero finite number and + + + x2_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is a signed infinity with the mathematical sign determined by the rule already stated above. +

    +
  • +
  • +

    + In the remaining cases, where neither + + + infinity + + + nor + + + NaN + + + is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an + + + infinity + + + of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. +

    +
  • +
+
+

+ Note +

+

+ Floating-point multiplication is not always associative due to finite precision. +

+
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise products. The returned array must have a data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ negative(x, /) + + ¶ + +

+

+ Computes the numerical negative of each element + + + x_i + + + (i.e., + + + y_i + + + = + + + -x_i + + + ) of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated result for each element in + + + x + + + . The returned array must have a data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ not_equal(x1, x2, /) + + ¶ + +

+

+ Computes the truth value of + + + x1_i + + + != + + + x2_i + + + for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. May have any data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    + +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ positive(x, /) + + ¶ + +

+

+ Computes the numerical positive of each element + + + x_i + + + (i.e., + + + y_i + + + = + + + +x_i + + + ) of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated result for each element in + + + x + + + . The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ pow(x1, x2, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation of exponentiation by raising each element + + + x1_i + + + (the base) of the input array + + + x1 + + + to the power of + + + x2_i + + + (the exponent), where + + + x2_i + + + is the corresponding element of the input array + + + x2 + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x1_i + + + is not equal to + + + 1 + + + and + + + x2_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x2_i + + + is + + + +0 + + + , the result is + + + 1 + + + , even if + + + x1_i + + + is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x2_i + + + is + + + -0 + + + , the result is + + + 1 + + + , even if + + + x1_i + + + is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + NaN + + + and + + + x2_i + + + is not equal to + + + 0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is greater than + + + 1 + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is greater than + + + 1 + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is + + + 1 + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is + + + 1 + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + 1 + + + and + + + x2_i + + + is not + + + NaN + + + , the result is + + + 1 + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is less than + + + 1 + + + and + + + x2_i + + + is + + + +infinity + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + abs(x1_i) + + + is less than + + + 1 + + + and + + + x2_i + + + is + + + -infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +infinity + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + , + + + x2_i + + + is greater than + + + 0 + + + , and + + + x2_i + + + is an odd integer value, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + , + + + x2_i + + + is greater than + + + 0 + + + , and + + + x2_i + + + is not an odd integer value, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + , + + + x2_i + + + is less than + + + 0 + + + , and + + + x2_i + + + is an odd integer value, the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -infinity + + + , + + + x2_i + + + is less than + + + 0 + + + , and + + + x2_i + + + is not an odd integer value, the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is greater than + + + 0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + +0 + + + and + + + x2_i + + + is less than + + + 0 + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + , + + + x2_i + + + is greater than + + + 0 + + + , and + + + x2_i + + + is an odd integer value, the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + , + + + x2_i + + + is greater than + + + 0 + + + , and + + + x2_i + + + is not an odd integer value, the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + , + + + x2_i + + + is less than + + + 0 + + + , and + + + x2_i + + + is an odd integer value, the result is + + + -infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is + + + -0 + + + , + + + x2_i + + + is less than + + + 0 + + + , and + + + x2_i + + + is not an odd integer value, the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x1_i + + + is less than + + + 0 + + + , + + + x1_i + + + is a finite number, + + + x2_i + + + is a finite number, and + + + x2_i + + + is not an integer value, the result is + + + NaN + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array whose elements correspond to the exponentiation base. Should have a floating-point data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array whose elements correspond to the exponentiation exponent. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+
+
+ + +

+ remainder(x1, x2, /) + + ¶ + +

+

+ Returns the remainder of division for each element + + + x1_i + + + of the input array + + + x1 + + + and the respective element + + + x2_i + + + of the input array + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + dividend input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + divisor input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise results. Each element-wise result must have the same sign as the respective element + + + x2_i + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ round(x, /) + + ¶ + +

+

+ Rounds each element + + + x_i + + + of the input array + + + x + + + to the nearest integer-valued number. +

+
+

+ Special Cases + + ¶ + +

+
    +
  • +

    + If + + + x_i + + + is already integer-valued, the result is + + + x_i + + + . +

    +
  • +
  • +

    + If two integers are equally close to + + + x_i + + + , the result is the even integer closest to + + + x_i + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the rounded result for each element in + + + x + + + . The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ sign(x, /) + + ¶ + +

+

+ Returns an indication of the sign of a number for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+
    +
  • +

    + If + + + x_i + + + is less than + + + 0 + + + , the result is + + + -1 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is either + + + -0 + + + or + + + +0 + + + , the result is + + + 0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is greater than + + + 0 + + + , the result is + + + +1 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated result for each element in + + + x + + + . The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ sin(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the sine, having domain + + + (-infinity, + + + +infinity) + + + and codomain + + + [-1, + + + +1] + + + , for each element + + + x_i + + + of the input array + + + x + + + . Each element + + + x_i + + + is assumed to be expressed in radians. +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements are each expressed in radians. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the sine of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ sinh(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the hyperbolic sine, having domain + + + [-infinity, + + + +infinity] + + + and codomain + + + [-infinity, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + -infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements each represent a hyperbolic angle. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the hyperbolic sine of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ square(x, /) + + ¶ + +

+

+ Squares ( + + + x_i + + + * + + + x_i + + + ) each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the evaluated result for each element in + + + x + + + . The returned array must have a data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ sqrt(x, /) + + ¶ + +

+

+ Calculates the square root, having domain + + + [0, + + + +infinity] + + + and codomain + + + [0, + + + +infinity] + + + , for each element + + + x_i + + + of the input array + + + x + + + . After rounding, each result must be indistinguishable from the infinitely precise result (as required by IEEE 754). +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is less than + + + 0 + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +infinity + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the square root of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ subtract(x1, x2, /) + + ¶ + +

+

+ Calculates the difference for each element + + + x1_i + + + of the input array + + + x1 + + + with the respective element + + + x2_i + + + of the input array + + + x2 + + + . The result of + + + x1_i + + + - + + + x2_i + + + must be the same as + + + x1_i + + + + + + + (-x2_i) + + + and must be governed by the same floating-point rules as addition (see + + + + + add() + + + + + ). +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + x1 + + + (see + + + Broadcasting + + + ). Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the element-wise differences. The returned array must have a data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ tan(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the tangent, having domain + + + (-infinity, + + + +infinity) + + + and codomain + + + (-infinity, + + + +infinity) + + + , for each element + + + x_i + + + of the input array + + + x + + + . Each element + + + x_i + + + is assumed to be expressed in radians. +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is either + + + +infinity + + + or + + + -infinity + + + , the result is + + + NaN + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements are expressed in radians. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the tangent of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ tanh(x, /) + + ¶ + +

+

+ Calculates an implementation-dependent approximation to the hyperbolic tangent, having domain + + + [-infinity, + + + +infinity] + + + and codomain + + + [-1, + + + +1] + + + , for each element + + + x_i + + + of the input array + + + x + + + . +

+
+

+ Special Cases + + ¶ + +

+

+ For floating-point operands, +

+
    +
  • +

    + If + + + x_i + + + is + + + NaN + + + , the result is + + + NaN + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +0 + + + , the result is + + + +0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -0 + + + , the result is + + + -0 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + +infinity + + + , the result is + + + +1 + + + . +

    +
  • +
  • +

    + If + + + x_i + + + is + + + -infinity + + + , the result is + + + -1 + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array whose elements each represent a hyperbolic angle. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the hyperbolic tangent of each element in + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ trunc(x, /) + + ¶ + +

+

+ Rounds each element + + + x_i + + + of the input array + + + x + + + to the integer-valued number that is closest to but no greater than + + + x_i + + + . +

+
+

+ Special Cases + + ¶ + +

+
    +
  • +

    + If + + + x_i + + + is already integer-valued, the result is + + + x_i + + + . +

    +
  • +
+
+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the rounded result for each element in + + + x + + + . The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/function_and_method_signatures.html b/latest/API_specification/function_and_method_signatures.html new file mode 100644 index 000000000..08f7a914a --- /dev/null +++ b/latest/API_specification/function_and_method_signatures.html @@ -0,0 +1,577 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Function and method signatures — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +

+ Function and method signatures + + ¶ + +

+

+ Function signatures in this standard adhere to the following: +

+
    +
  1. +

    + Positional parameters must be + + positional-only + + parameters. +Positional-only parameters have no externally-usable name. When a function +accepting positional-only parameters is called, positional arguments are +mapped to these parameters based solely on their order. +

    +

    + + Rationale: existing libraries have incompatible conventions, and using names +of positional parameters is not normal/recommended practice. + +

    +
    +

    + Note +

    +

    + Positional-only parameters are only available in Python >= 3.8. Libraries +still supporting 3.7 or 3.6 may consider making the API standard-compliant +namespace >= 3.8. Alternatively, they can add guidance to their users in the +documentation to use the functions as if they were positional-only. +

    +
    +
  2. +
  3. +

    + Optional parameters must be + + keyword-only + + arguments. +

    +

    + + Rationale: this leads to more readable code, and it makes it easier to +evolve an API over time by adding keywords without having to worry about +keyword order. + +

    +
  4. +
  5. +

    + For functions that have a single positional array parameter, that parameter +is called + + + x + + + . For functions that have multiple array parameters, those +parameters are called + + + xi + + + with + + + i + + + = + + + 1, + + + 2, + + + ... + + + (i.e., + + + x1 + + + , + + + x2 + + + ). +

    +
  6. +
  7. +

    + Type annotations are left out of the signatures themselves for readability; however, +they are added to individual parameter descriptions. For code which aims to +adhere to the standard, adding type annotations is strongly recommended. +

    +
  8. +
+

+ A function signature and description will look like: +

+
+
+
funcname(x1, x2, /, *, key1=-1, key2=None)
+
+    Parameters
+
+    x1 : array
+        description
+    x2 : array
+        description
+    key1 : int
+        description
+    key2 : Optional[str]
+        description
+
+    Returns
+
+    out : array
+        description
+
+
+
+

+ Method signatures will follow the same conventions modulo the addition of + + + self + + + . +

+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/index.html b/latest/API_specification/index.html new file mode 100644 index 000000000..86b94aab2 --- /dev/null +++ b/latest/API_specification/index.html @@ -0,0 +1,1629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + API specification — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +

+ API specification + + ¶ + +

+
+

+ + API specification + +

+ +
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/indexing.html b/latest/API_specification/indexing.html new file mode 100644 index 000000000..618815090 --- /dev/null +++ b/latest/API_specification/indexing.html @@ -0,0 +1,2062 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Indexing — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Indexing + + ¶ + +

+
+
+

+ Array API specification for indexing arrays. +

+
+
+

+ A conforming implementation of the array API standard must adhere to the following conventions. +

+
+

+ Single-axis Indexing + + ¶ + +

+

+ To index a single array axis, an array must support standard Python indexing rules. Let + + + n + + + be the axis (dimension) size. +

+
    +
  • +

    + An integer index must be an object satisfying + + + + operator.index + + + + (e.g., + + + int + + + ). +

    +
  • +
  • +

    + Nonnegative indices must start at + + + 0 + + + (i.e., zero-based indexing). +

    +
  • +
  • +

    + + Valid + + nonnegative indices must reside on the half-open interval + + + [0, + + + n) + + + . +

    +
    +

    + Note +

    +

    + This specification does not require bounds checking. The behavior for out-of-bounds integer indices is left unspecified. +

    +
    +
  • +
  • +

    + Negative indices must count backward from the last array index, starting from + + + -1 + + + (i.e., negative-one-based indexing, where + + + -1 + + + refers to the last array index). +

    +
    +

    + Note +

    +

    + A negative index + + + j + + + is equivalent to + + + n-j + + + ; the former is syntactic sugar for the latter, providing a shorthand for indexing elements that would otherwise need to be specified in terms of the axis (dimension) size. +

    +
    +
  • +
  • +

    + + Valid + + negative indices must reside on the closed interval + + + [-n, + + + -1] + + + . +

    +
    +

    + Note +

    +

    + This specification does not require bounds checking. The behavior for out-of-bounds integer indices is left unspecified. +

    +
    +
  • +
  • +

    + A negative index + + + j + + + is related to a zero-based nonnegative index + + + i + + + via + + + i + + + = + + + n+j + + + . +

    +
  • +
  • +

    + Colons + + + : + + + must be used for + + slices + + : + + + start:stop:step + + + , where + + + start + + + is inclusive and + + + stop + + + is exclusive. +

    +
  • +
+
+

+ Slice Syntax + + ¶ + +

+

+ The basic slice syntax is + + + i:j:k + + + where + + + i + + + is the starting index, + + + j + + + is the stopping index, and + + + k + + + is the step ( + + + k + + + != + + + 0 + + + ). A slice may contain either one or two colons, with either an integer value or nothing on either side of each colon. The following are valid slices. +

+
+
+
A[:]
+A[i:]
+A[:j]
+A[i:k]
+A[::]
+A[i::]
+A[:j:]
+A[::k]
+A[i:j:]
+A[i::k]
+A[:j:k]
+A[i::k]
+A[i:j:k]
+
+
+
+
+

+ Note +

+

+ Slice syntax can be equivalently achieved using the Python built-in + + + + slice() + + + + API. From the perspective of + + + A + + + , the behavior of + + + A[i:j:k] + + + and + + + A[slice(i, + + + j, + + + k)] + + + is indistinguishable (i.e., both retrieve the same set of items from + + + __getitem__ + + + ). +

+
+

+ Using a slice to index a single array axis must select + + + m + + + elements with index values +

+
+
+
i, i+k, i+2k, i+3k, ..., i+(m-1)k
+
+
+
+

+ where +

+
+
+
m = q + r
+
+
+
+

+ and + + + q + + + and + + + r + + + ( + + + r + + + != + + + 0 + + + ) are the quotient and remainder obtained by dividing + + + j-i + + + by + + + k + + +

+
+
+
j - i = qk + r
+
+
+
+

+ such that +

+
+
+
j > i + (m-1)k
+
+
+
+
+

+ Note +

+

+ For + + + i + + + on the interval + + + [0, + + + n) + + + (where + + + n + + + is the axis size), + + + j + + + on the interval + + + (0, + + + n] + + + , + + + i + + + less than + + + j + + + , and positive step + + + k + + + , a starting index + + + i + + + is + + always + + included, while the stopping index + + + j + + + is + + always + + excluded. This preserves + + + x[:i]+x[i:] + + + always being equal to + + + x + + + . +

+
+
+

+ Note +

+

+ Using a slice to index into a single array axis should select the same elements as using a slice to index a Python list of the same size. +

+
+

+ Slice syntax must have the following defaults. Let + + + n + + + be the axis (dimension) size. +

+
    +
  • +

    + If + + + k + + + is not provided (e.g., + + + 0:10 + + + ), + + + k + + + must equal + + + 1 + + + . +

    +
  • +
  • +

    + If + + + k + + + is greater than + + + 0 + + + and + + + i + + + is not provided (e.g., + + + :10:2 + + + ), + + + i + + + must equal + + + 0 + + + . +

    +
  • +
  • +

    + If + + + k + + + is greater than + + + 0 + + + and + + + j + + + is not provided (e.g., + + + 0::2 + + + ), + + + j + + + must equal + + + n + + + . +

    +
  • +
  • +

    + If + + + k + + + is less than + + + 0 + + + and + + + i + + + is not provided (e.g., + + + :10:-2 + + + ), + + + i + + + must equal + + + n-1 + + + . +

    +
  • +
  • +

    + If + + + k + + + is less than + + + 0 + + + and + + + j + + + is not provided (e.g., + + + 0::-2 + + + ), + + + j + + + must equal + + + -n-1 + + + . +

    +
  • +
+

+ Using a slice to index a single array axis must adhere to the following rules. Let + + + n + + + be the axis (dimension) size. +

+
    +
  • +

    + If + + + i + + + equals + + + j + + + , a slice must return an empty array, whose axis (dimension) size along the indexed axis is + + + 0 + + + . +

    +
  • +
  • +

    + Indexing via + + + : + + + and + + + :: + + + must be equivalent and have defaults derived from the rules above. Both + + + : + + + and + + + :: + + + indicate to select all elements along a single axis (dimension). +

    +
  • +
+
+

+ Note +

+

+ This specification does not require “clipping” out-of-bounds indices (i.e., requiring the starting and stopping indices + + + i + + + and + + + j + + + be bound by + + + 0 + + + and + + + n + + + , respectively). +

+

+ + Rationale: this is consistent with bounds checking for integer indexing; the behavior of out-of-bounds indices is left unspecified. Implementations may choose to clip, raise an exception, return junk values, or some other behavior depending on device requirements and performance considerations. + +

+
+
+

+ Note +

+

+ This specification leaves unspecified the behavior of indexing a single array axis with an out-of-bounds slice (i.e., a slice which does not select any array axis elements). +

+

+ + Rationale: this is consistent with bounds checking for integer indexing; the behavior of out-of-bounds indices is left unspecified. Implementations may choose to return an empty array (whose axis (dimension) size along the indexed axis is + + + 0 + + + ), raise an exception, or some other behavior depending on device requirements and performance considerations. + +

+
+
+
+
+

+ Multi-axis Indexing + + ¶ + +

+

+ Multi-dimensional arrays must extend the concept of single-axis indexing to multiple axes by applying single-axis indexing rules along each axis (dimension) and supporting the following additional rules. Let + + + N + + + be the number of dimensions (“rank”) of a multi-dimensional array + + + A + + + . +

+
    +
  • +

    + Each axis may be independently indexed via single-axis indexing by providing a comma-separated sequence (“selection tuple”) of single-axis indexing expressions (e.g., + + + A[:, + + + 2:10, + + + :, + + + 5] + + + ). +

    +
    +

    + Note +

    +

    + In Python, + + + x[(exp1, + + + exp2, + + + ..., + + + expN)] + + + is equivalent to + + + x[exp1, + + + exp2, + + + ..., + + + expN] + + + ; the latter is syntactic sugar for the former. +

    +
    +
  • +
  • +

    + Providing a single nonnegative integer + + + i + + + as a single-axis index must index the same elements as the slice + + + i:i+1 + + + . +

    +
  • +
  • +

    + Providing a single negative integer + + + i + + + as a single-axis index must index the same elements as the slice + + + n+i:n+i+1 + + + , where + + + n + + + is the axis (dimension) size. +

    +
  • +
  • +

    + Providing a single integer as a single-axis index must reduce the number of array dimensions by + + + 1 + + + (i.e., the array rank should decrease by one; if + + + A + + + has rank + + + 2 + + + , + + + rank(A)-1 + + + == + + + rank(A[0, + + + :]) + + + ). In particular, a selection tuple with the + + + m + + + th element an integer (and all other entries + + + : + + + ) indexes a sub-array with rank + + + N-1 + + + . +

    +
  • +
  • +

    + Providing a slice must retain array dimensions (i.e., the array rank must remain the same; + + + rank(A) + + + == + + + rank(A[:]) + + + ). +

    +
  • +
  • +

    + If the number of provided single-axis indexing expressions is less than + + + N + + + , then + + + : + + + must be assumed for the remaining dimensions (e.g., if + + + A + + + has rank + + + 2 + + + , + + + A[2:10] + + + == + + + A[2:10, + + + :] + + + ). +

    +
  • +
  • +

    + An + + + IndexError + + + exception must be raised if the number of provided single-axis indexing expressions is greater than + + + N + + + . +

    +
  • +
  • +

    + Providing + + ellipsis + + must apply + + + : + + + to each dimension necessary to index all dimensions (e.g., if + + + A + + + has rank + + + 4 + + + , + + + A[1:, + + + ..., + + + 2:5] + + + == + + + A[1:, + + + :, + + + :, + + + 2:5] + + + ). Only a single ellipsis must be allowed. An + + + IndexError + + + exception must be raised if more than one ellipsis is provided. +

    +
  • +
+
+

+ Note +

+

+ This specification leaves unspecified the behavior of providing a slice which attempts to select elements along a particular axis, but whose starting index is out-of-bounds. +

+

+ + Rationale: this is consistent with bounds-checking for single-axis indexing. An implementation may choose to set the axis (dimension) size of the result array to + + + 0 + + + , raise an exception, return junk values, or some other behavior depending on device requirements and performance considerations. + +

+
+
+
+

+ Boolean Array Indexing + + ¶ + +

+

+ An array must support indexing via a + + single + + + + M + + + -dimensional boolean array + + + B + + + with shape + + + S1 + + + = + + + (s1, + + + ..., + + + sM) + + + according to the following rules. Let + + + A + + + be an + + + N + + + -dimensional array with shape + + + S2 + + + = + + + (s1, + + + ..., + + + sM, + + + ..., + + + sN) + + + . +

+
    +
  • +

    + If + + + N + + + >= + + + M + + + , then + + + A[B] + + + must replace the first + + + M + + + dimensions of + + + A + + + with a single dimension having a size equal to the number of + + + True + + + elements in + + + B + + + . The values in the resulting array must be in row-major (C-style order); this is equivalent to + + + A[nonzero(B)] + + + . +

    +
    +

    + Note +

    +

    + For example, if + + + N + + + == + + + M + + + == + + + 2 + + + , indexing + + + A + + + via a boolean array + + + B + + + will return a one-dimensional array whose size is equal to the number of + + + True + + + elements in + + + B + + + . +

    +
    +
  • +
  • +

    + If + + + N + + + < + + + M + + + , then an + + + IndexError + + + exception must be raised. +

    +
  • +
  • +

    + The size of each dimension in + + + B + + + must equal the size of the corresponding dimension in + + + A + + + or be + + + 0 + + + , beginning with the first dimension in + + + A + + + . If a dimension size does not equal the size of the corresponding dimension in + + + A + + + and is not + + + 0 + + + , then an + + + IndexError + + + exception must be raised. +

    +
  • +
  • +

    + The elements of a boolean index array must be iterated in row-major, C-style order, with the exception of zero-dimensional boolean arrays. +

    +
  • +
  • +

    + A zero-dimensional boolean index array (equivalent to + + + True + + + or + + + False + + + ) must follow the same axis replacement rules stated above. Namely, a zero-dimensional boolean index array removes zero dimensions and adds a single dimension of length + + + 1 + + + if the index array’s value is + + + True + + + and of length + + + 0 + + + if the index array’s value is + + + False + + + . Accordingly, for a zero-dimensional boolean index array + + + B + + + , the result of + + + A[B] + + + has shape + + + S + + + = + + + (1, + + + s1, + + + ..., + + + sN) + + + if the index array’s value is + + + True + + + and has shape + + + S + + + = + + + (0, + + + s1, + + + ..., + + + sN) + + + if the index array’s value is + + + False + + + . +

    +
  • +
+
+
+

+ Return Values + + ¶ + +

+

+ The result of an indexing operation (e.g., multi-axis indexing, boolean array indexing, etc) must be an array of the same data type as the indexed array. +

+
+

+ Note +

+

+ The specified return value behavior includes indexing operations which return a single value (e.g., accessing a single element within a one-dimensional array). +

+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/linear_algebra_functions.html b/latest/API_specification/linear_algebra_functions.html new file mode 100644 index 000000000..ec912df6a --- /dev/null +++ b/latest/API_specification/linear_algebra_functions.html @@ -0,0 +1,2723 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Linear Algebra Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+

+ Linear Algebra Functions + + ¶ + +

+
+
+

+ Array API specification for linear algebra functions. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Broadcasting semantics must follow the semantics defined in + + + Broadcasting + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must support the data types defined in + + + Data Types + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must adhere to the type promotion rules defined in + + + Type Promotion Rules + + + . +

    +
  • +
  • +

    + Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ cholesky() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ cross(x1, x2, /, *, axis=-1) + + ¶ + +

+

+ Returns the cross product of 3-element vectors. If + + + x1 + + + and + + + x2 + + + are multi-dimensional arrays (i.e., both have a rank greater than + + + 1 + + + ), then the cross-product of each pair of corresponding 3-element vectors is independently computed. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must have the same shape as + + + x1 + + + . Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + int + +

    +
      +
    • +

      + the axis (dimension) of + + + x1 + + + and + + + x2 + + + containing the vectors for which to compute the cross product. If set to + + + -1 + + + , the function computes the cross product for vectors defined by the last axis (dimension). Default: + + + -1 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    + +
  • +
+
+
+
+ + +

+ det(x, /) + + ¶ + +

+

+ Returns the determinant of a square matrix (or stack of square matrices) + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array having shape + + + (..., + + + M, + + + M) + + + and whose innermost two dimensions form square matrices. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if + + + x + + + is a two-dimensional array, a zero-dimensional array containing the determinant; otherwise, a non-zero dimensional array containing the determinant for each square matrix. The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ diagonal(x, /, *, axis1=0, axis2=1, offset=0) + + ¶ + +

+

+ Returns the specified diagonals. If + + + x + + + has more than two dimensions, then the axes (dimensions) specified by + + + axis1 + + + and + + + axis2 + + + are used to determine the two-dimensional sub-arrays from which to return diagonals. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Must have at least + + + 2 + + + dimensions. +

      +
    • +
    +
  • +
  • +

    + + axis1 + + : + + int + +

    +
      +
    • +

      + first axis (dimension) with respect to which to take diagonal. Default: + + + 0 + + + . +

      +
    • +
    +
  • +
  • +

    + + axis2 + + : + + int + +

    +
      +
    • +

      + second axis (dimension) with respect to which to take diagonal. Default: + + + 1 + + + . +

      +
    • +
    +
  • +
  • +

    + + offset + + : + + int + +

    +
      +
    • +

      + offset specifying the off-diagonal relative to the main diagonal. +

      +
        +
      • +

        + + + offset + + + = + + + 0 + + + : the main diagonal. +

        +
      • +
      • +

        + + + offset + + + > + + + 0 + + + : off-diagonal above the main diagonal. +

        +
      • +
      • +

        + + + offset + + + < + + + 0 + + + : off-diagonal below the main diagonal. +

        +
      • +
      +

      + Default: + + + 0 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if + + + x + + + is a two-dimensional array, a one-dimensional array containing the diagonal; otherwise, a multi-dimensional array containing the diagonals and whose shape is determined by removing + + + axis1 + + + and + + + axis2 + + + and appending a dimension equal to the size of the resulting diagonals. The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ dot() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ eig() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ eigvalsh() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ einsum() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ inv(x, /) + + ¶ + +

+

+ Computes the multiplicative inverse of a square matrix (or a stack of square matrices) + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array having shape + + + (..., + + + M, + + + M) + + + and whose innermost two dimensions form square matrices. Should have a floating-point data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the multiplicative inverses. The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + and must have the same shape as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ lstsq() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ matmul() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ matrix_power() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ matrix_rank() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ norm(x, /, *, axis=None, keepdims=False, ord=None) + + ¶ + +

+

+ Computes the matrix or vector norm of + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Should have a floating-point data type. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, int ] ] ] + +

    +
      +
    • +

      + If an integer, + + + axis + + + specifies the axis (dimension) along which to compute vector norms. +

      +

      + If a 2-tuple, + + + axis + + + specifies the axes (dimensions) defining two-dimensional matrices for which to compute matrix norms. +

      +

      + If + + + None + + + , +

      +
        +
      • +

        + if + + + x + + + is one-dimensional, the function must compute the vector norm. +

        +
      • +
      • +

        + if + + + x + + + is two-dimensional, the function must compute the matrix norm. +

        +
      • +
      • +

        + if + + + x + + + has more than two dimensions, the function must compute the vector norm over all array values (i.e., equivalent to computing the vector norm of a flattened array). +

        +
      • +
      +

      + Negative indices must be supported. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the axes (dimensions) specified by + + + axis + + + must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the axes (dimensions) specified by + + + axis + + + must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
  • +

    + + ord + + : + + Optional[ Union[ int, float, Literal[ inf, -inf, ‘fro’, ‘nuc’ ] ] ] + +

    +
      +
    • +

      + order of the norm. The following mathematical norms must be supported: +

      +
    • +
    +
  • +
+
    | ord              | matrix                          | vector                     |
+    | ---------------- | ------------------------------- | -------------------------- |
+    | 'fro'            | 'fro'                           | -                          |
+    | 'nuc'            | 'nuc'                           | -                          |
+    | 1                | max(sum(abs(x), axis=0))        | L1-norm (Manhattan)        |
+    | 2                | largest singular value          | L2-norm (Euclidean)        |
+    | inf              | max(sum(abs(x), axis=1))        | infinity norm              |
+    | (int,float >= 1) | -                               | p-norm                     |
+
+
+
+
    The following non-mathematical "norms" must be supported:
+
+
+
+
    | ord              | matrix                          | vector                         |
+    | ---------------- | ------------------------------- | ------------------------------ |
+    | 0                | -                               | sum(a != 0)                    |
+    | -1               | min(sum(abs(x), axis=0))        | 1./sum(1./abs(a))              |
+    | -2               | smallest singular value         | 1./sqrt(sum(1./abs(a)\*\*2))   |
+    | -inf             | min(sum(abs(x), axis=1))        | min(abs(a))                    |
+    | (int,float < 1)  | -                               | sum(abs(a)\*\*ord)\*\*(1./ord) |
+
+
+
+
    When `ord` is `None`, the following norms must be the default norms:
+
+
+
+
    | ord              | matrix                          | vector                     |
+    | ---------------- | ------------------------------- | -------------------------- |
+    | None             | 'fro'                           | L2-norm (Euclidean)        |
+
+
+
+
    where `fro` corresponds to the **Frobenius norm**, `nuc` corresponds to the **nuclear norm**, and `-` indicates that the norm is **not** supported.
+
+    For matrices,
+
+    -   if `ord=1`, the norm corresponds to the induced matrix norm where `p=1` (i.e., the maximum absolute value column sum).
+    -   if `ord=2`, the norm corresponds to the induced matrix norm where `p=inf` (i.e., the maximum absolute value row sum).
+    -   if `ord=inf`, the norm corresponds to the induced matrix norm where `p=2` (i.e., the largest singular value).
+
+    If `None`,
+
+    -   if matrix (or matrices), the function must compute the Frobenius norm.
+    -   if vector (or vectors), the function must compute the L2-norm (Euclidean norm).
+
+    Default: `None`.
+
+
+
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the norms. If + + + axis + + + is + + + None + + + , the returned array must be a zero-dimensional array containing a vector norm. If + + + axis + + + is a scalar value ( + + + int + + + or + + + float + + + ), the returned array must have a rank which is one less than the rank of + + + x + + + . If + + + axis + + + is a 2-tuple, the returned array must have a rank which is two less than the rank of + + + x + + + . The returned array must have a floating-point data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ outer(x1, x2, /) + + ¶ + +

+

+ Computes the outer product of two vectors + + + x1 + + + and + + + x2 + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first one-dimensional input array of size + + + N + + + . Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second one-dimensional input array of size + + + M + + + . Should have a numeric data type. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + a two-dimensional array containing the outer product and whose shape is + + + (N, + + + M) + + + . The returned array must have a data type determined by + + + Type Promotion Rules + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ pinv() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ qr() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ slogdet() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ solve() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ svd() + + ¶ + +

+

+ TODO +

+
+
+ + +

+ trace(x, /, *, axis1=0, axis2=1, offset=0) + + ¶ + +

+

+ Returns the sum along the specified diagonals. If + + + x + + + has more than two dimensions, then the axes (dimensions) specified by + + + axis1 + + + and + + + axis2 + + + are used to determine the two-dimensional sub-arrays for which to compute the trace. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Must have at least + + + 2 + + + dimensions. Should have a numeric data type. +

      +
    • +
    +
  • +
  • +

    + + axis1 + + : + + int + +

    +
      +
    • +

      + first axis (dimension) with respect to which to compute the trace. Default: + + + 0 + + + . +

      +
    • +
    +
  • +
  • +

    + + axis2 + + : + + int + +

    +
      +
    • +

      + second axis (dimension) with respect to which to compute the trace. Default: + + + 1 + + + . +

      +
    • +
    +
  • +
  • +

    + + offset + + : + + int + +

    +
      +
    • +

      + offset specifying the off-diagonal relative to the main diagonal. +

      +
        +
      • +

        + + + offset + + + = + + + 0 + + + : the main diagonal. +

        +
      • +
      • +

        + + + offset + + + > + + + 0 + + + : off-diagonal above the main diagonal. +

        +
      • +
      • +

        + + + offset + + + < + + + 0 + + + : off-diagonal below the main diagonal. +

        +
      • +
      +

      + Default: + + + 0 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if + + + x + + + is a two-dimensional array, the returned array must be a zero-dimensional array containing the trace; otherwise, the returned array must be a multi-dimensional array containing the traces. +

      +

      + The shape of a multi-dimensional output array is determined by removing + + + axis1 + + + and + + + axis2 + + + and storing the traces in the last array dimension. For example, if + + + x + + + has rank + + + k + + + and shape + + + (I, + + + J, + + + K, + + + ..., + + + L, + + + M, + + + N) + + + and + + + axis1=-2 + + + and + + + axis1=-1 + + + , then a multi-dimensional output array has rank + + + k-2 + + + and shape + + + (I, + + + J, + + + K, + + + ..., + + + L) + + + where +

      +
      +
      +
      out[i, j, k, ..., l] = trace(a[i, j, k, ..., l, :, :])
      +
      +
      +
      +

      + The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ transpose(x, /, *, axes=None) + + ¶ + +

+

+ Transposes (or permutes the axes (dimensions)) of an array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axes + + : + + Optional[ Tuple[ int, … ] ] + +

    +
      +
    • +

      + tuple containing a permutation of + + + (0, + + + 1, + + + ..., + + + N-1) + + + where + + + N + + + is the number of axes (dimensions) of + + + x + + + . If + + + None + + + , the axes (dimensions) must be permuted in reverse order (i.e., equivalent to setting + + + axes=(N-1, + + + ..., + + + 1, + + + 0) + + + ). Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array containing the transpose. The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/manipulation_functions.html b/latest/API_specification/manipulation_functions.html new file mode 100644 index 000000000..bc8406a77 --- /dev/null +++ b/latest/API_specification/manipulation_functions.html @@ -0,0 +1,1865 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Manipulation Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+

+ Manipulation Functions + + ¶ + +

+
+
+

+ Array API specification for manipulating arrays. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Unless stated otherwise, functions must adhere to the type promotion rules defined in + + + Type Promotion Rules + + + . +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ concat(arrays, /, *, axis=0) + + ¶ + +

+

+ Joins a sequence of arrays along an existing axis. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + arrays + + : + + Tuple[ <array>, … ] + +

    +
      +
    • +

      + input arrays to join. The arrays must have the same shape, except in the dimension specified by + + + axis + + + . +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ int ] + +

    +
      +
    • +

      + axis along which the arrays will be joined. If + + + axis + + + is + + + None + + + , arrays must be flattened before concatenation. If + + + axis + + + is negative, the function must determine the axis along which to join by counting from the last dimension. Default: + + + 0 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an output array containing the concatenated values. If the input arrays have different data types, normal + + + type promotion rules + + + must apply. If the input arrays have the same data type, the output array must have the same data type as the input arrays. +

      +
      +

      + Note +

      +

      + This specification leaves type promotion between data type families (i.e., + + + intxx + + + and + + + floatxx + + + ) unspecified. +

      +
      +
    • +
    +
  • +
+
+
+
+ + +

+ expand_dims(x, axis, /) + + ¶ + +

+

+ Expands the shape of an array by inserting a new axis (dimension) of size one at the position specified by + + + axis + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + int + +

    +
      +
    • +

      + axis position. Must follow Python’s indexing rules: zero-based and negative indices must be counted backward from the last dimension. If + + + x + + + has rank + + + N + + + , a valid + + + axis + + + must reside on the interval + + + [-N-1, + + + N+1] + + + . An + + + IndexError + + + exception must be raised if provided an invalid + + + axis + + + position. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an expanded output array having the same data type and shape as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ flip(x, /, *, axis=None) + + ¶ + +

+

+ Reverses the order of elements in an array along the given axis. The shape of the array must be preserved. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis (or axes) along which to flip. If + + + axis + + + is + + + None + + + , the function must flip all input array axes. If + + + axis + + + is negative, the function must count from the last dimension. If provided more than one axis, the function must flip only the specified axes. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an output array having the same data type and shape as + + + x + + + and whose elements, relative to + + + x + + + , are reordered. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ reshape(x, shape, /) + + ¶ + +

+

+ Reshapes an array without changing its data. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array to reshape. +

      +
    • +
    +
  • +
  • +

    + + shape + + : + + Tuple[ int, … ] + +

    +
      +
    • +

      + a new shape compatible with the original shape. One shape dimension is allowed to be + + + -1 + + + . When a shape dimension is + + + -1 + + + , the corresponding output array shape dimension must be inferred from the length of the array and the remaining dimensions. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an output array having the same data type, elements, and underlying element order as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ roll(x, shift, /, *, axis=None) + + ¶ + +

+

+ Rolls array elements along a specified axis. Array elements that roll beyond the last position are re-introduced at the first position. Array elements that roll beyond the first position are re-introduced at the last position. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + shift + + : + + Union[ int, Tuple[ int, … ] ] + +

    +
      +
    • +

      + number of places by which the elements are shifted. If + + + shift + + + is a tuple, then + + + axis + + + must be a tuple of the same size, and each of the given axes must be shifted by the corresponding element in + + + shift + + + . If + + + shift + + + is an + + + int + + + and + + + axis + + + a tuple, then the same + + + shift + + + must be used for all specified axes. If a shift is positive, then array elements must be shifted positively (toward larger indices) along the dimension of + + + axis + + + . If a shift is negative, then array elements must be shifted negatively (toward smaller indices) along the dimension of + + + axis + + + . +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis (or axes) along which elements to shift. If + + + axis + + + is + + + None + + + , the array must be flattened, shifted, and then restored to its original shape. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an output array having the same data type as + + + x + + + and whose elements, relative to + + + x + + + , are shifted. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ squeeze(x, /, *, axis=None) + + ¶ + +

+

+ Removes singleton dimensions (axes) from + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis (or axes) to squeeze. If provided, only the specified axes must be squeezed. If + + + axis + + + is + + + None + + + , all singleton dimensions (axes) must be removed. If a specified axis has a size greater than one, the specified axis must be left unchanged. Default: + + + None + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an output array having the same data type and elements as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ stack(arrays, /, *, axis=0) + + ¶ + +

+

+ Joins a sequence of arrays along a new axis. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + arrays + + : + + Tuple[ <array>, … ] + +

    +
      +
    • +

      + input arrays to join. Each array must have the same shape. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + int + +

    +
      +
    • +

      + axis along which the arrays will be joined. Providing an + + + axis + + + specifies the index of the new axis in the dimensions of the result. For example, if + + + axis + + + is + + + 0 + + + , the new axis will be the first dimension and the output array will have shape + + + (N, + + + A, + + + B, + + + C) + + + ; if + + + axis + + + is + + + 1 + + + , the new axis will be the second dimension and the output array will have shape + + + (A, + + + N, + + + B, + + + C) + + + ; and, if + + + axis + + + is + + + -1 + + + , the new axis will be the last dimension and the output array will have shape + + + (A, + + + B, + + + C, + + + N) + + + . A valid + + + axis + + + must be on the interval + + + [-N, + + + N) + + + , where + + + N + + + is the rank (number of dimensions) of + + + x + + + . If provided an + + + axis + + + outside of the required interval, the function must raise an exception. Default: + + + 0 + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an output array having rank + + + N+1 + + + , where + + + N + + + is the rank (number of dimensions) of + + + x + + + . If the input arrays have different data types, normal + + + type promotion rules + + + must apply. If the input arrays have the same data type, the output array must have the same data type as the input arrays. +

      +
      +

      + Note +

      +

      + This specification leaves type promotion between data type families (i.e., + + + intxx + + + and + + + floatxx + + + ) unspecified. +

      +
      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/searching_functions.html b/latest/API_specification/searching_functions.html new file mode 100644 index 000000000..86f45b101 --- /dev/null +++ b/latest/API_specification/searching_functions.html @@ -0,0 +1,1333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Searching Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Searching Functions + + ¶ + +

+
+
+

+ Array API specification for functions for searching arrays. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Broadcasting semantics must follow the semantics defined in + + + Broadcasting + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must support the data types defined in + + + Data Types + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must adhere to the type promotion rules defined in + + + Type Promotion Rules + + + . +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ argmax(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Returns the indices of the maximum values along a specified axis. When the maximum value occurs multiple times, only the indices corresponding to the first occurrence are returned. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + int + +

    +
      +
    • +

      + axis along which to search. If + + + None + + + , the function must return the index of the maximum value of the flattened array. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if + + + axis + + + is + + + None + + + , a zero-dimensional array containing the index of the first occurrence of the maximum value; otherwise, a non-zero-dimensional array containing the indices of the maximum values. The returned array must have be the default array index data type. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ argmin(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Returns the indices of the minimum values along a specified axis. When the minimum value occurs multiple times, only the indices corresponding to the first occurrence are returned. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + int + +

    +
      +
    • +

      + axis along which to search. If + + + None + + + , the function must return the index of the minimum value of the flattened array. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if + + + axis + + + is + + + None + + + , a zero-dimensional array containing the index of the first occurrence of the minimum value; otherwise, a non-zero-dimensional array containing the indices of the minimum values. The returned array must have the default array index data type. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ nonzero(x, /) + + ¶ + +

+

+ Returns the indices of the array elements which are non-zero. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. Must have a positive rank. If + + + x + + + is zero-dimensional, the function must raise an exception. +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + Tuple[ <array>, … ] + +

    +
      +
    • +

      + a tuple of + + + k + + + arrays, one for each dimension of + + + x + + + and each of size + + + n + + + (where + + + n + + + is the total number of non-zero elements), containing the indices of the non-zero elements in that dimension. The indices must be returned in row-major, C-style order. The returned array must have the default array index data type. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ where(condition, x1, x2, /) + + ¶ + +

+

+ Returns elements chosen from + + + x1 + + + or + + + x2 + + + depending on + + + condition + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + condition + + : + + <array> + +

    +
      +
    • +

      + when + + + True + + + , yield + + + x1_i + + + ; otherwise, yield + + + x2_i + + + . Must be compatible with + + + x1 + + + and + + + x2 + + + (see + + + Broadcasting + + + ). +

      +
    • +
    +
  • +
  • +

    + + x1 + + : + + <array> + +

    +
      +
    • +

      + first input array. Must be compatible with + + + condition + + + and + + + x2 + + + (see + + + Broadcasting + + + ). +

      +
    • +
    +
  • +
  • +

    + + x2 + + : + + <array> + +

    +
      +
    • +

      + second input array. Must be compatible with + + + condition + + + and + + + x1 + + + (see + + + Broadcasting + + + ). +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array with elements from + + + x1 + + + where + + + condition + + + is + + + True + + + , and elements from + + + x2 + + + elsewhere. The returned array must have a data type determined by + + + Type Promotion Rules + + + rules. +

      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/set_functions.html b/latest/API_specification/set_functions.html new file mode 100644 index 000000000..a7e892c6a --- /dev/null +++ b/latest/API_specification/set_functions.html @@ -0,0 +1,925 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Set Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+

+ Set Functions + + ¶ + +

+
+
+

+ Array API specification for creating and operating on sets. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Unless stated otherwise, functions must support the data types defined in + + + Data Types + + + . +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ unique(x, /, *, return_counts=False, return_index=False, return_inverse=False) + + ¶ + +

+

+ Returns the unique elements of an input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. If + + + x + + + has more than one dimension, the function must flatten + + + x + + + and return the unique elements of the flattened array. +

      +
    • +
    +
  • +
  • +

    + + return_counts + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the function must also return the number of times each unique element occurs in + + + x + + + . Default: + + + False + + + . +

      +
    • +
    +
  • +
  • +

    + + return_index + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the function must also return the indices (first occurrences) of + + + x + + + that result in the unique array. Default: + + + False + + + . +

      +
    • +
    +
  • +
  • +

    + + return_inverse + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the function must also return the indices of the unique array that reconstruct + + + x + + + . Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + Union[ <array>, Tuple[ <array>, … ] ] + +

    +
      +
    • +

      + if + + + return_counts + + + , + + + return_index + + + , and + + + return_inverse + + + are all + + + False + + + , an array containing the set of unique elements in + + + x + + + ; otherwise, a tuple containing two or more of the following arrays (in order): +

      +
        +
      • +

        + + unique + + : + + <array> + +

        +
          +
        • +

          + an array containing the set of unique elements in + + + x + + + . The returned array must have the same data type as + + + x + + + . +

          +
        • +
        +
        +

        + Note +

        +

        + The order of elements is not specified, and may vary between implementations. +

        +
        +
      • +
      • +

        + + indices + + : + + <array> + +

        +
          +
        • +

          + an array containing the indices (first occurrences) of + + + x + + + that result in + + + unique + + + . The returned array must have the default array index data type. +

          +
        • +
        +
      • +
      • +

        + + inverse + + : + + <array> + +

        +
          +
        • +

          + an array containing the indices of + + + unique + + + that reconstruct + + + x + + + . The returned array must have the default array index data type. +

          +
        • +
        +
      • +
      • +

        + + counts + + : + + <array> + +

        +
          +
        • +

          + an array containing the number of times each unique element occurs in + + + x + + + . +

          +

          + + TODO: should this be + + + int64 + + + ? This probably makes sense for most hardware; however, may be undesirable for older hardware and/or embedded systems. + +

          +
        • +
        +
      • +
      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/sorting_functions.html b/latest/API_specification/sorting_functions.html new file mode 100644 index 000000000..1a1c57a2d --- /dev/null +++ b/latest/API_specification/sorting_functions.html @@ -0,0 +1,1017 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sorting Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+

+ Sorting Functions + + ¶ + +

+
+
+

+ Array API specification for sorting functions. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Unless stated otherwise, functions must support the data types defined in + + + Data Types + + + . +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ argsort(x, /, *, axis=-1, descending=False, stable=True) + + ¶ + +

+

+ Returns the indices that sort an array + + + x + + + along a specified axis. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + int + +

    +
      +
    • +

      + axis along which to sort. If set to + + + -1 + + + , the function must sort along the last axis. Default: + + + -1 + + + . +

      +
    • +
    +
  • +
  • +

    + + descending + + : + + bool + +

    +
      +
    • +

      + sort order. If + + + True + + + , the returned indices sort + + + x + + + in descending order (by value). If + + + False + + + , the returned indices sort + + + x + + + in ascending order (by value). Default: + + + False + + + . +

      +
    • +
    +
  • +
  • +

    + + stable + + : + + bool + +

    +
      +
    • +

      + sort stability. If + + + True + + + , the returned indices must maintain the relative order of + + + x + + + values which compare as equal. If + + + False + + + , the returned indices may or may not maintain the relative order of + + + x + + + values which compare as equal (i.e., the relative order of + + + x + + + values which compare as equal is implementation-dependent). Default: + + + True + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + an array of indices. The returned array must have the same shape as + + + x + + + . The returned array must have the default array index data type. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ sort(x, /, *, axis=-1, descending=False, stable=True) + + ¶ + +

+

+ Returns a sorted copy of an input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + int + +

    +
      +
    • +

      + axis along which to sort. If set to + + + -1 + + + , the function must sort along the last axis. Default: + + + -1 + + + . +

      +
    • +
    +
  • +
  • +

    + + descending + + : + + bool + +

    +
      +
    • +

      + sort order. If + + + True + + + , the array must be sorted in descending order (by value). If + + + False + + + , the array must be sorted in ascending order (by value). Default: + + + False + + + . +

      +
    • +
    +
  • +
  • +

    + + stable + + : + + bool + +

    +
      +
    • +

      + sort stability. If + + + True + + + , the returned array must maintain the relative order of + + + x + + + values which compare as equal. If + + + False + + + , the returned array may or may not maintain the relative order of + + + x + + + values which compare as equal (i.e., the relative order of + + + x + + + values which compare as equal is implementation-dependent). Default: + + + True + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + a sorted array. The returned array must have the same data type and shape as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/statistical_functions.html b/latest/API_specification/statistical_functions.html new file mode 100644 index 000000000..28f1d9b81 --- /dev/null +++ b/latest/API_specification/statistical_functions.html @@ -0,0 +1,1951 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Statistical Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+
+

+ Statistical Functions + + ¶ + +

+
+
+

+ Array API specification for statistical functions. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Broadcasting semantics must follow the semantics defined in + + + Broadcasting + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must support the data types defined in + + + Data Types + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must adhere to the type promotion rules defined in + + + Type Promotion Rules + + + . +

    +
  • +
  • +

    + Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ max(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Calculates the maximum value of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which maximum values must be computed. By default, the maximum value must be computed over the entire array. If a tuple of integers, maximum values must be computed over multiple axes. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if the maximum value was computed over the entire array, a zero-dimensional array containing the maximum value; otherwise, a non-zero-dimensional array containing the maximum values. The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ mean(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Calculates the arithmetic mean of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which arithmetic means must be computed. By default, the mean must be computed over the entire array. If a tuple of integers, arithmetic means must be computed over multiple axes. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if the arithmetic mean was computed over the entire array, a zero-dimensional array containing the arithmetic mean; otherwise, a non-zero-dimensional array containing the arithmetic means. The returned array must have be the default floating-point data type. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ min(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Calculates the minimum value of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which minimum values must be computed. By default, the minimum value must be computed over the entire array. If a tuple of integers, minimum values must be computed over multiple axes. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if the minimum value was computed over the entire array, a zero-dimensional array containing the minimum value; otherwise, a non-zero-dimensional array containing the minimum values. The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ prod(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Calculates the product of input array + + + x + + + elements. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which products must be computed. By default, the product must be computed over the entire array. If a tuple of integers, products must be computed over multiple axes. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if the product was computed over the entire array, a zero-dimensional array containing the product; otherwise, a non-zero-dimensional array containing the products. The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ std(x, /, *, axis=None, correction=0.0, keepdims=False) + + ¶ + +

+

+ Calculates the standard deviation of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which standard deviations must be computed. By default, the standard deviation must be computed over the entire array. If a tuple of integers, standard deviations must be computed over multiple axes. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + correction + + : + + Union[ int, float ] + +

    +
      +
    • +

      + degrees of freedom adjustment. Setting this parameter to a value other than + + + 0 + + + has the effect of adjusting the divisor during the calculation of the standard deviation according to + + + N-c + + + where + + + N + + + corresponds to the total number of elements over which the standard deviation is computed and + + + c + + + corresponds to the provided degrees of freedom adjustment. When computing the standard deviation of a population, setting this parameter to + + + 0 + + + is the standard choice (i.e., the provided array contains data constituting an entire population). When computing the corrected sample standard deviation, setting this parameter to + + + 1 + + + is the standard choice (i.e., the provided array contains data sampled from a larger population; this is commonly referred to as Bessel’s correction). Default: + + + 0 + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if the standard deviation was computed over the entire array, a zero-dimensional array containing the standard deviation; otherwise, a non-zero-dimensional array containing the standard deviations. The returned array must have the default floating-point data type. +

      +
    • +
    +
  • +
+
+
+
+ + +

+ sum(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Calculates the sum of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which sums must be computed. By default, the sum must be computed over the entire array. If a tuple of integers, sums must be computed over multiple axes. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if the sum was computed over the entire array, a zero-dimensional array containing the sum; otherwise, an array containing the sums. The returned array must have the same data type as + + + x + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ var(x, /, *, axis=None, correction=0.0, keepdims=False) + + ¶ + +

+

+ Calculates the variance of the input array + + + x + + + . +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which variances must be computed. By default, the variance must be computed over the entire array. If a tuple of integers, variances must be computed over multiple axes. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + correction + + : + + Union[ int, float ] + +

    +
      +
    • +

      + degrees of freedom adjustment. Setting this parameter to a value other than + + + 0 + + + has the effect of adjusting the divisor during the calculation of the variance according to + + + N-c + + + where + + + N + + + corresponds to the total number of elements over which the variance is computed and + + + c + + + corresponds to the provided degrees of freedom adjustment. When computing the variance of a population, setting this parameter to + + + 0 + + + is the standard choice (i.e., the provided array contains data constituting an entire population). When computing the unbiased sample variance, setting this parameter to + + + 1 + + + is the standard choice (i.e., the provided array contains data sampled from a larger population; this is commonly referred to as Bessel’s correction). Default: + + + 0 + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if the variance was computed over the entire array, a zero-dimensional array containing the variance; otherwise, a non-zero-dimensional array containing the variances. The returned array must have the default floating-point data type. +

      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/type_promotion.html b/latest/API_specification/type_promotion.html new file mode 100644 index 000000000..60d8accbe --- /dev/null +++ b/latest/API_specification/type_promotion.html @@ -0,0 +1,1373 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Type Promotion Rules — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Type Promotion Rules + + ¶ + +

+
+
+

+ Array API specification for type promotion rules. +

+
+
+

+ Type promotion rules can be understood at a high level from the following +diagram: +

+

+ Type promotion diagram +

+

+ + Type promotion diagram. Promotion between any two types is given by their join on this lattice. Only the types of participating arrays matter, not their values. Dashed lines indicate that behavior for Python scalars is undefined on overflow. Boolean, integer and floating-point dtypes are not connected, indicating mixed-kind promotion is undefined. + +

+
+

+ Rules + + ¶ + +

+

+ A conforming implementation of the array API standard must implement the following type promotion rules governing the common result type for two + + array + + operands during an arithmetic operation. +

+

+ A conforming implementation of the array API standard may support additional type promotion rules beyond those described in this specification. +

+
+

+ Note +

+

+ Type codes are used here to keep tables readable; they are not part of the standard. +In code, use the data type objects specified in + + + Data Types + + + (e.g., + + + int16 + + + rather than + + + 'i2' + + + ). +

+
+ +

+ The following type promotion tables specify the casting behavior for +operations involving two array operands. When more than two array operands +participate, application of the promotion tables is associative (i.e., the +result does not depend on operand order). +

+
+

+ Signed integer type promotion table + + ¶ + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + i1 + + i2 + + i4 + + i8 +
+ + i1 + + + i1 + + i2 + + i4 + + i8 +
+ + i2 + + + i2 + + i2 + + i4 + + i8 +
+ + i4 + + + i4 + + i4 + + i4 + + i8 +
+ + i8 + + + i8 + + i8 + + i8 + + i8 +
+

+ where +

+
    +
  • +

    + + i1 + + : 8-bit signed integer (i.e., + + + int8 + + + ) +

    +
  • +
  • +

    + + i2 + + : 16-bit signed integer (i.e., + + + int16 + + + ) +

    +
  • +
  • +

    + + i4 + + : 32-bit signed integer (i.e., + + + int32 + + + ) +

    +
  • +
  • +

    + + i8 + + : 64-bit signed integer (i.e., + + + int64 + + + ) +

    +
  • +
+
+
+

+ Unsigned integer type promotion table + + ¶ + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + u1 + + u2 + + u4 + + u8 +
+ + u1 + + + u1 + + u2 + + u4 + + u8 +
+ + u2 + + + u2 + + u2 + + u4 + + u8 +
+ + u4 + + + u4 + + u4 + + u4 + + u8 +
+ + u8 + + + u8 + + u8 + + u8 + + u8 +
+

+ where +

+
    +
  • +

    + + u1 + + : 8-bit unsigned integer (i.e., + + + uint8 + + + ) +

    +
  • +
  • +

    + + u2 + + : 16-bit unsigned integer (i.e., + + + uint16 + + + ) +

    +
  • +
  • +

    + + u4 + + : 32-bit unsigned integer (i.e., + + + uint32 + + + ) +

    +
  • +
  • +

    + + u8 + + : 64-bit unsigned integer (i.e., + + + uint64 + + + ) +

    +
  • +
+
+
+

+ Mixed unsigned and signed integer type promotion table + + ¶ + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + u1 + + u2 + + u4 +
+ + i1 + + + i2 + + i4 + + i8 +
+ + i2 + + + i2 + + i4 + + i8 +
+ + i4 + + + i4 + + i4 + + i8 +
+
+
+

+ Floating-point type promotion table + + ¶ + +

+ + + + + + + + + + + + + + + + + + + + +
+ + f4 + + f8 +
+ + f4 + + + f4 + + f8 +
+ + f8 + + + f8 + + f8 +
+

+ where +

+
    +
  • +

    + + f4 + + : single-precision (32-bit) floating-point number (i.e., + + + float32 + + + ) +

    +
  • +
  • +

    + + f8 + + : double-precision (64-bit) floating-point number (i.e., + + + float64 + + + ) +

    +
  • +
+
+
+

+ Notes + + ¶ + +

+
    +
  • +

    + Type promotion rules must apply when determining the common result type for two + + array + + operands during an arithmetic operation, regardless of array dimension. Accordingly, zero-dimensional arrays must be subject to the same type promotion rules as dimensional arrays. +

    +
  • +
  • +

    + Type promotion of non-numerical data types to numerical data types is unspecified (e.g., + + + bool + + + to + + + intxx + + + or + + + floatxx + + + ). +

    +
  • +
+
+

+ Note +

+

+ Mixed integer and floating-point type promotion rules are not specified +because behavior varies between implementations. +

+
+
+
+

+ Mixing arrays with Python scalars + + ¶ + +

+

+ Using Python scalars (i.e., instances of + + + bool + + + , + + + int + + + , + + + float + + + ) together with +arrays must be supported for: +

+
    +
  • +

    + + + array + + + <op> + + + scalar + + +

    +
  • +
  • +

    + + + scalar + + + <op> + + + array + + +

    +
  • +
+

+ where + + + <op> + + + is a built-in operator (see + + + Operators + + + for operators +supported by the array object) and + + + scalar + + + has a compatible type and value +to the array dtype: +

+
    +
  • +

    + Python + + + bool + + + for a + + + bool + + + array dtype, +

    +
  • +
  • +

    + a Python + + + int + + + within the + + + bounds + + + of the given dtype for integer array dtypes, +

    +
  • +
  • +

    + a Python + + + int + + + or + + + float + + + for floating-point array dtypes +The expected behavior is then equivalent to: +

    +
  • +
+
    +
  1. +

    + Convert the scalar to a 0-D array with the same dtype as that of the array +used in the expression. +

    +
  2. +
  3. +

    + Execute the operation for + + + array + + + <op> + + + 0-D + + + array + + + (or + + + 0-D + + + array + + + <op> + + + array + + + if + + + scalar + + + was the left-hand argument). +

    +
  4. +
+
+

+ Note +

+

+ Behaviour is not specified when mixing a Python + + + float + + + and an array with an +integer dtype; this may give + + + float32 + + + , + + + float64 + + + , or raise an exception - +behavior of implementations will differ. +

+

+ The behavior is also not specified for integers outside of the bounds of a +given integer dtype. It may overflow, or result in an error. +

+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/API_specification/utility_functions.html b/latest/API_specification/utility_functions.html new file mode 100644 index 000000000..4d21adfee --- /dev/null +++ b/latest/API_specification/utility_functions.html @@ -0,0 +1,1014 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Utility Functions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+

+ Utility Functions + + ¶ + +

+
+
+

+ Array API specification for utility functions. +

+
+
+

+ A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. +

+
    +
  • +

    + Positional parameters must be + + positional-only + + parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +

    +
  • +
  • +

    + Optional parameters must be + + keyword-only + + arguments. +

    +
  • +
  • +

    + Broadcasting semantics must follow the semantics defined in + + + Broadcasting + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must support the data types defined in + + + Data Types + + + . +

    +
  • +
  • +

    + Unless stated otherwise, functions must adhere to the type promotion rules defined in + + + Type Promotion Rules + + + . +

    +
  • +
  • +

    + Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. +

    +
  • +
+
+

+ Objects in API + + ¶ + +

+ +
+ + +

+ all(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Tests whether all input array elements evaluate to + + + True + + + along a specified axis. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which to perform a logical AND reduction. By default, a logical AND reduction must be performed over the entire array. If a tuple of integers, logical AND reductions must be performed over multiple axes. A valid + + + axis + + + must be an integer on the interval + + + [-N, + + + N) + + + , where + + + N + + + is the rank (number of dimensions) of + + + x + + + . If an + + + axis + + + is specified as a negative integer, the function must determine the axis along which to perform a reduction by counting backward from the last dimension (where + + + -1 + + + refers to the last dimension). If provided an invalid + + + axis + + + , the function must raise an exception. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if a logical AND reduction was performed over the entire array, the returned array must be a zero-dimensional array containing the test result; otherwise, the returned array must be a non-zero-dimensional array containing the test results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+ + +

+ any(x, /, *, axis=None, keepdims=False) + + ¶ + +

+

+ Tests whether any input array element evaluates to + + + True + + + along a specified axis. +

+
+

+ Parameters + + ¶ + +

+
    +
  • +

    + + x + + : + + <array> + +

    +
      +
    • +

      + input array. +

      +
    • +
    +
  • +
  • +

    + + axis + + : + + Optional[ Union[ int, Tuple[ int, … ] ] ] + +

    +
      +
    • +

      + axis or axes along which to perform a logical OR reduction. By default, a logical OR reduction must be performed over the entire array. If a tuple of integers, logical OR reductions must be performed over multiple axes. A valid + + + axis + + + must be an integer on the interval + + + [-N, + + + N) + + + , where + + + N + + + is the rank (number of dimensions) of + + + x + + + . If an + + + axis + + + is specified as a negative integer, the function must determine the axis along which to perform a reduction by counting backward from the last dimension (where + + + -1 + + + refers to the last dimension). If provided an invalid + + + axis + + + , the function must raise an exception. Default: + + + None + + + . +

      +
    • +
    +
  • +
  • +

    + + keepdims + + : + + bool + +

    +
      +
    • +

      + If + + + True + + + , the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see + + + Broadcasting + + + ). Otherwise, if + + + False + + + , the reduced axes (dimensions) must not be included in the result. Default: + + + False + + + . +

      +
    • +
    +
  • +
+
+
+

+ Returns + + ¶ + +

+
    +
  • +

    + + out + + : + + <array> + +

    +
      +
    • +

      + if a logical OR reduction was performed over the entire array, the returned array must be a zero-dimensional array containing the test result; otherwise, the returned array must be a non-zero-dimensional array containing the test results. The returned array must have a data type of + + + bool + + + . +

      +
    • +
    +
  • +
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/_images/DLPack_diagram.png b/latest/_images/DLPack_diagram.png new file mode 100644 index 000000000..a84598532 Binary files /dev/null and b/latest/_images/DLPack_diagram.png differ diff --git a/latest/_images/dependency_assumption_diagram.png b/latest/_images/dependency_assumption_diagram.png new file mode 100644 index 000000000..f77f11f45 Binary files /dev/null and b/latest/_images/dependency_assumption_diagram.png differ diff --git a/latest/_images/dtype_promotion_complex.png b/latest/_images/dtype_promotion_complex.png new file mode 100644 index 000000000..3503b07f5 Binary files /dev/null and b/latest/_images/dtype_promotion_complex.png differ diff --git a/latest/_images/dtype_promotion_lattice.png b/latest/_images/dtype_promotion_lattice.png new file mode 100644 index 000000000..669d30476 Binary files /dev/null and b/latest/_images/dtype_promotion_lattice.png differ diff --git a/latest/_images/scope_of_array_API.png b/latest/_images/scope_of_array_API.png new file mode 100644 index 000000000..55253288c Binary files /dev/null and b/latest/_images/scope_of_array_API.png differ diff --git a/latest/_sources/API_specification/array_object.md.txt b/latest/_sources/API_specification/array_object.md.txt new file mode 100644 index 000000000..a8eb39104 --- /dev/null +++ b/latest/_sources/API_specification/array_object.md.txt @@ -0,0 +1,1137 @@ +(array-object)= + +# Array object + +> Array API specification for array object attributes and methods. + +A conforming implementation of the array API standard must provide and support an array object having the following attributes and methods adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a method accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Broadcasting semantics must follow the semantics defined in {ref}`broadcasting`. +- Unless stated otherwise, methods must support the data types defined in {ref}`data-types`. +- Unless stated otherwise, methods must adhere to the type promotion rules defined in {ref}`type-promotion`. +- Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. + +* * * + +(operators)= + +## Operators + +A conforming implementation of the array API standard must provide and support an array object supporting the following Python operators: + +- `x1 < x2`: [`__lt__(x1, x2)`](#__lt__self-other-) + + - [`operator.lt(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.lt) + - [`operator.__lt__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__lt__) + +- `x1 <= x2`: [`__le__(x1, x2)`](#__le__self-other-) + + - [`operator.le(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.le) + - [`operator.__le__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__le__) + +- `x1 > x2`: [`__gt__(x1, x2)`](#__gt__self-other-) + + - [`operator.gt(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.gt) + - [`operator.__gt__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__gt__) + +- `x1 >= x2`: [`__ge__(x1, x2)`](#__ge__self-other-) + + - [`operator.ge(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.ge) + - [`operator.__ge__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__ge__) + +- `x1 == x2`: [`__eq__(x1, x2)`](#__eq__self-other-) + + - [`operator.eq(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.eq) + - [`operator.__eq__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__eq__) + +- `x1 != x2`: [`__ne__(x1, x2)`](#__ne__self-other-) + + - [`operator.ne(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.ne) + - [`operator.__ne__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__ne__) + +- `+x`: [`__pos__(x)`](#__pos__self-) + + - [`operator.pos(x)`](https://docs.python.org/3/library/operator.html#operator.pos) + - [`operator.__pos__(x)`](https://docs.python.org/3/library/operator.html#operator.__pos__) + +- `-x`: [`__neg__(x)`](#__neg__self-) + + - [`operator.neg(x)`](https://docs.python.org/3/library/operator.html#operator.neg) + - [`operator.__neg__(x)`](https://docs.python.org/3/library/operator.html#operator.__neg__) + +- `x1 + x2`: [`__add__(x1, x2)`](#__add__self-other-) + + - [`operator.add(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.add) + - [`operator.__add__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__add__) + +- `x1 - x2`: [`__sub__(x1, x2)`](#__sub__self-other-) + + - [`operator.sub(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.sub) + - [`operator.__sub__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__sub__) + +- `x1 * x2`: [`__mul__(x1, x2)`](#__mul__self-other-) + + - [`operator.mul(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.mul) + - [`operator.__mul__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__mul__) + +- `x1 / x2`: [`__truediv__(x1, x2)`](#__truediv__self-other-) + + - [`operator.truediv(x1,x2)`](https://docs.python.org/3/library/operator.html#operator.truediv) + - [`operator.__truediv__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__truediv__) + +- `x1 // x2`: [`__floordiv__(x1, x2)`](#__floordiv__self-other-) + + - [`operator.floordiv(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.floordiv) + - [`operator.__floordiv__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__floordiv__) + +- `x1 % x2`: [`__mod__(x1, x2)`](#__mod__self-other-) + + - [`operator.mod(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.mod) + - [`operator.__mod__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__mod__) + +- `x1 ** x2`: [`__pow__(x1, x2)`](#__pow__self-other-) + + - [`operator.pow(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.pow) + - [`operator.__pow__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__pow__) + +- `x1 @ x2`: [`__matmul__(x1, x2)`](#__matmul__self-other-) + + - [`operator.matmul(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.matmul) + - [`operator.__matmul__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__matmul__) + +- `~x`: [`__invert__(x)`](#__invert__self-) + + - [`operator.inv(x)`](https://docs.python.org/3/library/operator.html#operator.inv) + - [`operator.invert(x)`](https://docs.python.org/3/library/operator.html#operator.invert) + - [`operator.__inv__(x)`](https://docs.python.org/3/library/operator.html#operator.__inv__) + - [`operator.__invert__(x)`](https://docs.python.org/3/library/operator.html#operator.__invert__) + +- `x1 & x2`: [`__and__(x1, x2)`](#__and__self-other-) + + - [`operator.and(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.and) + - [`operator.__and__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__and__) + +- `x1 | x2`: [`__or__(x1, x2)`](#__or__self-other-) + + - [`operator.or(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.or) + - [`operator.__or__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__or__) + +- `x1 ^ x2`: [`__xor__(x1, x2)`](#__xor__self-other-) + + - [`operator.xor(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.xor) + - [`operator.__xor__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__xor__) + +- `x1 << x2`: [`__lshift__(x1, x2)`](#__lshift__self-other-) + + - [`operator.lshift(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.lshift) + - [`operator.__lshift__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__lshift__) + +- `x1 >> x2`: [`__rshift__(x1, x2)`](#__rshift__self-other-) + + - [`operator.rshift(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.rshift) + - [`operator.__rshift__(x1, x2)`](https://docs.python.org/3/library/operator.html#operator.__rshift__) + + +### In-place Operators + +A conforming implementation of the array API standard must provide and support +an array object supporting the following in-place Python operators: + +- `+=`. May be implemented via `__iadd__`. +- `-=`. May be implemented via `__isub__`. +- `*=`. May be implemented via `__imul__`. +- `/=`. May be implemented via `__itruediv__`. +- `//=`. May be implemented via `__ifloordiv__`. +- `**=`. May be implemented via `__ipow__`. +- `@=`. May be implemented via `__imatmul__`. +- `%=`. May be implemented via `__imod__`. +- `&=`. May be implemented via `__iand__`. +- `|=`. May be implemented via `__ior__`. +- `^=`. May be implemented via `__ixor__`. +- `<<=`. May be implemented via `__ilshift__`. +- `>>=`. May be implemented via `__irshift__`. + +```{note} + +In-place operators must be supported as discussed in {ref}`copyview-mutability`. +``` + +### Reflected Operators + +A conforming implementation of the array API standard must provide and support +an array object supporting the following reflected operators: + +- `__radd__` +- `__rsub__` +- `__rmul__` +- `__rtruediv__` +- `__rfloordiv__` +- `__rpow__` +- `__rmatmul__` +- `__rmod__` +- `__rand__` +- `__ror__` +- `__rxor__` +- `__rlshift__` +- `__rrshift__` + +The results of applying reflected operators must match their non-reflected equivalents. + +```{note} + +All operators for which `array scalar` is implemented must have an equivalent reflected operator implementation. +``` + +* * * + +## Attributes + + + +(attribute-dtype)= +### dtype + +Data type of the array elements. + +#### Returns + +- **out**: _<dtype>_ + + - array data type. + +(attribute-device)= +### device + +Hardware device the array data resides on. + +#### Returns + +- **out**: _<device>_ + + - a `device` object (see {ref}`device-support`). + +(attribute-ndim)= +### ndim + +Number of array dimensions (axes). + +#### Returns + +- **out**: _int_ + + - number of array dimensions (axes). + +_TODO: need to more carefully consider this in order to accommodate, e.g., graph tensors where the number of dimensions may be dynamic._ + +(attribute-shape)= +### shape + +Array dimensions. + +#### Returns + +- **out**: _Union\[ Tuple\[ int, ...], <shape> ]_ + + - array dimensions as either a tuple or a custom shape object. If a shape object, the object must be immutable and must support indexing for dimension retrieval. + +_TODO: need to more carefully consider this in order to accommodate, e.g., graph tensors where a shape may be dynamic._ + +(attribute-size)= +### size + +Number of elements in an array. This must equal the product of the array's dimensions. + +#### Returns + +- **out**: _int_ + + - number of elements in an array. + +_TODO: need to more carefully consider this in order to accommodate, e.g., graph tensors where the number of elements may be dynamic._ + +(attribute-T)= +### T + +Transpose of the array. + +#### Returns + +- **out**: _<array>_ + + - array whose dimensions (axes) are permuted in reverse order relative to original array. The returned array must have the same data type as the original array. + +* * * + +## Methods + + + +(method-__abs__)= +### \_\_abs\_\_(self, /) + +Calculates the absolute value for each element of an array instance (i.e., the element-wise result has the same magnitude as the respective element but has positive sign). + +#### Special Cases + +For floating-point operands, let `self` equal `x`. + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `-0`, the result is `+0`. +- If `x_i` is `-infinity`, the result is `+infinity`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise absolute value. The returned array must have the same data type as `self`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`abs(x)`](elementwise_functions.md#absx-). +``` + +(method-__add__)= +### \_\_add\_\_(self, other, /) + +Calculates the sum for each element of an array instance with the respective element of the array `other`. + +#### Special Cases + +For floating-point operands, let `self` equal `x1` and `other` equal `x2`. + +- If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. +- If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is `NaN`. +- If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is `NaN`. +- If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is `+infinity`. +- If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is `-infinity`. +- If `x1_i` is `+infinity` and `x2_i` is a finite number, the result is `+infinity`. +- If `x1_i` is `-infinity` and `x2_i` is a finite number, the result is `-infinity`. +- If `x1_i` is a finite number and `x2_i` is `+infinity`, the result is `+infinity`. +- If `x1_i` is a finite number and `x2_i` is `-infinity`, the result is `-infinity`. +- If `x1_i` is `-0` and `x2_i` is `-0`, the result is `-0`. +- If `x1_i` is `-0` and `x2_i` is `+0`, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is `-0`, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. +- If `x1_i` is either `+0` or `-0` and `x2_i` is a nonzero finite number, the result is `x2_i`. +- If `x1_i` is a nonzero finite number and `x2_i` is either `+0` or `-0`, the result is `x1_i`. +- If `x1_i` is a nonzero finite number and `x2_i` is `-x1_i`, the result is `+0`. +- In the remaining cases, when neither `infinity`, `+0`, `-0`, nor a `NaN` is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. + +```{note} + +Floating-point addition is a commutative operation, but not always associative. +``` + +#### Parameters + +- **self**: _<array>_ + + - array instance (augend array). + +- **other**: _<array>_ + + - addend array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise sums. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`add(x1, x2)`](elementwise_functions.md#addx1-x2-). +``` + +(method-__and__)= +### \_\_and\_\_(self, other, /) + +Evaluates `self_i & other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. Must have an integer or boolean data type. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). Must have an integer or boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`bitwise_and(x1, x2)`](elementwise_functions.md#logical_andx1-x2-). +``` + + +(method-__array_namespace__)= +### \_\_array_namespace\_\_(self, /, *, api_version=None) + +Returns an object that has all the array API functions on it. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **api_version**: _<Optional\[str\]>_ + + - string representing the version of the array API specification to be returned, in `'YYYY.MM'` form, for example, `'2020.10'`. If it is `None`, it should return the namespace corresponding to latest version of the array API specification. If the given version is invalid or not implemented for the given module, an error should be raised. Default: `None`. + +#### Returns + +- **out**: _<object>_ + + - an object representing the array API namespace. It should have every top-level function defined in the specification as an attribute. It may contain other public names as well, but it is recommended to only include those names that are part of the specification. + + +(method-__bool__)= +### \_\_bool\_\_(self, /) + +Converts a zero-dimensional boolean array to a Python `bool` object. + +#### Parameters + +- **self**: _<array>_ + + - zero-dimensional array instance. Must have a boolean data type. + +#### Returns + +- **out**: _<bool>_ + + - a Python `bool` object representing the single element of the array. + + +(method-__dlpack__)= +### \_\_dlpack\_\_(self, /, *, stream=None) + +Exports the array for consumption by {ref}`function-from_dlpack` as a DLPack capsule. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **stream**: _Optional\[ int ]_ + + - a Python integer representing a pointer to a stream. `stream` is provided by the consumer to the producer to instruct the producer to ensure that operations can safely be performed on the array. The pointer must be a positive integer or `-1`. If `stream` is `-1`, the value may be used by the consumer to signal "producer must not perform any synchronization". Device-specific notes: + + :::{admonition} CUDA + - `None`: producer must assume the legacy default stream (default). + - `1`: the legacy default stream. + - `2`: the per-thread default stream. + - `> 2`: stream number represented as a Python integer. + + `0` is disallowed due to its ambiguity: `0` could mean either `None`, `1`, or `2`. + ::: + + :::{admonition} ROCm + - `None`: producer must assume the legacy default stream (default). + - `0`: the default stream. + - `> 2`: stream number represented as a Python integer. + + Using `1` and `2` is not supported. + ::: + + ```{tip} + It is recommended that implementers explicitly handle streams. If + they use the legacy default stream, specifying `1` (CUDA) or `0` + (ROCm) is preferred. `None` is a safe default for developers who do + not want to think about stream handling at all, potentially at the + cost of more synchronization than necessary. + ``` + +#### Returns + +- **capsule**: _<PyCapsule>_ + + - a DLPack capsule for the array. See {ref}`data-interchange` for details. + + +(method-__dlpack_device__)= +### \_\_dlpack\_device\_\_(self, /) + +Returns device type and device ID in DLPack format. Meant for use within {ref}`function-from_dlpack`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +#### Returns + +- **device**: _Tuple\[enum.IntEnum, int\]_ + + - a tuple `(device_type, device_id)` in DLPack format. Valid device type enum members are: + + ``` + CPU = 1 + CUDA = 2 + CPU_PINNED = 3 + OPENCL = 4 + VULKAN = 7 + METAL = 8 + VPI = 9 + ROCM = 10 + ``` + +(method-__eq__)= +### \_\_eq\_\_(self, other, /) + +Computes the truth value of `self_i == other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`equal(x1, x2)`](elementwise_functions.md#equalx1-x2-). +``` + +(method-__float__)= +### \_\_float\_\_(self, /) + +Converts a zero-dimensional floating-point array to a Python `float` object. + +#### Parameters + +- **self**: _<array>_ + + - zero-dimensional array instance. Must have a floating-point data type. + +#### Returns + +- **out**: _<float>_ + + - a Python `float` object representing the single element of the array instance. + +(method-__floordiv__)= +### \_\_floordiv\_\_(self, other, /) + +Evaluates `self_i // other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`floor_divide(x1, x2)`](elementwise_functions.md#floor_dividex1-x2-). +``` + +(method-__ge__)= +### \_\_ge\_\_(self, other, /) + +Computes the truth value of `self_i >= other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`greater_equal(x1, x2)`](elementwise_functions.md#greater_equalx1-x2-). +``` + +(method-__getitem__)= +### \_\_getitem\_\_(self, key, /) + +Returns `self[key]`. + +#### Parameters + +- **self**: _<array;>_ + + - array instance. + +- **key**: _Union\[ int, slice, ellipsis, Tuple\[ Union\[ int, slice, ellipsis ], ... ], <array> ]_ + + - index key. + +#### Returns + +- **out**: _<array>_ + + - an array containing the accessed value(s). The returned array must have the same data type as `self`. + +(method-__gt__)= +### \_\_gt\_\_(self, other, /) + +Computes the truth value of `self_i > other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`greater(x1, x2)`](elementwise_functions.md#greaterx1-x2-). +``` + +(method-__int__)= +### \_\_int\_\_(self, /) + +Converts a zero-dimensional integer array to a Python `int` object. + +#### Parameters + +- **self**: _<array>_ + + - zero-dimensional array instance. Must have an integer data type. + +#### Returns + +- **out**: _<int>_ + + - a Python `int` object representing the single element of the array instance. + +(method-__invert__)= +### \_\_invert\_\_(self, /) + +Evaluates `~self_i` for each element of an array instance. + +#### Parameters + +- **self**: _<array>_ + + - array instance. Must have an integer or boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have the same data type as `self`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`bitwise_invert(x)`](elementwise_functions.md#bitwise_invertx-). +``` + +(method-__le__)= +### \_\_le\_\_(self, other, /) + +Computes the truth value of `self_i <= other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`less_equal(x1, x2)`](elementwise_functions.md#less_equalx1-x2-). +``` + +(method-__len__)= +### \_\_len\_\_(self, /) + +_TODO: need to more carefully consider this in order to accommodate, e.g., graph tensors where a shape may be dynamic. Furthermore, not clear whether this should be implemented, as, e.g., NumPy's behavior of returning the size of the first dimension is not necessarily intuitive, as opposed to, say, the total number of elements._ + +(method-__lshift__)= +### \_\_lshift\_\_(self, other, /) + +Evaluates `self_i << other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. Must have an integer data type. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). Must have an integer data type. Each element must be greater than or equal to `0`. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have the same data type as `self`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`less_equal(x1, x2)`](elementwise_functions.md#bitwise_left_shiftx1-x2-). +``` + +(method-__lt__)= +### \_\_lt\_\_(self, other, /) + +Computes the truth value of `self_i < other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`less(x1, x2)`](elementwise_functions.md#lessx1-x2-). +``` + +(method-__matmul__)= +### \_\_matmul\_\_(self, other, /) + +_TODO: awaiting `matmul` functional equivalent._ + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - _TODO_ + +(method-__mod__)= +### \_\_mod\_\_(self, other, /) + +Evaluates `self_i % other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. Each element-wise result must have the same sign as the respective element `other_i`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`remainder(x1, x2)`](elementwise_functions.md#remainderx1-x2-). +``` + +(method-__mul__)= +### \_\_mul\_\_(self, other, /) + +Calculates the product for each element of an array instance with the respective element of the array `other`. + +#### Special Cases + +For floating-point operands, let `self` equal `x1` and `other` equal `x2`. + +- If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. +- If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+0` or `-0`, the result is `NaN`. +- If `x1_i` is either `+0` or `-0` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. +- If `x1_i` and `x2_i` have the same mathematical sign, the result has a positive mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. +- If `x1_i` and `x2_i` have different mathematical signs, the result has a negative mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. +- If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. +- If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. +- If `x1_i` is a nonzero finite number and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. +- In the remaining cases, where neither `infinity` nor `NaN` is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. + +```{note} + +Floating-point multiplication is not always associative due to finite precision. +``` + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise products. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`multiply(x1, x2)`](elementwise_functions.md#multiplyx1-x2-). +``` + +(method-__ne__)= +### \_\_ne\_\_(self, other, /) + +Computes the truth value of `self_i != other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool` (i.e., must be a boolean array). + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`not_equal(x1, x2)`](elementwise_functions.md#not_equalx1-x2-). +``` + +(method-__neg__)= +### \_\_neg\_\_(self, /) + +Evaluates `-self_i` for each element of an array instance. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated result for each element in `self`. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`negative(x)`](elementwise_functions.md#negativex-). +``` + +(method-__or__)= +### \_\_or\_\_(self, other, /) + +Evaluates `self_i | other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. Must have an integer or boolean data type. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). Must have an integer or boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`positive(x1, x2)`](elementwise_functions.md#bitwise_orx1-x2-). +``` + +(method-__pos__)= +### \_\_pos\_\_(self, /) + +Evaluates `+self_i` for each element of an array instance. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated result for each element. The returned array must have the same data type as `self`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`positive(x)`](elementwise_functions.md#positivex-). +``` + +(method-__pow__)= +### \_\_pow\_\_(self, other, /) + +Calculates an implementation-dependent approximation of exponentiation by raising each element (the base) of an array instance to the power of `other_i` (the exponent), where `other_i` is the corresponding element of the array `other`. + +#### Special Cases + +For floating-point operands, let `self` equal `x1` and `other` equal `x2`. + +- If `x1_i` is not equal to `1` and `x2_i` is `NaN`, the result is `NaN`. +- If `x2_i` is `+0`, the result is `1`, even if `x1_i` is `NaN`. +- If `x2_i` is `-0`, the result is `1`, even if `x1_i` is `NaN`. +- If `x1_i` is `NaN` and `x2_i` is not equal to `0`, the result is `NaN`. +- If `abs(x1_i)` is greater than `1` and `x2_i` is `+infinity`, the result is `+infinity`. +- If `abs(x1_i)` is greater than `1` and `x2_i` is `-infinity`, the result is `+0`. +- If `abs(x1_i)` is `1` and `x2_i` is `+infinity`, the result is `1`. +- If `abs(x1_i)` is `1` and `x2_i` is `-infinity`, the result is `1`. +- If `x1_i` is `1` and `x2_i` is not `NaN`, the result is `1`. +- If `abs(x1_i)` is less than `1` and `x2_i` is `+infinity`, the result is `+0`. +- If `abs(x1_i)` is less than `1` and `x2_i` is `-infinity`, the result is `+infinity`. +- If `x1_i` is `+infinity` and `x2_i` is greater than `0`, the result is `+infinity`. +- If `x1_i` is `+infinity` and `x2_i` is less than `0`, the result is `+0`. +- If `x1_i` is `-infinity` and `x2_i` is greater than `0`, the result is `-infinity`. +- If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. +- If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-0`. +- If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `+infinity`. +- If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. +- If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+0`. +- If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. +- If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. +- If `x1_i` is less than `0`, `x1_i` is a finite number, `x2_i` is a finite number, and `x2_i` is not an integer value, the result is `NaN`. + +#### Parameters + +- **self**: _<array>_ + + - array instance whose elements correspond to the exponentiation base. + +- **other**: _<array>_ + + - other array whose elements correspond to the exponentiation exponent. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`pow(x1, x2)`](elementwise_functions.md#powx1-x2-). +``` + +(method-__rshift__)= +### \_\_rshift\_\_(self, other, /) + +Evaluates `self_i >> other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. Must have an integer data type. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). Must have an integer data type. Each element must be greater than or equal to `0`. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have the same data type as `self`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`bitwise_right_shift(x1, x2)`](elementwise_functions.md#bitwise_right_shiftx1-x2-). +``` + +(method-__setitem__)= +### \_\_setitem\_\_(self, key, value, /) + +_TODO: dependent on the indexing specification._ + +(method-__sub__)= +### \_\_sub\_\_(self, other, /) + +Calculates the difference for each element of an array instance with the respective element of the array `other`. The result of `self_i - other_i` must be the same as `self_i + (-other_i)` and must be governed by the same floating-point rules as addition (see [`__add__()`](#__add__self-other-)). + +#### Parameters + +- **self**: _<array>_ + + - array instance (minuend array). + +- **other**: _<array>_ + + - subtrahend array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise differences. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`subtract(x1, x2)`](elementwise_functions.md#subtractx1-x2-). +``` + +(method-__truediv__)= +### \_\_truediv\_\_(self, other, /) + +Evaluates `self_i / other_i` for each element of an array instance with the respective element of the array `other`. + +#### Special Cases + +For floating-point operands, let `self` equal `x1` and `other` equal `x2`. + +- If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. +- If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. +- If `x1_i` is either `+0` or `-0` and `x2_i` is either `+0` or `-0`, the result is `NaN`. +- If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. +- If `x1_i` is `-0` and `x2_i` is greater than `0`, the result `-0`. +- If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `-0`. +- If `x1_i` is `-0` and `x2_i` is less than `0`, the result is `+0`. +- If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is `+infinity`. +- If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is `-infinity`. +- If `x1_i` is less than `0` and `x2_i` is `+0`, the result is `-infinity`. +- If `x1_i` is less than `0` and `x2_i` is `-0`, the result is `+infinity`. +- If `x1_i` is `+infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `+infinity`. +- If `x1_i` is `+infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `-infinity`. +- If `x1_i` is `-infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `-infinity`. +- If `x1_i` is `-infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `+infinity`. +- If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `+infinity`, the result is `+0`. +- If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `-infinity`, the result is `-0`. +- If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `+infinity`, the result is `-0`. +- If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `-infinity`, the result is `+0`. +- If `x1_i` and `x2_i` have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. +- If `x1_i` and `x2_i` have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. +- In the remaining cases, where neither `-infinity`, `+0`, `-0`, nor `NaN` is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. + +#### Parameters + +- **self**: _<array>_ + + - array instance. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`divide(x1, x2)`](elementwise_functions.md#dividex1-x2-). +``` + +(method-__xor__)= +### \_\_xor\_\_(self, other, /) + +Evaluates `self_i ^ other_i` for each element of an array instance with the respective element of the array `other`. + +#### Parameters + +- **self**: _<array>_ + + - array instance. Must have an integer or boolean data type. + +- **other**: _<array>_ + + - other array. Must be compatible with `self` (see {ref}`broadcasting`). Must have an integer or boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +```{note} + +Element-wise results must equal the results returned by the equivalent element-wise function [`bitwise_xor(x1, x2)`](elementwise_functions.md#bitwise_xorx1-x2-). +``` diff --git a/latest/_sources/API_specification/broadcasting.md.txt b/latest/_sources/API_specification/broadcasting.md.txt new file mode 100644 index 000000000..34e90cd0b --- /dev/null +++ b/latest/_sources/API_specification/broadcasting.md.txt @@ -0,0 +1,116 @@ +(broadcasting)= + +# Broadcasting + +> Array API specification for broadcasting semantics. + +## Overview + +**Broadcasting** refers to the automatic (implicit) expansion of array dimensions to be of equal sizes without copying array data for the purpose of making arrays with different shapes have compatible shapes for element-wise operations. + +Broadcasting facilitates user ergonomics by encouraging users to avoid unnecessary copying of array data and can **potentially** enable more memory-efficient element-wise operations through vectorization, reduced memory consumption, and cache locality. + +## Algorithm + +Given an element-wise operation involving two compatible arrays, an array having a singleton dimension (i.e., a dimension whose size is one) is broadcast (i.e., virtually repeated) across an array having a corresponding non-singleton dimension. + +If two arrays are of unequal rank, the array having a lower rank is promoted to a higher rank by (virtually) prepending singleton dimensions until the number of dimensions matches that of the array having a higher rank. + +The results of the element-wise operation must be stored in an array having a shape determined by the following algorithm. + +1. Let `A` and `B` both be arrays. + +1. Let `shape1` be a tuple describing the shape of array `A`. + +1. Let `shape2` be a tuple describing the shape of array `B`. + +1. Let `N1` be the number of dimensions of array `A` (i.e., the result of `len(shape1)`). + +1. Let `N2` be the number of dimensions of array `B` (i.e., the result of `len(shape2)`). + +1. Let `N` be the maximum value of `N1` and `N2` (i.e., the result of `max(N1, N2)`). + +1. Let `shape` be a temporary list of length `N` for storing the shape of the result array. + +1. Let `i` be `N-1`. + +1. Repeat, while `i >= 0` + + 1. Let `n1` be `N1 - N + i`. + + 1. If `n1 >= 0`, let `d1` be the size of dimension `n1` for array `A` (i.e., the result of `shape1[n1]`); else, let `d1` be `1`. + + 1. Let `n2` be `N2 - N + i`. + + 1. If `n2 >= 0`, let `d2` be the size of dimension `n2` for array `B` (i.e., the result of `shape2[n2]`); else, let `d2` be `1`. + + 1. If `d1 == 1`, then + + - set the `i`th element of `shape` to `d2`. + + 1. Else, if `d2 == 1`, then + + - set the `i`th element of `shape` to `d1`. + + 1. Else, if `d1 == d2`, then + + - set the `i`th element of `shape` to `d1`. + + 1. Else, throw an exception. + + 1. Set `i` to `i-1`. + +1. Let `tuple(shape)` be the shape of the result array. + +### Examples + +The following examples demonstrate the application of the broadcasting algorithm for two compatible arrays. + +```text +A (4d array): 8 x 1 x 6 x 1 +B (3d array): 7 x 1 x 5 +--------------------------------- +Result (4d array): 8 x 7 x 6 x 5 + +A (2d array): 5 x 4 +B (1d array): 1 +------------------------- +Result (2d array): 5 x 4 + +A (2d array): 5 x 4 +B (1d array): 4 +------------------------- +Result (2d array): 5 x 4 + +A (3d array): 15 x 3 x 5 +B (3d array): 15 x 1 x 5 +------------------------------ +Result (3d array): 15 x 3 x 5 + +A (3d array): 15 x 3 x 5 +B (2d array): 3 x 5 +------------------------------ +Result (3d array): 15 x 3 x 5 + +A (3d array): 15 x 3 x 5 +B (2d array): 3 x 1 +------------------------------ +Result (3d array): 15 x 3 x 5 +``` + +The following examples demonstrate array shapes which do **not** broadcast. + +```text +A (1d array): 3 +B (1d array): 4 # dimension does not match + +A (2d array): 2 x 1 +B (3d array): 8 x 4 x 3 # second dimension does not match + +A (3d array): 15 x 3 x 5 +B (2d array): 15 x 3 # singleton dimensions can only be prepended, not appended +``` + +## In-place Semantics + +As implied by the broadcasting algorithm, in-place element-wise operations must not change the shape of the in-place array as a result of broadcasting. \ No newline at end of file diff --git a/latest/_sources/API_specification/constants.md.txt b/latest/_sources/API_specification/constants.md.txt new file mode 100644 index 000000000..4a9cd040f --- /dev/null +++ b/latest/_sources/API_specification/constants.md.txt @@ -0,0 +1,37 @@ +# Constants + +> Array API specification for constants. + +A conforming implementation of the array API standard must provide and support the following constants. + + + +## Objects in API + +(constant-e)= +### e + +Euler's constant. + +```text +e = 2.71828182845904523536028747135266249775724709369995... +``` + +(constant-inf)= +### inf + +IEEE 754 floating-point representation of (positive) infinity. + +(constant-nan)= +### nan + +IEEE 754 floating-point representation of Not a Number (`NaN`). + +(constant-pi)= +### pi + +The mathematical constant `π`. + +```text +pi = 3.1415926535897932384626433... +``` diff --git a/latest/_sources/API_specification/creation_functions.md.txt b/latest/_sources/API_specification/creation_functions.md.txt new file mode 100644 index 000000000..a072bd968 --- /dev/null +++ b/latest/_sources/API_specification/creation_functions.md.txt @@ -0,0 +1,390 @@ +# Creation Functions + +> Array API specification for creating arrays. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. + +## Objects in API + + + +(function-arange)= +### arange(start, /, *, stop=None, step=1, dtype=None, device=None) + +Returns evenly spaced values within the half-open interval `[start, stop)` as a one-dimensional array. + +#### Parameters + +- **start**: _Union\[ int, float ]_ + + - if `stop` is specified, the start of interval (inclusive); otherwise, the end of the interval (exclusive). If `stop` is not specified, the default starting value is `0`. + +- **stop**: _Optional\[ Union\[ int, float ] ]_ + + - the end of the interval. Default: `None`. + +```{note} + +This function cannot guarantee that the interval does not include the `stop` value in those cases where `step` is not an integer and floating-point rounding errors affect the length of the output array. +``` + +- **step**: _Union\[ int, float ]_ + + - the distance between two adjacent elements (`out[i+1] - out[i]`). Default: `1`. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be the default floating-point data type. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - a one-dimensional array containing evenly spaced values. The length of the output array must be `ceil((stop-start)/step)`. + + +(function-asarray)= +### asarray(obj, /, *, dtype=None, device=None, copy=None) + +Convert the input to an array. + +#### Parameters + +- **obj**: _Union\[ float, NestedSequence\[ bool | int | float ], SupportsDLPack, SupportsBufferProtocol ]_ + + - Object to be converted to an array. Can be a Python scalar, a (possibly nested) sequence of Python scalars, or an object supporting DLPack or the Python buffer protocol. + + :::{tip} + An object supporting DLPack has `__dlpack__` and `__dlpack_device__` methods. + An object supporting the buffer protocol can be turned into a memoryview through `memoryview(obj)`. + ::: + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be inferred from the data type(s) in `obj`. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. Default: `None`. + +- **copy**: _Optional\[ bool ]_ + + - Whether or not to make a copy of the input. If `True`, always copies. If `False`, never copies for input which supports DLPack or the buffer protocol, and raises `ValueError` in case that would be necessary. If `None`, reuses existing memory buffer if possible, copies otherwise. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - An array containing the data from `obj`. + + +(function-empty)= +### empty(shape, /, *, dtype=None, device=None) + +Returns an uninitialized array having a specified `shape`. + +#### Parameters + +- **shape**: _Union\[ int, Tuple\[ int, ... ] ]_ + + - output array shape. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be the default floating-point data type. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array containing uninitialized data. + +(function-empty_like)= +### empty_like(x, /, *, dtype=None, device=None) + +Returns an uninitialized array with the same `shape` as an input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array from which to derive the output array shape. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be inferred from `x`. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. If `device` is `None`, the default device must be used, not `x.device`. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array having the same shape as `x` and containing uninitialized data. + +(function-eye)= +### eye(N, /, *, M=None, k=0, dtype=None, device=None) + +Returns a two-dimensional array with ones on the `k`th diagonal and zeros elsewhere. + +#### Parameters + +- **N**: _int_ + + - number of rows in the output array. + +- **M**: _Optional\[ int ]_ + + - number of columns in the output array. If `None`, the default number of columns in the output array is `N`. Default: `None`. + +- **k**: _Optional\[ int ]_ + + - index of the diagonal. A positive value refers to an upper diagonal, a negative value to a lower diagonal, and `0` to the main diagonal. Default: `0`. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be the default floating-point data type. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array where all elements are equal to zero, except for the `k`th diagonal, whose values are equal to one. + +(function-from_dlpack)= +### from_dlpack(x, /) + +Returns a new array containing the data from another (array) object with a `__dlpack__` method. + +#### Parameters + +- **x**: _object_ + + - input (array) object. + +#### Returns + +- **out**: _<array>_ + + - an array containing the data in `x`. + + ```{note} + The returned array may be either a copy or a view. See {ref}`data-interchange` for details. + ``` + +(function-full)= +### full(shape, fill_value, /, *, dtype=None, device=None) + +Returns a new array having a specified `shape` and filled with `fill_value`. + +#### Parameters + +- **shape**: _Union\[ int, Tuple\[ int, ... ] ]_ + + - output array shape. + +- **fill_value**: _Union\[ int, float ]_ + + - fill value. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be the default floating-point data type. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array where every element is equal to `fill_value`. + +(function-full_like)= +### full_like(x, fill_value, /, *, dtype=None, device=None) + +Returns a new array filled with `fill_value` and having the same `shape` as an input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array from which to derive the output array shape. + +- **fill_value**: _Union\[ int, float ]_ + + - fill value. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be inferred from `x`. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. If `device` is `None`, the default device must be used, not `x.device`. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array having the same shape as `x` and where every element is equal to `fill_value`. + +(function-linspace)= +### linspace(start, stop, num, /, *, dtype=None, device=None, endpoint=True) + +Returns evenly spaced numbers over a specified interval. + +#### Parameters + +- **start**: _Union\[ int, float ]_ + + - the start of the interval. + +- **stop**: _Union\[ int, float ]_ + + - the end of the interval. If `endpoint` is `False`, the function must generate a sequence of `num+1` evenly spaced numbers starting with `start` and ending with `stop` and exclude the `stop` from the returned array such that the returned array consists of evenly spaced numbers over the half-open interval `[start, stop)`. If `endpoint` is `True`, the output array must consist of evenly spaced numbers over the closed interval `[start, stop]`. Default: `True`. + + ```{note} + + The step size changes when `endpoint` is `False`. + ``` + +- **num**: _int_ + + - number of samples. Must be a non-negative integer value; otherwise, the function must raise an exception. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be the default floating-point data type. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. Default: `None`. + +- **endpoint**: _bool_ + + - boolean indicating whether to include `stop` in the interval. Default: `True`. + +#### Returns + +- **out**: _<array>_ + + - a one-dimensional array containing evenly spaced values. + +(function-ones)= +### ones(shape, /, *, dtype=None, device=None) + +Returns a new array having a specified `shape` and filled with ones. + +#### Parameters + +- **shape**: _Union\[ int, Tuple\[ int, ... ] ]_ + + - output array shape. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be the default floating-point data type. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array containing ones. + +(function-ones_like)= +### ones_like(x, /, *, dtype=None, device=None) + +Returns a new array filled with ones and having the same `shape` as an input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array from which to derive the output array shape. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be inferred from `x`. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. If `device` is `None`, the default device must be used, not `x.device`. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array having the same shape as `x` and filled with ones. + +(function-zeros)= +### zeros(shape, /, *, dtype=None, device=None) + +Returns a new array having a specified `shape` and filled with zeros. + +#### Parameters + +- **shape**: _Union\[ int, Tuple\[ int, ... ] ]_ + + - output array shape. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be the default floating-point data type. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array containing zeros. + +(function-zeros_like)= +### zeros_like(x, /, *, dtype=None, device=None) + +Returns a new array filled with zeros and having the same `shape` as an input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array from which to derive the output array shape. + +- **dtype**: _Optional\[ <dtype> ]_ + + - output array data type. If `dtype` is `None`, the output array data type must be inferred from `x`. Default: `None`. + +- **device**: _Optional\[ <device> ]_ + + - device to place the created array on, if given. If `device` is `None`, the default device must be used, not `x.device`. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array having the same shape as `x` and filled with zeros. diff --git a/latest/_sources/API_specification/data_type_functions.md.txt b/latest/_sources/API_specification/data_type_functions.md.txt new file mode 100644 index 000000000..0da170084 --- /dev/null +++ b/latest/_sources/API_specification/data_type_functions.md.txt @@ -0,0 +1,81 @@ +# Data type functions + +> Array API specification for data type functions. + +A conforming implementation of the array API standard must provide and support the following data type functions. + + + +## Objects in API + +(function-finfo)= +### finfo(type, /) + +Machine limits for floating-point data types. + +#### Parameters + +- **type**: _Union\[ <dtype>, <array> ]_ + + - the kind of floating-point data-type about which to get information. + +#### Returns + +- **out**: _<finfo object>_ + + - an object having the following attributes: + + - **bits**: _int_ + - number of bits occupied by the floating-point data type. + - **eps**: _float_ + - difference between 1.0 and the next smallest representable floating-point number larger than 1.0 according to the IEEE-754 standard. + - **max**: _float_ + - largest representable number. + - **min**: _float_ + - smallest representable number. + +(function-iinfo)= +### iinfo(type, /) + +Machine limits for integer data types. + +#### Parameters + +- **type**: _Union\[ <dtype>, <array> ]_ + + - the kind of integer data-type about which to get information. + +#### Returns + +- **out**: _<iinfo object>_ + + - a class with that encapsules the following attributes: + + - **bits**: _int_ + - number of bits occupied by the type + - **max**: _int_ + - largest representable number. + - **min**: _int_ + - smallest representable number. + +(function-result_type)= +### result_type(*arrays_and_dtypes) + +Returns the dtype that results from applying the type promotion rules +(see {ref}`type-promotion`) to the arguments. + +```{note} +If provided mixed dtypes (e.g., integer and floating-point), the returned dtype will be implementation-specific. +``` + +#### Parameters + +- **arrays_and_dtypes**: _Sequence\[ Union\[ <array>, <dtype> \] \]_ + + - input arrays and dtypes. + +#### Returns + +- **out**: _<dtype>_ + + - the dtype resulting from an operation involving the input arrays and dtypes. diff --git a/latest/_sources/API_specification/data_types.md.txt b/latest/_sources/API_specification/data_types.md.txt new file mode 100644 index 000000000..b1c83b4d5 --- /dev/null +++ b/latest/_sources/API_specification/data_types.md.txt @@ -0,0 +1,106 @@ +(data-types)= + +# Data Types + +> Array API specification for supported data types. + +A conforming implementation of the array API standard must provide and support the following data types. + +A conforming implementation of the array API standard must define a default floating-point data type (either `float32` or `float64`), as well as a default data type for an array index (either `int32` or `int64`). + +```{note} + +The default floating-point and array index integer data types should be clearly defined in a conforming library's documentation. +``` + + +## bool + +Boolean (`True` or `False`). + +## int8 + +An 8-bit signed integer whose values exist on the interval `[-128, +127]`. + +## int16 + +A 16-bit signed integer whose values exist on the interval `[−32,767, +32,767]`. + +## int32 + +A 32-bit signed integer whose values exist on the interval `[−2,147,483,647, +2,147,483,647]`. + +## int64 + +A 64-bit signed integer whose values exist on the interval `[−9,223,372,036,854,775,807, +9,223,372,036,854,775,807]`. + +## uint8 + +An 8-bit unsigned integer whose values exist on the interval `[0, +255]`. + +## uint16 + +A 16-bit unsigned integer whose values exist on the interval `[0, +65,535]`. + +## uint32 + +A 32-bit unsigned integer whose values exist on the interval `[0, +4,294,967,295]`. + +## uint64 + +A 64-bit unsigned integer whose values exist on the interval `[0, +18,446,744,073,709,551,615]`. + +## float32 + +IEEE 754 single-precision (32-bit) binary floating-point number (see IEEE 754-2019). + +## float64 + +IEEE 754 double-precision (64-bit) binary floating-point number (see IEEE 754-2019). + + +:::{admonition} Future extension +:class: hint +It is expected that in the next version of this standard, `complex64` and `complex128` +dtypes will be added, with these casting rules (will be added to {ref}`type-promotion`): + +![Type promotion diagram for complex dtypes in next version](/_static/images/dtype_promotion_complex.png) + +See [array-api/issues/102](https://github.com/data-apis/array-api/issues/102) +for more details. +::: + +```{note} +Data types ("dtypes") are objects that can be used as `dtype` specifiers in functions and methods (e.g., `zeros((2, 3), dtype=float32)`). A conforming implementation may add methods or attributes to data type objects; however, these methods and attributes are not included in this specification. + +Implementations may provide other ways to specify data types (e.g., +`zeros((2, 3), dtype='f4')`); however, these are not included in this specification. + +A conforming implementation of the array API standard may provide and support additional data types beyond those described in this specification. +``` + +(data-type-categories)= +## Data Type Categories + +For the purposes of this specification, the following data type categories are defined. +Libraries do not need to organize dtypes according to these categories. These +are only for organizing the functions in this specification itself. Future versions of +the specification will include additional categories for complex data types. + +### Numeric Data Types + +`int8`, `int16`, `int32`, `int64`, `uint8`, `uint16`, `uint32`, +`uint64`, `float32`, and `float64` (i.e., all dtypes except for `bool`). + +### Integer Data Types + +`int8`, `int16`, `int32`, `int64`, `uint8`, `uint16`, `uint32`, and +`uint64`. + +### Floating-point Data Types + +`float32` and `float64`. + +### Boolean Data Types + +`bool`. diff --git a/latest/_sources/API_specification/elementwise_functions.md.txt b/latest/_sources/API_specification/elementwise_functions.md.txt new file mode 100644 index 000000000..3dcf0dcf4 --- /dev/null +++ b/latest/_sources/API_specification/elementwise_functions.md.txt @@ -0,0 +1,1443 @@ +(element-wise-functions)= + +# Element-wise Functions + +> Array API specification for element-wise functions. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Broadcasting semantics must follow the semantics defined in {ref}`broadcasting`. +- Unless stated otherwise, functions must support the data types defined in {ref}`data-types`. +- Functions may only be required for a subset of input data type. Libraries may choose to implement functions for additional data types, but that behavior is not required by the specification. See {ref}`data-type-categories`. +- Unless stated otherwise, functions must adhere to the type promotion rules defined in {ref}`type-promotion`. +- Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. +- Unless stated otherwise, element-wise mathematical functions must satisfy the minimum accuracy requirements defined in {ref}`accuracy`. + +## Objects in API + + + +(function-abs)= +### abs(x, /) + +Calculates the absolute value for each element `x_i` of the input array `x` (i.e., the element-wise result has the same magnitude as the respective element in `x` but has positive sign). + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `-0`, the result is `+0`. +- If `x_i` is `-infinity`, the result is `+infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the absolute value of each element in `x`. The returned array must have the same data type as `x`. + +(function-acos)= +### acos(x, /) + +Calculates an implementation-dependent approximation of the principal value of the inverse cosine, having domain `[-1, +1]` and codomain `[+0, +π]`, for each element `x_i` of the input array `x`. Each element-wise result is expressed in radians. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is greater than `1`, the result is `NaN`. +- If `x_i` is less than `-1`, the result is `NaN`. +- If `x_i` is `1`, the result is `+0`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the inverse cosine of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-acosh)= +### acosh(x, /) + +Calculates an implementation-dependent approximation to the inverse hyperbolic cosine, having domain `[+1, +infinity]` and codomain `[+0, +infinity]`, for each element `x_i` of the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is less than `1`, the result is `NaN`. +- If `x_i` is `1`, the result is `+0`. +- If `x_i` is `+infinity`, the result is `+infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements each represent the area of a hyperbolic sector. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the inverse hyperbolic cosine of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-add)= +### add(x1, x2, /) + +Calculates the sum for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Special Cases + +For floating-point operands, + +- If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. +- If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is `NaN`. +- If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is `NaN`. +- If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is `+infinity`. +- If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is `-infinity`. +- If `x1_i` is `+infinity` and `x2_i` is a finite number, the result is `+infinity`. +- If `x1_i` is `-infinity` and `x2_i` is a finite number, the result is `-infinity`. +- If `x1_i` is a finite number and `x2_i` is `+infinity`, the result is `+infinity`. +- If `x1_i` is a finite number and `x2_i` is `-infinity`, the result is `-infinity`. +- If `x1_i` is `-0` and `x2_i` is `-0`, the result is `-0`. +- If `x1_i` is `-0` and `x2_i` is `+0`, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is `-0`, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. +- If `x1_i` is either `+0` or `-0` and `x2_i` is a nonzero finite number, the result is `x2_i`. +- If `x1_i` is a nonzero finite number and `x2_i` is either `+0` or `-0`, the result is `x1_i`. +- If `x1_i` is a nonzero finite number and `x2_i` is `-x1_i`, the result is `+0`. +- In the remaining cases, when neither `infinity`, `+0`, `-0`, nor a `NaN` is involved, and the operands have the same mathematical sign or have different magnitudes, the sum must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported round mode. If the magnitude is too large to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. + +```{note} + +Floating-point addition is a commutative operation, but not always associative. +``` + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise sums. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-asin)= +### asin(x, /) + +Calculates an implementation-dependent approximation of the principal value of the inverse sine, having domain `[-1, +1]` and codomain `[-π/2, +π/2]` for each element `x_i` of the input array `x`. Each element-wise result is expressed in radians. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is greater than `1`, the result is `NaN`. +- If `x_i` is less than `-1`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the inverse sine of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-asinh)= +### asinh(x, /) + +Calculates an implementation-dependent approximation to the inverse hyperbolic sine, having domain `[-infinity, +infinity]` and codomain `[-infinity, +infinity]`, for each element `x_i` in the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is `+infinity`, the result is `+infinity`. +- If `x_i` is `-infinity`, the result is `-infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements each represent the area of a hyperbolic sector. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the inverse hyperbolic sine of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-atan)= +### atan(x, /) + +Calculates an implementation-dependent approximation of the principal value of the inverse tangent, having domain `[-infinity, +infinity]` and codomain `[-π/2, +π/2]`, for each element `x_i` of the input array `x`. Each element-wise result is expressed in radians. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is `+infinity`, the result is an implementation-dependent approximation to `+π/2`. +- If `x_i` is `-infinity`, the result is an implementation-dependent approximation to `-π/2`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the inverse tangent of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-atan2)= +### atan2(x1, x2, /) + +Calculates an implementation-dependent approximation of the inverse tangent of the quotient `x1/x2`, having domain `[-infinity, +infinity] x [-infinity, +infinity]` (where the `x` notation denotes the set of ordered pairs of elements `(x1_i, x2_i)`) and codomain `[-π, +π]`, for each pair of elements `(x1_i, x2_i)` of the input arrays `x1` and `x2`, respectively. Each element-wise result is expressed in radians. + +The mathematical signs of `x1_i` and `x2_i` determine the quadrant of each element-wise result. The quadrant (i.e., branch) is chosen such that each element-wise result is the signed angle in radians between the ray ending at the origin and passing through the point `(1,0)` and the ray ending at the origin and passing through the point `(x2_i, x1_i)`. + +```{note} + +Note the role reversal: the "y-coordinate" is the first function parameter; the "x-coordinate" is the second function parameter. The parameter order is intentional and traditional for the two-argument inverse tangent function where the y-coordinate argument is first and the x-coordinate argument is second. +``` + +By IEEE 754 convention, the inverse tangent of the quotient `x1/x2` is defined for `x2_i` equal to positive or negative zero and for either or both of `x1_i` and `x2_i` equal to positive or negative `infinity`. + +#### Special Cases + +For floating-point operands, + +- If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. +- If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is an implementation-dependent approximation to `+π/2`. +- If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is an implementation-dependent approximation to `+π/2`. +- If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is `+0`, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is `-0`, the result is an implementation-dependent approximation to `+π`. +- If `x1_i` is `+0` and `x2_i` is less than `0`, the result is an implementation-dependent approximation to `+π`. +- If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. +- If `x1_i` is `-0` and `x2_i` is `+0`, the result is `-0`. +- If `x1_i` is `-0` and `x2_i` is `-0`, the result is an implementation-dependent approximation to `-π`. +- If `x1_i` is `-0` and `x2_i` is less than `0`, the result is an implementation-dependent approximation to `-π`. +- If `x1_i` is less than `0` and `x2_i` is `+0`, the result is an implementation-dependent approximation to `-π/2`. +- If `x1_i` is less than `0` and `x2_i` is `-0`, the result is an implementation-dependent approximation to `-π/2`. +- If `x1_i` is greater than `0`, `x1_i` is a finite number, and `x2_i` is `+infinity`, the result is `+0`. +- If `x1_i` is greater than `0`, `x1_i` is a finite number, and `x2_i` is `-infinity`, the result is an implementation-dependent approximation to `+π`. +- If `x1_i` is less than `0`, `x1_i` is a finite number, and `x2_i` is `+infinity`, the result is `-0`. +- If `x1_i` is less than `0`, `x1_i` is a finite number, and `x2_i` is `-infinity`, the result is an implementation-dependent approximation to `-π`. +- If `x1_i` is `+infinity` and `x2_i` is finite, the result is an implementation-dependent approximation to `+π/2`. +- If `x1_i` is `-infinity` and `x2_i` is finite, the result is an implementation-dependent approximation to `-π/2`. +- If `x1_i` is `+infinity` and `x2_i` is `+infinity`, the result is an implementation-dependent approximation to `+π/4`. +- If `x1_i` is `+infinity` and `x2_i` is `-infinity`, the result is an implementation-dependent approximation to `+3π/4`. +- If `x1_i` is `-infinity` and `x2_i` is `+infinity`, the result is an implementation-dependent approximation to `-π/4`. +- If `x1_i` is `-infinity` and `x2_i` is `-infinity`, the result is an implementation-dependent approximation to `-3π/4`. + +#### Parameters + +- **x1**: _<array>_ + + - input array corresponding to the y-coordinates. Should have a floating-point data type. + +- **x2**: _<array>_ + + - input array corresponding to the x-coordinates. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the inverse tangent of the quotient `x1/x2`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-atanh)= +### atanh(x, /) + +Calculates an implementation-dependent approximation to the inverse hyperbolic tangent, having domain `[-1, +1]` and codomain `[-infinity, +infinity]`, for each element `x_i` of the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is less than `-1`, the result is `NaN`. +- If `x_i` is greater than `1`, the result is `NaN`. +- If `x_i` is `-1`, the result is `-infinity`. +- If `x_i` is `+1`, the result is `+infinity`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements each represent the area of a hyperbolic sector. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the inverse hyperbolic tangent of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-bitwise_and)= +### bitwise_and(x1, x2, /) + +Computes the bitwise AND of the underlying binary representation of each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have an integer or boolean data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have an integer or boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-bitwise_left_shift)= +### bitwise_left_shift(x1, x2, /) + +Shifts the bits of each element `x1_i` of the input array `x1` to the left by appending `x2_i` (i.e., the respective element in the input array `x2`) zeros to the right of `x1_i`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have an integer data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have an integer data type. Each element must be greater than or equal to `0`. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have the same data type as `x1`. + +(function-bitwise_invert)= +### bitwise_invert(x, /) + +Inverts (flips) each bit for each element `x_i` of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have an integer or boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have the same data type as `x`. + +(function-bitwise_or)= +### bitwise_or(x1, x2, /) + +Computes the bitwise OR of the underlying binary representation of each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have an integer or boolean data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have an integer or boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-bitwise_right_shift)= +### bitwise_right_shift(x1, x2, /) + +Shifts the bits of each element `x1_i` of the input array `x1` to the right according to the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have an integer data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have an integer data type. Each element must be greater than or equal to `0`. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have the same data type as `x1`. + +(function-bitwise_xor)= +### bitwise_xor(x1, x2, /) + +Computes the bitwise XOR of the underlying binary representation of each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have an integer or boolean data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have an integer or boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-ceil)= +### ceil(x, /) + +Rounds each element `x_i` of the input array `x` to the smallest (i.e., closest to `-infinity`) integer-valued number that is not less than `x_i`. + +#### Special Cases + +- If `x_i` is already integer-valued, the result is `x_i`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the rounded result for each element in `x`. The returned array must have the same data type as `x`. + +(function-cos)= +### cos(x, /) + +Calculates an implementation-dependent approximation to the cosine, having domain `(-infinity, +infinity)` and codomain `[-1, +1]`, for each element `x_i` of the input array `x`. Each element `x_i` is assumed to be expressed in radians. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `1`. +- If `x_i` is `-0`, the result is `1`. +- If `x_i` is `+infinity`, the result is `NaN`. +- If `x_i` is `-infinity`, the result is `NaN`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements are each expressed in radians. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the cosine of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-cosh)= +### cosh(x, /) + +Calculates an implementation-dependent approximation to the hyperbolic cosine, having domain `[-infinity, +infinity]` and codomain `[-infinity, +infinity]`, for each element `x_i` in the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `1`. +- If `x_i` is `-0`, the result is `1`. +- If `x_i` is `+infinity`, the result is `+infinity`. +- If `x_i` is `-infinity`, the result is `+infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements each represent a hyperbolic angle. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the hyperbolic cosine of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-divide)= +### divide(x1, x2, /) + +Calculates the division for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Special Cases + +For floating-point operands, + +- If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. +- If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. +- If `x1_i` is either `+0` or `-0` and `x2_i` is either `+0` or `-0`, the result is `NaN`. +- If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. +- If `x1_i` is `-0` and `x2_i` is greater than `0`, the result is `-0`. +- If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `-0`. +- If `x1_i` is `-0` and `x2_i` is less than `0`, the result is `+0`. +- If `x1_i` is greater than `0` and `x2_i` is `+0`, the result is `+infinity`. +- If `x1_i` is greater than `0` and `x2_i` is `-0`, the result is `-infinity`. +- If `x1_i` is less than `0` and `x2_i` is `+0`, the result is `-infinity`. +- If `x1_i` is less than `0` and `x2_i` is `-0`, the result is `+infinity`. +- If `x1_i` is `+infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `+infinity`. +- If `x1_i` is `+infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `-infinity`. +- If `x1_i` is `-infinity` and `x2_i` is a positive (i.e., greater than `0`) finite number, the result is `-infinity`. +- If `x1_i` is `-infinity` and `x2_i` is a negative (i.e., less than `0`) finite number, the result is `+infinity`. +- If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `+infinity`, the result is `+0`. +- If `x1_i` is a positive (i.e., greater than `0`) finite number and `x2_i` is `-infinity`, the result is `-0`. +- If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `+infinity`, the result is `-0`. +- If `x1_i` is a negative (i.e., less than `0`) finite number and `x2_i` is `-infinity`, the result is `+0`. +- If `x1_i` and `x2_i` have the same mathematical sign and are both nonzero finite numbers, the result has a positive mathematical sign. +- If `x1_i` and `x2_i` have different mathematical signs and are both nonzero finite numbers, the result has a negative mathematical sign. +- In the remaining cases, where neither `-infinity`, `+0`, `-0`, nor `NaN` is involved, the quotient must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too larger to represent, the operation overflows and the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the operation underflows and the result is a zero of appropriate mathematical sign. + +#### Parameters + +- **x1**: _<array>_ + + - dividend input array. Should have a floating-point data type. + +- **x2**: _<array>_ + + - divisor input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-equal)= +### equal(x1, x2, /) + +Computes the truth value of `x1_i == x2_i` for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. May have any data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-exp)= +### exp(x, /) + +Calculates an implementation-dependent approximation to the exponential function, having domain `[-infinity, +infinity]` and codomain `[+0, +infinity]`, for each element `x_i` of the input array `x` (`e` raised to the power of `x_i`, where `e` is the base of the natural logarithm). + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `1`. +- If `x_i` is `-0`, the result is `1`. +- If `x_i` is `+infinity`, the result is `+infinity`. +- If `x_i` is `-infinity`, the result is `+0`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated exponential function result for each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-expm1)= +### expm1(x, /) + +Calculates an implementation-dependent approximation to `exp(x)-1`, having domain `[-infinity, +infinity]` and codomain `[-1, +infinity]`, for each element `x_i` of the input array `x`. + +```{note} + +The purpose of this function is to calculate `exp(x)-1.0` more accurately when `x` is close to zero. Accordingly, conforming implementations should avoid implementing this function as simply `exp(x)-1.0`. See FDLIBM, or some other IEEE 754-2019 compliant mathematical library, for a potential reference implementation. +``` + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is `+infinity`, the result is `+infinity`. +- If `x_i` is `-infinity`, the result is `-1`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated result for each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-floor)= +### floor(x, /) + +Rounds each element `x_i` of the input array `x` to the greatest (i.e., closest to `+infinity`) integer-valued number that is not greater than `x_i`. + +#### Special Cases + +- If `x_i` is already integer-valued, the result is `x_i`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the rounded result for each element in `x`. The returned array must have the same data type as `x`. + +(function-floor_divide)= +### floor_divide(x1, x2, /) + +Rounds the result of dividing each element `x1_i` of the input array `x1` by the respective element `x2_i` of the input array `x2` to the greatest (i.e., closest to `+infinity`) integer-value number that is not greater than the division result. + +#### Parameters + +- **x1**: _<array>_ + + - dividend input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - divisor input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-greater)= +### greater(x1, x2, /) + +Computes the truth value of `x1_i > x2_i` for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-greater_equal)= +### greater_equal(x1, x2, /) + +Computes the truth value of `x1_i >= x2_i` for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-isfinite)= +### isfinite(x, /) + +Tests each element `x_i` of the input array `x` to determine if finite (i.e., not `NaN` and not equal to positive or negative infinity). + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing test results. An element `out_i` is `True` if `x_i` is finite and `False` otherwise. The returned array must have a data type of `bool`. + +(function-isinf)= +### isinf(x, /) + +Tests each element `x_i` of the input array `x` to determine if equal to positive or negative infinity. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing test results. An element `out_i` is `True` if `x_i` is either positive or negative infinity and `False` otherwise. The returned array must have a data type of `bool`. + +(function-isnan)= +### isnan(x, /) + +Tests each element `x_i` of the input array `x` to determine whether the element is `NaN`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing test results. An element `out_i` is `True` if `x_i` is `NaN` and `False` otherwise. The returned array should have a data type of `bool`. + +(function-less)= +### less(x1, x2, /) + +Computes the truth value of `x1_i < x2_i` for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-less_equal)= +### less_equal(x1, x2, /) + +Computes the truth value of `x1_i <= x2_i` for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-log)= +### log(x, /) + +Calculates an implementation-dependent approximation to the natural (base `e`) logarithm, having domain `[0, +infinity]` and codomain `[-infinity, +infinity]`, for each element `x_i` of the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is less than `0`, the result is `NaN`. +- If `x_i` is either `+0` or `-0`, the result is `-infinity`. +- If `x_i` is `1`, the result is `+0`. +- If `x_i` is `+infinity`, the result is `+infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated natural logarithm for each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-log1p)= +### log1p(x, /) + +Calculates an implementation-dependent approximation to `log(1+x)`, where `log` refers to the natural (base `e`) logarithm, having domain `[-1, +infinity]` and codomain `[-infinity, +infinity]`, for each element `x_i` of the input array `x`. + +```{note} + +The purpose of this function is to calculate `log(1+x)` more accurately when `x` is close to zero. Accordingly, conforming implementations should avoid implementing this function as simply `log(1+x)`. See FDLIBM, or some other IEEE 754-2019 compliant mathematical library, for a potential reference implementation. +``` + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is less than `-1`, the result is `NaN`. +- If `x_i` is `-1`, the result is `-infinity`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `+infinity`, the result is `+infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated result for each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-log2)= +### log2(x, /) + +Calculates an implementation-dependent approximation to the base `2` logarithm, having domain `[0, +infinity]` and codomain `[-infinity, +infinity]`, for each element `x_i` of the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is less than `0`, the result is `NaN`. +- If `x_i` is either `+0` or `-0`, the result is `-infinity`. +- If `x_i` is `1`, the result is `+0`. +- If `x_i` is `+infinity`, the result is `+infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated base `2` logarithm for each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-log10)= +### log10(x, /) + +Calculates an implementation-dependent approximation to the base `10` logarithm, having domain `[0, +infinity]` and codomain `[-infinity, +infinity]`, for each element `x_i` of the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is less than `0`, the result is `NaN`. +- If `x_i` is either `+0` or `-0`, the result is `-infinity`. +- If `x_i` is `1`, the result is `+0`. +- If `x_i` is `+infinity`, the result is `+infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated base `10` logarithm for each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-logaddexp)= +### logaddexp(x1, x2) + +Calculates the logarithm of the sum of exponentiations `log(exp(x1) + exp(x2))` for +each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array +`x2`. + +#### Special Cases + +For floating-point operands, + +- If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. +- If either `x1_i` or `x2_i` is `+infinity`, the result is `+infinity`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a floating-point + data type determined by {ref}`type-promotion`. + +(function-logical_and)= +### logical_and(x1, x2, /) + +Computes the logical AND for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. Zeros are considered the equivalent of `False`, while non-zeros are considered the equivalent of `True`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a boolean data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-logical_not)= +### logical_not(x, /) + +Computes the logical NOT for each element `x_i` of the input array `x`. Zeros are considered the equivalent of `False`, while non-zeros are considered the equivalent of `True`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-logical_or)= +### logical_or(x1, x2, /) + +Computes the logical OR for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. Zeros are considered the equivalent of `False`, while non-zeros are considered the equivalent of `True`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a boolean data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-logical_xor)= +### logical_xor(x1, x2, /) + +Computes the logical XOR for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. Zeros are considered the equivalent of `False`, while non-zeros are considered the equivalent of `True`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a boolean data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a boolean data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-multiply)= +### multiply(x1, x2, /) + +Calculates the product for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Special Cases + +For floating-point operands, + +- If either `x1_i` or `x2_i` is `NaN`, the result is `NaN`. +- If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+0` or `-0`, the result is `NaN`. +- If `x1_i` is either `+0` or `-0` and `x2_i` is either `+infinity` or `-infinity`, the result is `NaN`. +- If `x1_i` and `x2_i` have the same mathematical sign, the result has a positive mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. +- If `x1_i` and `x2_i` have different mathematical signs, the result has a negative mathematical sign, unless the result is `NaN`. If the result is `NaN`, the "sign" of `NaN` is implementation-defined. +- If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. +- If `x1_i` is either `+infinity` or `-infinity` and `x2_i` is a nonzero finite number, the result is a signed infinity with the mathematical sign determined by the rule already stated above. +- If `x1_i` is a nonzero finite number and `x2_i` is either `+infinity` or `-infinity`, the result is a signed infinity with the mathematical sign determined by the rule already stated above. +- In the remaining cases, where neither `infinity` nor `NaN` is involved, the product must be computed and rounded to the nearest representable value according to IEEE 754-2019 and a supported rounding mode. If the magnitude is too large to represent, the result is an `infinity` of appropriate mathematical sign. If the magnitude is too small to represent, the result is a zero of appropriate mathematical sign. + +```{note} + +Floating-point multiplication is not always associative due to finite precision. +``` + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise products. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-negative)= +### negative(x, /) + +Computes the numerical negative of each element `x_i` (i.e., `y_i = -x_i`) of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated result for each element in `x`. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-not_equal)= +### not_equal(x1, x2, /) + +Computes the truth value of `x1_i != x2_i` for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. May have any data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type of `bool`. + +(function-positive)= +### positive(x, /) + +Computes the numerical positive of each element `x_i` (i.e., `y_i = +x_i`) of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated result for each element in `x`. The returned array must have the same data type as `x`. + +(function-pow)= +### pow(x1, x2, /) + +Calculates an implementation-dependent approximation of exponentiation by raising each element `x1_i` (the base) of the input array `x1` to the power of `x2_i` (the exponent), where `x2_i` is the corresponding element of the input array `x2`. + +#### Special Cases + +For floating-point operands, + +- If `x1_i` is not equal to `1` and `x2_i` is `NaN`, the result is `NaN`. +- If `x2_i` is `+0`, the result is `1`, even if `x1_i` is `NaN`. +- If `x2_i` is `-0`, the result is `1`, even if `x1_i` is `NaN`. +- If `x1_i` is `NaN` and `x2_i` is not equal to `0`, the result is `NaN`. +- If `abs(x1_i)` is greater than `1` and `x2_i` is `+infinity`, the result is `+infinity`. +- If `abs(x1_i)` is greater than `1` and `x2_i` is `-infinity`, the result is `+0`. +- If `abs(x1_i)` is `1` and `x2_i` is `+infinity`, the result is `1`. +- If `abs(x1_i)` is `1` and `x2_i` is `-infinity`, the result is `1`. +- If `x1_i` is `1` and `x2_i` is not `NaN`, the result is `1`. +- If `abs(x1_i)` is less than `1` and `x2_i` is `+infinity`, the result is `+0`. +- If `abs(x1_i)` is less than `1` and `x2_i` is `-infinity`, the result is `+infinity`. +- If `x1_i` is `+infinity` and `x2_i` is greater than `0`, the result is `+infinity`. +- If `x1_i` is `+infinity` and `x2_i` is less than `0`, the result is `+0`. +- If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. +- If `x1_i` is `-infinity`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. +- If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-0`. +- If `x1_i` is `-infinity`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is greater than `0`, the result is `+0`. +- If `x1_i` is `+0` and `x2_i` is less than `0`, the result is `+infinity`. +- If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is an odd integer value, the result is `-0`. +- If `x1_i` is `-0`, `x2_i` is greater than `0`, and `x2_i` is not an odd integer value, the result is `+0`. +- If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is an odd integer value, the result is `-infinity`. +- If `x1_i` is `-0`, `x2_i` is less than `0`, and `x2_i` is not an odd integer value, the result is `+infinity`. +- If `x1_i` is less than `0`, `x1_i` is a finite number, `x2_i` is a finite number, and `x2_i` is not an integer value, the result is `NaN`. + +#### Parameters + +- **x1**: _<array>_ + + - first input array whose elements correspond to the exponentiation base. Should have a floating-point data type. + +- **x2**: _<array>_ + + - second input array whose elements correspond to the exponentiation exponent. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-remainder)= +### remainder(x1, x2, /) + +Returns the remainder of division for each element `x1_i` of the input array `x1` and the respective element `x2_i` of the input array `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - dividend input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - divisor input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise results. Each element-wise result must have the same sign as the respective element `x2_i`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-round)= +### round(x, /) + +Rounds each element `x_i` of the input array `x` to the nearest integer-valued number. + +#### Special Cases + +- If `x_i` is already integer-valued, the result is `x_i`. +- If two integers are equally close to `x_i`, the result is the even integer closest to `x_i`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the rounded result for each element in `x`. The returned array must have the same data type as `x`. + +(function-sign)= +### sign(x, /) + +Returns an indication of the sign of a number for each element `x_i` of the input array `x`. + +#### Special Cases + +- If `x_i` is less than `0`, the result is `-1`. +- If `x_i` is either `-0` or `+0`, the result is `0`. +- If `x_i` is greater than `0`, the result is `+1`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated result for each element in `x`. The returned array must have the same data type as `x`. + +(function-sin)= +### sin(x, /) + +Calculates an implementation-dependent approximation to the sine, having domain `(-infinity, +infinity)` and codomain `[-1, +1]`, for each element `x_i` of the input array `x`. Each element `x_i` is assumed to be expressed in radians. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is either `+infinity` or `-infinity`, the result is `NaN`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements are each expressed in radians. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the sine of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-sinh)= +### sinh(x, /) + +Calculates an implementation-dependent approximation to the hyperbolic sine, having domain `[-infinity, +infinity]` and codomain `[-infinity, +infinity]`, for each element `x_i` of the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is `+infinity`, the result is `+infinity`. +- If `x_i` is `-infinity`, the result is `-infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements each represent a hyperbolic angle. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the hyperbolic sine of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-square)= +### square(x, /) + +Squares (`x_i * x_i`) each element `x_i` of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the evaluated result for each element in `x`. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-sqrt)= +### sqrt(x, /) + +Calculates the square root, having domain `[0, +infinity]` and codomain `[0, +infinity]`, for each element `x_i` of the input array `x`. After rounding, each result must be indistinguishable from the infinitely precise result (as required by IEEE 754). + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is less than `0`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is `+infinity`, the result is `+infinity`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the square root of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-subtract)= +### subtract(x1, x2, /) + +Calculates the difference for each element `x1_i` of the input array `x1` with the respective element `x2_i` of the input array `x2`. The result of `x1_i - x2_i` must be the same as `x1_i + (-x2_i)` and must be governed by the same floating-point rules as addition (see [`add()`](#addx1-x2-)). + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - second input array. Must be compatible with `x1` (see {ref}`broadcasting`). Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the element-wise differences. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-tan)= +### tan(x, /) + +Calculates an implementation-dependent approximation to the tangent, having domain `(-infinity, +infinity)` and codomain `(-infinity, +infinity)`, for each element `x_i` of the input array `x`. Each element `x_i` is assumed to be expressed in radians. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is either `+infinity` or `-infinity`, the result is `NaN`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements are expressed in radians. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the tangent of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-tanh)= +### tanh(x, /) + +Calculates an implementation-dependent approximation to the hyperbolic tangent, having domain `[-infinity, +infinity]` and codomain `[-1, +1]`, for each element `x_i` of the input array `x`. + +#### Special Cases + +For floating-point operands, + +- If `x_i` is `NaN`, the result is `NaN`. +- If `x_i` is `+0`, the result is `+0`. +- If `x_i` is `-0`, the result is `-0`. +- If `x_i` is `+infinity`, the result is `+1`. +- If `x_i` is `-infinity`, the result is `-1`. + +#### Parameters + +- **x**: _<array>_ + + - input array whose elements each represent a hyperbolic angle. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the hyperbolic tangent of each element in `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-trunc)= +### trunc(x, /) + +Rounds each element `x_i` of the input array `x` to the integer-valued number that is closest to but no greater than `x_i`. + +#### Special Cases + +- If `x_i` is already integer-valued, the result is `x_i`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the rounded result for each element in `x`. The returned array must have the same data type as `x`. diff --git a/latest/_sources/API_specification/function_and_method_signatures.md.txt b/latest/_sources/API_specification/function_and_method_signatures.md.txt new file mode 100644 index 000000000..d199bcbb6 --- /dev/null +++ b/latest/_sources/API_specification/function_and_method_signatures.md.txt @@ -0,0 +1,62 @@ +(function-and-method-signatures)= + +# Function and method signatures + +Function signatures in this standard adhere to the following: + +1. Positional parameters must be + [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. + Positional-only parameters have no externally-usable name. When a function + accepting positional-only parameters is called, positional arguments are + mapped to these parameters based solely on their order. + + _Rationale: existing libraries have incompatible conventions, and using names + of positional parameters is not normal/recommended practice._ + + ```{note} + + Positional-only parameters are only available in Python >= 3.8. Libraries + still supporting 3.7 or 3.6 may consider making the API standard-compliant + namespace >= 3.8. Alternatively, they can add guidance to their users in the + documentation to use the functions as if they were positional-only. + ``` + +2. Optional parameters must be + [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. + + _Rationale: this leads to more readable code, and it makes it easier to + evolve an API over time by adding keywords without having to worry about + keyword order._ + +3. For functions that have a single positional array parameter, that parameter + is called `x`. For functions that have multiple array parameters, those + parameters are called `xi` with `i = 1, 2, ...` (i.e., `x1`, `x2`). + +4. Type annotations are left out of the signatures themselves for readability; however, + they are added to individual parameter descriptions. For code which aims to + adhere to the standard, adding type annotations is strongly recommended. + +A function signature and description will look like: + +``` +funcname(x1, x2, /, *, key1=-1, key2=None) + + Parameters + + x1 : array + description + x2 : array + description + key1 : int + description + key2 : Optional[str] + description + + Returns + + out : array + description +``` + +Method signatures will follow the same conventions modulo the addition of +`self`. diff --git a/latest/_sources/API_specification/index.rst.txt b/latest/_sources/API_specification/index.rst.txt new file mode 100644 index 000000000..55faa1c4d --- /dev/null +++ b/latest/_sources/API_specification/index.rst.txt @@ -0,0 +1,26 @@ +.. _api-specification: + +API specification +================= + +.. toctree:: + :caption: API specification + :maxdepth: 3 + + function_and_method_signatures + array_object + indexing + data_types + data_type_functions + type_promotion + broadcasting + creation_functions + manipulation_functions + elementwise_functions + statistical_functions + linear_algebra_functions + searching_functions + sorting_functions + set_functions + utility_functions + constants diff --git a/latest/_sources/API_specification/indexing.md.txt b/latest/_sources/API_specification/indexing.md.txt new file mode 100644 index 000000000..ae9c5cedb --- /dev/null +++ b/latest/_sources/API_specification/indexing.md.txt @@ -0,0 +1,187 @@ +(indexing)= + +# Indexing + +> Array API specification for indexing arrays. + +A conforming implementation of the array API standard must adhere to the following conventions. + +## Single-axis Indexing + +To index a single array axis, an array must support standard Python indexing rules. Let `n` be the axis (dimension) size. + +- An integer index must be an object satisfying [`operator.index`](https://www.python.org/dev/peps/pep-0357/) (e.g., `int`). + +- Nonnegative indices must start at `0` (i.e., zero-based indexing). + +- **Valid** nonnegative indices must reside on the half-open interval `[0, n)`. + + ```{note} + + This specification does not require bounds checking. The behavior for out-of-bounds integer indices is left unspecified. + ``` + +- Negative indices must count backward from the last array index, starting from `-1` (i.e., negative-one-based indexing, where `-1` refers to the last array index). + + ```{note} + + A negative index `j` is equivalent to `n-j`; the former is syntactic sugar for the latter, providing a shorthand for indexing elements that would otherwise need to be specified in terms of the axis (dimension) size. + ``` + +- **Valid** negative indices must reside on the closed interval `[-n, -1]`. + + ```{note} + + This specification does not require bounds checking. The behavior for out-of-bounds integer indices is left unspecified. + ``` + +- A negative index `j` is related to a zero-based nonnegative index `i` via `i = n+j`. + +- Colons `:` must be used for [slices](https://docs.python.org/3/library/functions.html#slice): `start:stop:step`, where `start` is inclusive and `stop` is exclusive. + +### Slice Syntax + +The basic slice syntax is `i:j:k` where `i` is the starting index, `j` is the stopping index, and `k` is the step (`k != 0`). A slice may contain either one or two colons, with either an integer value or nothing on either side of each colon. The following are valid slices. + +```text +A[:] +A[i:] +A[:j] +A[i:k] +A[::] +A[i::] +A[:j:] +A[::k] +A[i:j:] +A[i::k] +A[:j:k] +A[i::k] +A[i:j:k] +``` + +```{note} + +Slice syntax can be equivalently achieved using the Python built-in [`slice()`](https://docs.python.org/3/library/functions.html#slice) API. From the perspective of `A`, the behavior of `A[i:j:k]` and `A[slice(i, j, k)]` is indistinguishable (i.e., both retrieve the same set of items from `__getitem__`). +``` + +Using a slice to index a single array axis must select `m` elements with index values + +```text +i, i+k, i+2k, i+3k, ..., i+(m-1)k +``` + +where + +```text +m = q + r +``` + +and `q` and `r` (`r != 0`) are the quotient and remainder obtained by dividing `j-i` by `k` + +```text +j - i = qk + r +``` + +such that + +```text +j > i + (m-1)k +``` + +```{note} + +For `i` on the interval `[0, n)` (where `n` is the axis size), `j` on the interval `(0, n]`, `i` less than `j`, and positive step `k`, a starting index `i` is **always** included, while the stopping index `j` is **always** excluded. This preserves `x[:i]+x[i:]` always being equal to `x`. +``` + +```{note} + +Using a slice to index into a single array axis should select the same elements as using a slice to index a Python list of the same size. +``` + +Slice syntax must have the following defaults. Let `n` be the axis (dimension) size. + +- If `k` is not provided (e.g., `0:10`), `k` must equal `1`. +- If `k` is greater than `0` and `i` is not provided (e.g., `:10:2`), `i` must equal `0`. +- If `k` is greater than `0` and `j` is not provided (e.g., `0::2`), `j` must equal `n`. +- If `k` is less than `0` and `i` is not provided (e.g., `:10:-2`), `i` must equal `n-1`. +- If `k` is less than `0` and `j` is not provided (e.g., `0::-2`), `j` must equal `-n-1`. + +Using a slice to index a single array axis must adhere to the following rules. Let `n` be the axis (dimension) size. + +- If `i` equals `j`, a slice must return an empty array, whose axis (dimension) size along the indexed axis is `0`. + +- Indexing via `:` and `::` must be equivalent and have defaults derived from the rules above. Both `:` and `::` indicate to select all elements along a single axis (dimension). + +```{note} + +This specification does not require "clipping" out-of-bounds indices (i.e., requiring the starting and stopping indices `i` and `j` be bound by `0` and `n`, respectively). + +_Rationale: this is consistent with bounds checking for integer indexing; the behavior of out-of-bounds indices is left unspecified. Implementations may choose to clip, raise an exception, return junk values, or some other behavior depending on device requirements and performance considerations._ +``` + +```{note} + +This specification leaves unspecified the behavior of indexing a single array axis with an out-of-bounds slice (i.e., a slice which does not select any array axis elements). + +_Rationale: this is consistent with bounds checking for integer indexing; the behavior of out-of-bounds indices is left unspecified. Implementations may choose to return an empty array (whose axis (dimension) size along the indexed axis is `0`), raise an exception, or some other behavior depending on device requirements and performance considerations._ +``` + +## Multi-axis Indexing + +Multi-dimensional arrays must extend the concept of single-axis indexing to multiple axes by applying single-axis indexing rules along each axis (dimension) and supporting the following additional rules. Let `N` be the number of dimensions ("rank") of a multi-dimensional array `A`. + +- Each axis may be independently indexed via single-axis indexing by providing a comma-separated sequence ("selection tuple") of single-axis indexing expressions (e.g., `A[:, 2:10, :, 5]`). + + ```{note} + + In Python, `x[(exp1, exp2, ..., expN)]` is equivalent to `x[exp1, exp2, ..., expN]`; the latter is syntactic sugar for the former. + ``` + +- Providing a single nonnegative integer `i` as a single-axis index must index the same elements as the slice `i:i+1`. + +- Providing a single negative integer `i` as a single-axis index must index the same elements as the slice `n+i:n+i+1`, where `n` is the axis (dimension) size. + +- Providing a single integer as a single-axis index must reduce the number of array dimensions by `1` (i.e., the array rank should decrease by one; if `A` has rank `2`, `rank(A)-1 == rank(A[0, :])`). In particular, a selection tuple with the `m`th element an integer (and all other entries `:`) indexes a sub-array with rank `N-1`. + +- Providing a slice must retain array dimensions (i.e., the array rank must remain the same; `rank(A) == rank(A[:])`). + +- If the number of provided single-axis indexing expressions is less than `N`, then `:` must be assumed for the remaining dimensions (e.g., if `A` has rank `2`, `A[2:10] == A[2:10, :]`). + +- An `IndexError` exception must be raised if the number of provided single-axis indexing expressions is greater than `N`. + +- Providing [ellipsis](https://docs.python.org/3/library/constants.html#Ellipsis) must apply `:` to each dimension necessary to index all dimensions (e.g., if `A` has rank `4`, `A[1:, ..., 2:5] == A[1:, :, :, 2:5]`). Only a single ellipsis must be allowed. An `IndexError` exception must be raised if more than one ellipsis is provided. + +```{note} + +This specification leaves unspecified the behavior of providing a slice which attempts to select elements along a particular axis, but whose starting index is out-of-bounds. + +_Rationale: this is consistent with bounds-checking for single-axis indexing. An implementation may choose to set the axis (dimension) size of the result array to `0`, raise an exception, return junk values, or some other behavior depending on device requirements and performance considerations._ +``` + +## Boolean Array Indexing + +An array must support indexing via a **single** `M`-dimensional boolean array `B` with shape `S1 = (s1, ..., sM)` according to the following rules. Let `A` be an `N`-dimensional array with shape `S2 = (s1, ..., sM, ..., sN)`. + +- If `N >= M`, then `A[B]` must replace the first `M` dimensions of `A` with a single dimension having a size equal to the number of `True` elements in `B`. The values in the resulting array must be in row-major (C-style order); this is equivalent to `A[nonzero(B)]`. + + ```{note} + + For example, if `N == M == 2`, indexing `A` via a boolean array `B` will return a one-dimensional array whose size is equal to the number of `True` elements in `B`. + ``` + +- If `N < M`, then an `IndexError` exception must be raised. + +- The size of each dimension in `B` must equal the size of the corresponding dimension in `A` or be `0`, beginning with the first dimension in `A`. If a dimension size does not equal the size of the corresponding dimension in `A` and is not `0`, then an `IndexError` exception must be raised. + +- The elements of a boolean index array must be iterated in row-major, C-style order, with the exception of zero-dimensional boolean arrays. + +- A zero-dimensional boolean index array (equivalent to `True` or `False`) must follow the same axis replacement rules stated above. Namely, a zero-dimensional boolean index array removes zero dimensions and adds a single dimension of length `1` if the index array's value is `True` and of length `0` if the index array's value is `False`. Accordingly, for a zero-dimensional boolean index array `B`, the result of `A[B]` has shape `S = (1, s1, ..., sN)` if the index array's value is `True` and has shape `S = (0, s1, ..., sN)` if the index array's value is `False`. + +## Return Values + +The result of an indexing operation (e.g., multi-axis indexing, boolean array indexing, etc) must be an array of the same data type as the indexed array. + +```{note} + +The specified return value behavior includes indexing operations which return a single value (e.g., accessing a single element within a one-dimensional array). +``` \ No newline at end of file diff --git a/latest/_sources/API_specification/linear_algebra_functions.md.txt b/latest/_sources/API_specification/linear_algebra_functions.md.txt new file mode 100644 index 000000000..100efccf2 --- /dev/null +++ b/latest/_sources/API_specification/linear_algebra_functions.md.txt @@ -0,0 +1,344 @@ +# Linear Algebra Functions + +> Array API specification for linear algebra functions. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Broadcasting semantics must follow the semantics defined in {ref}`broadcasting`. +- Unless stated otherwise, functions must support the data types defined in {ref}`data-types`. +- Unless stated otherwise, functions must adhere to the type promotion rules defined in {ref}`type-promotion`. +- Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. + +## Objects in API + + + +(function-cholesky)= +### cholesky() + +TODO + +(function-cross)= +### cross(x1, x2, /, *, axis=-1) + +Returns the cross product of 3-element vectors. If `x1` and `x2` are multi-dimensional arrays (i.e., both have a rank greater than `1`), then the cross-product of each pair of corresponding 3-element vectors is independently computed. + +#### Parameters + +- **x1**: _<array>_ + + - first input array. Should have a numeric data type. + +- **x2**: _<array>_ + + - second input array. Must have the same shape as `x1`. Should have a numeric data type. + +- **axis**: _int_ + + - the axis (dimension) of `x1` and `x2` containing the vectors for which to compute the cross product. If set to `-1`, the function computes the cross product for vectors defined by the last axis (dimension). Default: `-1`. + +#### Returns + +- **out**: _<array>_ + + - an array containing the cross products. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-det)= +### det(x, /) + +Returns the determinant of a square matrix (or stack of square matrices) `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array having shape `(..., M, M)` and whose innermost two dimensions form square matrices. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - if `x` is a two-dimensional array, a zero-dimensional array containing the determinant; otherwise, a non-zero dimensional array containing the determinant for each square matrix. The returned array must have the same data type as `x`. + +(function-diagonal)= +### diagonal(x, /, *, axis1=0, axis2=1, offset=0) + +Returns the specified diagonals. If `x` has more than two dimensions, then the axes (dimensions) specified by `axis1` and `axis2` are used to determine the two-dimensional sub-arrays from which to return diagonals. + +#### Parameters + +- **x**: _<array>_ + + - input array. Must have at least `2` dimensions. + +- **axis1**: _int_ + + - first axis (dimension) with respect to which to take diagonal. Default: `0`. + +- **axis2**: _int_ + + - second axis (dimension) with respect to which to take diagonal. Default: `1`. + +- **offset**: _int_ + + - offset specifying the off-diagonal relative to the main diagonal. + + - `offset = 0`: the main diagonal. + - `offset > 0`: off-diagonal above the main diagonal. + - `offset < 0`: off-diagonal below the main diagonal. + + Default: `0`. + +#### Returns + +- **out**: _<array>_ + + - if `x` is a two-dimensional array, a one-dimensional array containing the diagonal; otherwise, a multi-dimensional array containing the diagonals and whose shape is determined by removing `axis1` and `axis2` and appending a dimension equal to the size of the resulting diagonals. The returned array must have the same data type as `x`. + +(function-dot)= +### dot() + +TODO + +(function-eig)= +### eig() + +TODO + +(function-eigvalsh)= +### eigvalsh() + +TODO + +(function-einsum)= +### einsum() + +TODO + +(function-inv)= +### inv(x, /) + +Computes the multiplicative inverse of a square matrix (or a stack of square matrices) `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array having shape `(..., M, M)` and whose innermost two dimensions form square matrices. Should have a floating-point data type. + +#### Returns + +- **out**: _<array>_ + + - an array containing the multiplicative inverses. The returned array must have a floating-point data type determined by {ref}`type-promotion` and must have the same shape as `x`. + +(function-lstsq)= +### lstsq() + +TODO + +(function-matmul)= +### matmul() + +TODO + +(function-matrix_power)= +### matrix_power() + +TODO + +(function-matrix_rank)= +### matrix_rank() + +TODO + +(function-norm)= +### norm(x, /, *, axis=None, keepdims=False, ord=None) + +Computes the matrix or vector norm of `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. Should have a floating-point data type. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, int ] ] ]_ + + - If an integer, `axis` specifies the axis (dimension) along which to compute vector norms. + + If a 2-tuple, `axis` specifies the axes (dimensions) defining two-dimensional matrices for which to compute matrix norms. + + If `None`, + + - if `x` is one-dimensional, the function must compute the vector norm. + - if `x` is two-dimensional, the function must compute the matrix norm. + - if `x` has more than two dimensions, the function must compute the vector norm over all array values (i.e., equivalent to computing the vector norm of a flattened array). + + Negative indices must be supported. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the axes (dimensions) specified by `axis` must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the axes (dimensions) specified by `axis` must not be included in the result. Default: `False`. + +- **ord**: _Optional\[ Union\[ int, float, Literal\[ inf, -inf, 'fro', 'nuc' ] ] ]_ + + - order of the norm. The following mathematical norms must be supported: + + | ord | matrix | vector | + | ---------------- | ------------------------------- | -------------------------- | + | 'fro' | 'fro' | - | + | 'nuc' | 'nuc' | - | + | 1 | max(sum(abs(x), axis=0)) | L1-norm (Manhattan) | + | 2 | largest singular value | L2-norm (Euclidean) | + | inf | max(sum(abs(x), axis=1)) | infinity norm | + | (int,float >= 1) | - | p-norm | + + The following non-mathematical "norms" must be supported: + + | ord | matrix | vector | + | ---------------- | ------------------------------- | ------------------------------ | + | 0 | - | sum(a != 0) | + | -1 | min(sum(abs(x), axis=0)) | 1./sum(1./abs(a)) | + | -2 | smallest singular value | 1./sqrt(sum(1./abs(a)\*\*2)) | + | -inf | min(sum(abs(x), axis=1)) | min(abs(a)) | + | (int,float < 1) | - | sum(abs(a)\*\*ord)\*\*(1./ord) | + + When `ord` is `None`, the following norms must be the default norms: + + | ord | matrix | vector | + | ---------------- | ------------------------------- | -------------------------- | + | None | 'fro' | L2-norm (Euclidean) | + + where `fro` corresponds to the **Frobenius norm**, `nuc` corresponds to the **nuclear norm**, and `-` indicates that the norm is **not** supported. + + For matrices, + + - if `ord=1`, the norm corresponds to the induced matrix norm where `p=1` (i.e., the maximum absolute value column sum). + - if `ord=2`, the norm corresponds to the induced matrix norm where `p=inf` (i.e., the maximum absolute value row sum). + - if `ord=inf`, the norm corresponds to the induced matrix norm where `p=2` (i.e., the largest singular value). + + If `None`, + + - if matrix (or matrices), the function must compute the Frobenius norm. + - if vector (or vectors), the function must compute the L2-norm (Euclidean norm). + + Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array containing the norms. If `axis` is `None`, the returned array must be a zero-dimensional array containing a vector norm. If `axis` is a scalar value (`int` or `float`), the returned array must have a rank which is one less than the rank of `x`. If `axis` is a 2-tuple, the returned array must have a rank which is two less than the rank of `x`. The returned array must have a floating-point data type determined by {ref}`type-promotion`. + +(function-outer)= +### outer(x1, x2, /) + +Computes the outer product of two vectors `x1` and `x2`. + +#### Parameters + +- **x1**: _<array>_ + + - first one-dimensional input array of size `N`. Should have a numeric data type. + +- **x2**: _<array>_ + + - second one-dimensional input array of size `M`. Should have a numeric data type. + +#### Returns + +- **out**: _<array>_ + + - a two-dimensional array containing the outer product and whose shape is `(N, M)`. The returned array must have a data type determined by {ref}`type-promotion`. + +(function-pinv)= +### pinv() + +TODO + +(function-qr)= +### qr() + +TODO + +(function-slogdet)= +### slogdet() + +TODO + +(function-solve)= +### solve() + +TODO + +(function-svd)= +### svd() + +TODO + +(function-trace)= +### trace(x, /, *, axis1=0, axis2=1, offset=0) + +Returns the sum along the specified diagonals. If `x` has more than two dimensions, then the axes (dimensions) specified by `axis1` and `axis2` are used to determine the two-dimensional sub-arrays for which to compute the trace. + +#### Parameters + +- **x**: _<array>_ + + - input array. Must have at least `2` dimensions. Should have a numeric data type. + +- **axis1**: _int_ + + - first axis (dimension) with respect to which to compute the trace. Default: `0`. + +- **axis2**: _int_ + + - second axis (dimension) with respect to which to compute the trace. Default: `1`. + +- **offset**: _int_ + + - offset specifying the off-diagonal relative to the main diagonal. + + - `offset = 0`: the main diagonal. + - `offset > 0`: off-diagonal above the main diagonal. + - `offset < 0`: off-diagonal below the main diagonal. + + Default: `0`. + +#### Returns + +- **out**: _<array>_ + + - if `x` is a two-dimensional array, the returned array must be a zero-dimensional array containing the trace; otherwise, the returned array must be a multi-dimensional array containing the traces. + + The shape of a multi-dimensional output array is determined by removing `axis1` and `axis2` and storing the traces in the last array dimension. For example, if `x` has rank `k` and shape `(I, J, K, ..., L, M, N)` and `axis1=-2` and `axis1=-1`, then a multi-dimensional output array has rank `k-2` and shape `(I, J, K, ..., L)` where + + ```text + out[i, j, k, ..., l] = trace(a[i, j, k, ..., l, :, :]) + ``` + + The returned array must have the same data type as `x`. + +(function-transpose)= +### transpose(x, /, *, axes=None) + +Transposes (or permutes the axes (dimensions)) of an array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axes**: _Optional\[ Tuple\[ int, ... ] ]_ + + - tuple containing a permutation of `(0, 1, ..., N-1)` where `N` is the number of axes (dimensions) of `x`. If `None`, the axes (dimensions) must be permuted in reverse order (i.e., equivalent to setting `axes=(N-1, ..., 1, 0)`). Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an array containing the transpose. The returned array must have the same data type as `x`. diff --git a/latest/_sources/API_specification/manipulation_functions.md.txt b/latest/_sources/API_specification/manipulation_functions.md.txt new file mode 100644 index 000000000..29fca5a29 --- /dev/null +++ b/latest/_sources/API_specification/manipulation_functions.md.txt @@ -0,0 +1,174 @@ +# Manipulation Functions + +> Array API specification for manipulating arrays. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Unless stated otherwise, functions must adhere to the type promotion rules defined in {ref}`type-promotion`. + +## Objects in API + + + +(function-concat)= +### concat(arrays, /, *, axis=0) + +Joins a sequence of arrays along an existing axis. + +#### Parameters + +- **arrays**: _Tuple\[ <array>, ... ]_ + + - input arrays to join. The arrays must have the same shape, except in the dimension specified by `axis`. + +- **axis**: _Optional\[ int ]_ + + - axis along which the arrays will be joined. If `axis` is `None`, arrays must be flattened before concatenation. If `axis` is negative, the function must determine the axis along which to join by counting from the last dimension. Default: `0`. + +#### Returns + +- **out**: _<array>_ + + - an output array containing the concatenated values. If the input arrays have different data types, normal [type promotion rules](type_promotion.md) must apply. If the input arrays have the same data type, the output array must have the same data type as the input arrays. + + ```{note} + + This specification leaves type promotion between data type families (i.e., `intxx` and `floatxx`) unspecified. + ``` + +(function-expand_dims)= +### expand_dims(x, axis, /) + +Expands the shape of an array by inserting a new axis (dimension) of size one at the position specified by `axis`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _int_ + + - axis position. Must follow Python's indexing rules: zero-based and negative indices must be counted backward from the last dimension. If `x` has rank `N`, a valid `axis` must reside on the interval `[-N-1, N+1]`. An `IndexError` exception must be raised if provided an invalid `axis` position. + +#### Returns + +- **out**: _<array>_ + + - an expanded output array having the same data type and shape as `x`. + +(function-flip)= +### flip(x, /, *, axis=None) + +Reverses the order of elements in an array along the given axis. The shape of the array must be preserved. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis (or axes) along which to flip. If `axis` is `None`, the function must flip all input array axes. If `axis` is negative, the function must count from the last dimension. If provided more than one axis, the function must flip only the specified axes. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an output array having the same data type and shape as `x` and whose elements, relative to `x`, are reordered. + +(function-reshape)= +### reshape(x, shape, /) + +Reshapes an array without changing its data. + +#### Parameters + +- **x**: _<array>_ + + - input array to reshape. + +- **shape**: _Tuple\[ int, ... ]_ + + - a new shape compatible with the original shape. One shape dimension is allowed to be `-1`. When a shape dimension is `-1`, the corresponding output array shape dimension must be inferred from the length of the array and the remaining dimensions. + +#### Returns + +- **out**: _<array>_ + + - an output array having the same data type, elements, and underlying element order as `x`. + +(function-roll)= +### roll(x, shift, /, *, axis=None) + +Rolls array elements along a specified axis. Array elements that roll beyond the last position are re-introduced at the first position. Array elements that roll beyond the first position are re-introduced at the last position. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **shift**: _Union\[ int, Tuple\[ int, ... ] ]_ + + - number of places by which the elements are shifted. If `shift` is a tuple, then `axis` must be a tuple of the same size, and each of the given axes must be shifted by the corresponding element in `shift`. If `shift` is an `int` and `axis` a tuple, then the same `shift` must be used for all specified axes. If a shift is positive, then array elements must be shifted positively (toward larger indices) along the dimension of `axis`. If a shift is negative, then array elements must be shifted negatively (toward smaller indices) along the dimension of `axis`. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis (or axes) along which elements to shift. If `axis` is `None`, the array must be flattened, shifted, and then restored to its original shape. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an output array having the same data type as `x` and whose elements, relative to `x`, are shifted. + +(function-squeeze)= +### squeeze(x, /, *, axis=None) + +Removes singleton dimensions (axes) from `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis (or axes) to squeeze. If provided, only the specified axes must be squeezed. If `axis` is `None`, all singleton dimensions (axes) must be removed. If a specified axis has a size greater than one, the specified axis must be left unchanged. Default: `None`. + +#### Returns + +- **out**: _<array>_ + + - an output array having the same data type and elements as `x`. + +(function-stack)= +### stack(arrays, /, *, axis=0) + +Joins a sequence of arrays along a new axis. + +#### Parameters + +- **arrays**: _Tuple\[ <array>, ... ]_ + + - input arrays to join. Each array must have the same shape. + +- **axis**: _int_ + + - axis along which the arrays will be joined. Providing an `axis` specifies the index of the new axis in the dimensions of the result. For example, if `axis` is `0`, the new axis will be the first dimension and the output array will have shape `(N, A, B, C)`; if `axis` is `1`, the new axis will be the second dimension and the output array will have shape `(A, N, B, C)`; and, if `axis` is `-1`, the new axis will be the last dimension and the output array will have shape `(A, B, C, N)`. A valid `axis` must be on the interval `[-N, N)`, where `N` is the rank (number of dimensions) of `x`. If provided an `axis` outside of the required interval, the function must raise an exception. Default: `0`. + +#### Returns + +- **out**: _<array>_ + + - an output array having rank `N+1`, where `N` is the rank (number of dimensions) of `x`. If the input arrays have different data types, normal [type promotion rules](type_promotion.md) must apply. If the input arrays have the same data type, the output array must have the same data type as the input arrays. + + ```{note} + + This specification leaves type promotion between data type families (i.e., `intxx` and `floatxx`) unspecified. + ``` diff --git a/latest/_sources/API_specification/searching_functions.md.txt b/latest/_sources/API_specification/searching_functions.md.txt new file mode 100644 index 000000000..d3d06d7a6 --- /dev/null +++ b/latest/_sources/API_specification/searching_functions.md.txt @@ -0,0 +1,109 @@ +(searching-functions)= + +# Searching Functions + +> Array API specification for functions for searching arrays. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Broadcasting semantics must follow the semantics defined in {ref}`broadcasting`. +- Unless stated otherwise, functions must support the data types defined in {ref}`data-types`. +- Unless stated otherwise, functions must adhere to the type promotion rules defined in {ref}`type-promotion`. + +## Objects in API + + + +(function-argmax)= +### argmax(x, /, *, axis=None, keepdims=False) + +Returns the indices of the maximum values along a specified axis. When the maximum value occurs multiple times, only the indices corresponding to the first occurrence are returned. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _int_ + + - axis along which to search. If `None`, the function must return the index of the maximum value of the flattened array. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if `axis` is `None`, a zero-dimensional array containing the index of the first occurrence of the maximum value; otherwise, a non-zero-dimensional array containing the indices of the maximum values. The returned array must have be the default array index data type. + +(function-argmin)= +### argmin(x, /, *, axis=None, keepdims=False) + +Returns the indices of the minimum values along a specified axis. When the minimum value occurs multiple times, only the indices corresponding to the first occurrence are returned. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _int_ + + - axis along which to search. If `None`, the function must return the index of the minimum value of the flattened array. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if `axis` is `None`, a zero-dimensional array containing the index of the first occurrence of the minimum value; otherwise, a non-zero-dimensional array containing the indices of the minimum values. The returned array must have the default array index data type. + +(function-nonzero)= +### nonzero(x, /) + +Returns the indices of the array elements which are non-zero. + +#### Parameters + +- **x**: _<array>_ + + - input array. Must have a positive rank. If `x` is zero-dimensional, the function must raise an exception. + +#### Returns + +- **out**: _Tuple\[ <array>, ... ]_ + + - a tuple of `k` arrays, one for each dimension of `x` and each of size `n` (where `n` is the total number of non-zero elements), containing the indices of the non-zero elements in that dimension. The indices must be returned in row-major, C-style order. The returned array must have the default array index data type. + +(function-where)= +### where(condition, x1, x2, /) + +Returns elements chosen from `x1` or `x2` depending on `condition`. + +#### Parameters + +- **condition**: _<array>_ + + - when `True`, yield `x1_i`; otherwise, yield `x2_i`. Must be compatible with `x1` and `x2` (see {ref}`broadcasting`). + +- **x1**: _<array>_ + + - first input array. Must be compatible with `condition` and `x2` (see {ref}`broadcasting`). + +- **x2**: _<array>_ + + - second input array. Must be compatible with `condition` and `x1` (see {ref}`broadcasting`). + +#### Returns + +- **out**: _<array>_ + + - an array with elements from `x1` where `condition` is `True`, and elements from `x2` elsewhere. The returned array must have a data type determined by {ref}`type-promotion` rules. diff --git a/latest/_sources/API_specification/set_functions.md.txt b/latest/_sources/API_specification/set_functions.md.txt new file mode 100644 index 000000000..73d8338cc --- /dev/null +++ b/latest/_sources/API_specification/set_functions.md.txt @@ -0,0 +1,64 @@ +# Set Functions + +> Array API specification for creating and operating on sets. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Unless stated otherwise, functions must support the data types defined in {ref}`data-types`. + +## Objects in API + + + +(function-unique)= +### unique(x, /, *, return_counts=False, return_index=False, return_inverse=False) + +Returns the unique elements of an input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. If `x` has more than one dimension, the function must flatten `x` and return the unique elements of the flattened array. + +- **return_counts**: _bool_ + + - If `True`, the function must also return the number of times each unique element occurs in `x`. Default: `False`. + +- **return_index**: _bool_ + + - If `True`, the function must also return the indices (first occurrences) of `x` that result in the unique array. Default: `False`. + +- **return_inverse**: _bool_ + + - If `True`, the function must also return the indices of the unique array that reconstruct `x`. Default: `False`. + +#### Returns + +- **out**: _Union\[ <array>, Tuple\[ <array>, ... ] ]_ + + - if `return_counts`, `return_index`, and `return_inverse` are all `False`, an array containing the set of unique elements in `x`; otherwise, a tuple containing two or more of the following arrays (in order): + + - **unique**: _<array>_ + + - an array containing the set of unique elements in `x`. The returned array must have the same data type as `x`. + + ```{note} + The order of elements is not specified, and may vary between implementations. + ``` + + - **indices**: _<array>_ + + - an array containing the indices (first occurrences) of `x` that result in `unique`. The returned array must have the default array index data type. + + - **inverse**: _<array>_ + + - an array containing the indices of `unique` that reconstruct `x`. The returned array must have the default array index data type. + + - **counts**: _<array>_ + + - an array containing the number of times each unique element occurs in `x`. + + _TODO: should this be `int64`? This probably makes sense for most hardware; however, may be undesirable for older hardware and/or embedded systems._ diff --git a/latest/_sources/API_specification/sorting_functions.md.txt b/latest/_sources/API_specification/sorting_functions.md.txt new file mode 100644 index 000000000..f88b01a17 --- /dev/null +++ b/latest/_sources/API_specification/sorting_functions.md.txt @@ -0,0 +1,71 @@ +# Sorting Functions + +> Array API specification for sorting functions. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Unless stated otherwise, functions must support the data types defined in {ref}`data-types`. + +## Objects in API + + + +(function-argsort)= +### argsort(x, /, *, axis=-1, descending=False, stable=True) + +Returns the indices that sort an array `x` along a specified axis. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _int_ + + - axis along which to sort. If set to `-1`, the function must sort along the last axis. Default: `-1`. + +- **descending**: _bool_ + + - sort order. If `True`, the returned indices sort `x` in descending order (by value). If `False`, the returned indices sort `x` in ascending order (by value). Default: `False`. + +- **stable**: _bool_ + + - sort stability. If `True`, the returned indices must maintain the relative order of `x` values which compare as equal. If `False`, the returned indices may or may not maintain the relative order of `x` values which compare as equal (i.e., the relative order of `x` values which compare as equal is implementation-dependent). Default: `True`. + +#### Returns + +- **out**: _<array>_ + + - an array of indices. The returned array must have the same shape as `x`. The returned array must have the default array index data type. + +(function-sort)= +### sort(x, /, *, axis=-1, descending=False, stable=True) + +Returns a sorted copy of an input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _int_ + + - axis along which to sort. If set to `-1`, the function must sort along the last axis. Default: `-1`. + +- **descending**: _bool_ + + - sort order. If `True`, the array must be sorted in descending order (by value). If `False`, the array must be sorted in ascending order (by value). Default: `False`. + +- **stable**: _bool_ + + - sort stability. If `True`, the returned array must maintain the relative order of `x` values which compare as equal. If `False`, the returned array may or may not maintain the relative order of `x` values which compare as equal (i.e., the relative order of `x` values which compare as equal is implementation-dependent). Default: `True`. + +#### Returns + +- **out**: _<array>_ + + - a sorted array. The returned array must have the same data type and shape as `x`. diff --git a/latest/_sources/API_specification/statistical_functions.md.txt b/latest/_sources/API_specification/statistical_functions.md.txt new file mode 100644 index 000000000..1f5c6f2ab --- /dev/null +++ b/latest/_sources/API_specification/statistical_functions.md.txt @@ -0,0 +1,199 @@ +# Statistical Functions + +> Array API specification for statistical functions. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Broadcasting semantics must follow the semantics defined in {ref}`broadcasting`. +- Unless stated otherwise, functions must support the data types defined in {ref}`data-types`. +- Unless stated otherwise, functions must adhere to the type promotion rules defined in {ref}`type-promotion`. +- Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. + +## Objects in API + + + +(function-max)= +### max(x, /, *, axis=None, keepdims=False) + +Calculates the maximum value of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which maximum values must be computed. By default, the maximum value must be computed over the entire array. If a tuple of integers, maximum values must be computed over multiple axes. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if the maximum value was computed over the entire array, a zero-dimensional array containing the maximum value; otherwise, a non-zero-dimensional array containing the maximum values. The returned array must have the same data type as `x`. + +(function-mean)= +### mean(x, /, *, axis=None, keepdims=False) + +Calculates the arithmetic mean of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which arithmetic means must be computed. By default, the mean must be computed over the entire array. If a tuple of integers, arithmetic means must be computed over multiple axes. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if the arithmetic mean was computed over the entire array, a zero-dimensional array containing the arithmetic mean; otherwise, a non-zero-dimensional array containing the arithmetic means. The returned array must have be the default floating-point data type. + +(function-min)= +### min(x, /, *, axis=None, keepdims=False) + +Calculates the minimum value of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which minimum values must be computed. By default, the minimum value must be computed over the entire array. If a tuple of integers, minimum values must be computed over multiple axes. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if the minimum value was computed over the entire array, a zero-dimensional array containing the minimum value; otherwise, a non-zero-dimensional array containing the minimum values. The returned array must have the same data type as `x`. + +(function-prod)= +### prod(x, /, *, axis=None, keepdims=False) + +Calculates the product of input array `x` elements. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which products must be computed. By default, the product must be computed over the entire array. If a tuple of integers, products must be computed over multiple axes. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if the product was computed over the entire array, a zero-dimensional array containing the product; otherwise, a non-zero-dimensional array containing the products. The returned array must have the same data type as `x`. + +(function-std)= +### std(x, /, *, axis=None, correction=0.0, keepdims=False) + +Calculates the standard deviation of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which standard deviations must be computed. By default, the standard deviation must be computed over the entire array. If a tuple of integers, standard deviations must be computed over multiple axes. Default: `None`. + +- **correction**: _Union\[ int, float ]_ + + - degrees of freedom adjustment. Setting this parameter to a value other than `0` has the effect of adjusting the divisor during the calculation of the standard deviation according to `N-c` where `N` corresponds to the total number of elements over which the standard deviation is computed and `c` corresponds to the provided degrees of freedom adjustment. When computing the standard deviation of a population, setting this parameter to `0` is the standard choice (i.e., the provided array contains data constituting an entire population). When computing the corrected sample standard deviation, setting this parameter to `1` is the standard choice (i.e., the provided array contains data sampled from a larger population; this is commonly referred to as Bessel's correction). Default: `0`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if the standard deviation was computed over the entire array, a zero-dimensional array containing the standard deviation; otherwise, a non-zero-dimensional array containing the standard deviations. The returned array must have the default floating-point data type. + +(function-sum)= +### sum(x, /, *, axis=None, keepdims=False) + +Calculates the sum of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which sums must be computed. By default, the sum must be computed over the entire array. If a tuple of integers, sums must be computed over multiple axes. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if the sum was computed over the entire array, a zero-dimensional array containing the sum; otherwise, an array containing the sums. The returned array must have the same data type as `x`. + +(function-var)= +### var(x, /, *, axis=None, correction=0.0, keepdims=False) + +Calculates the variance of the input array `x`. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which variances must be computed. By default, the variance must be computed over the entire array. If a tuple of integers, variances must be computed over multiple axes. Default: `None`. + +- **correction**: _Union\[ int, float ]_ + + - degrees of freedom adjustment. Setting this parameter to a value other than `0` has the effect of adjusting the divisor during the calculation of the variance according to `N-c` where `N` corresponds to the total number of elements over which the variance is computed and `c` corresponds to the provided degrees of freedom adjustment. When computing the variance of a population, setting this parameter to `0` is the standard choice (i.e., the provided array contains data constituting an entire population). When computing the unbiased sample variance, setting this parameter to `1` is the standard choice (i.e., the provided array contains data sampled from a larger population; this is commonly referred to as Bessel's correction). Default: `0`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if the variance was computed over the entire array, a zero-dimensional array containing the variance; otherwise, a non-zero-dimensional array containing the variances. The returned array must have the default floating-point data type. diff --git a/latest/_sources/API_specification/type_promotion.md.txt b/latest/_sources/API_specification/type_promotion.md.txt new file mode 100644 index 000000000..d9862db88 --- /dev/null +++ b/latest/_sources/API_specification/type_promotion.md.txt @@ -0,0 +1,126 @@ +(type-promotion)= + +# Type Promotion Rules + +> Array API specification for type promotion rules. + +Type promotion rules can be understood at a high level from the following +diagram: + +![Type promotion diagram](/_static/images/dtype_promotion_lattice.png) + +_Type promotion diagram. Promotion between any two types is given by their join on this lattice. Only the types of participating arrays matter, not their values. Dashed lines indicate that behavior for Python scalars is undefined on overflow. Boolean, integer and floating-point dtypes are not connected, indicating mixed-kind promotion is undefined._ + + +## Rules + +A conforming implementation of the array API standard must implement the following type promotion rules governing the common result type for two **array** operands during an arithmetic operation. + +A conforming implementation of the array API standard may support additional type promotion rules beyond those described in this specification. + +```{note} + +Type codes are used here to keep tables readable; they are not part of the standard. +In code, use the data type objects specified in {ref}`data-types` (e.g., `int16` rather than `'i2'`). +``` + + + +The following type promotion tables specify the casting behavior for +operations involving two array operands. When more than two array operands +participate, application of the promotion tables is associative (i.e., the +result does not depend on operand order). + +### Signed integer type promotion table + +| | i1 | i2 | i4 | i8 | +| ------ | -- | -- | -- | -- | +| **i1** | i1 | i2 | i4 | i8 | +| **i2** | i2 | i2 | i4 | i8 | +| **i4** | i4 | i4 | i4 | i8 | +| **i8** | i8 | i8 | i8 | i8 | + +where + +- **i1**: 8-bit signed integer (i.e., `int8`) +- **i2**: 16-bit signed integer (i.e., `int16`) +- **i4**: 32-bit signed integer (i.e., `int32`) +- **i8**: 64-bit signed integer (i.e., `int64`) + +### Unsigned integer type promotion table + +| | u1 | u2 | u4 | u8 | +| ------ | -- | -- | -- | -- | +| **u1** | u1 | u2 | u4 | u8 | +| **u2** | u2 | u2 | u4 | u8 | +| **u4** | u4 | u4 | u4 | u8 | +| **u8** | u8 | u8 | u8 | u8 | + +where + +- **u1**: 8-bit unsigned integer (i.e., `uint8`) +- **u2**: 16-bit unsigned integer (i.e., `uint16`) +- **u4**: 32-bit unsigned integer (i.e., `uint32`) +- **u8**: 64-bit unsigned integer (i.e., `uint64`) + +### Mixed unsigned and signed integer type promotion table + +| | u1 | u2 | u4 | +| ------ | -- | -- | -- | +| **i1** | i2 | i4 | i8 | +| **i2** | i2 | i4 | i8 | +| **i4** | i4 | i4 | i8 | + +### Floating-point type promotion table + +| | f4 | f8 | +| ------ | -- | -- | +| **f4** | f4 | f8 | +| **f8** | f8 | f8 | + +where + +- **f4**: single-precision (32-bit) floating-point number (i.e., `float32`) +- **f8**: double-precision (64-bit) floating-point number (i.e., `float64`) + +### Notes + +- Type promotion rules must apply when determining the common result type for two **array** operands during an arithmetic operation, regardless of array dimension. Accordingly, zero-dimensional arrays must be subject to the same type promotion rules as dimensional arrays. +- Type promotion of non-numerical data types to numerical data types is unspecified (e.g., `bool` to `intxx` or `floatxx`). + +```{note} + +Mixed integer and floating-point type promotion rules are not specified +because behavior varies between implementations. +``` + +### Mixing arrays with Python scalars + +Using Python scalars (i.e., instances of `bool`, `int`, `float`) together with +arrays must be supported for: + +- `array scalar` +- `scalar array` + +where `` is a built-in operator (see {ref}`operators` for operators +supported by the array object) and `scalar` has a compatible type and value +to the array dtype: +- Python `bool` for a `bool` array dtype, +- a Python `int` within the [bounds](data-types) of the given dtype for integer array dtypes, +- a Python `int` or `float` for floating-point array dtypes +The expected behavior is then equivalent to: + +1. Convert the scalar to a 0-D array with the same dtype as that of the array + used in the expression. +2. Execute the operation for `array 0-D array` (or `0-D array + array` if `scalar` was the left-hand argument). + +```{note} + +Behaviour is not specified when mixing a Python `float` and an array with an +integer dtype; this may give `float32`, `float64`, or raise an exception - +behavior of implementations will differ. + +The behavior is also not specified for integers outside of the bounds of a +given integer dtype. It may overflow, or result in an error. +``` diff --git a/latest/_sources/API_specification/utility_functions.md.txt b/latest/_sources/API_specification/utility_functions.md.txt new file mode 100644 index 000000000..aad65a71b --- /dev/null +++ b/latest/_sources/API_specification/utility_functions.md.txt @@ -0,0 +1,66 @@ +# Utility Functions + +> Array API specification for utility functions. + +A conforming implementation of the array API standard must provide and support the following functions adhering to the following conventions. + +- Positional parameters must be [positional-only](https://www.python.org/dev/peps/pep-0570/) parameters. Positional-only parameters have no externally-usable name. When a function accepting positional-only parameters is called, positional arguments are mapped to these parameters based solely on their order. +- Optional parameters must be [keyword-only](https://www.python.org/dev/peps/pep-3102/) arguments. +- Broadcasting semantics must follow the semantics defined in {ref}`broadcasting`. +- Unless stated otherwise, functions must support the data types defined in {ref}`data-types`. +- Unless stated otherwise, functions must adhere to the type promotion rules defined in {ref}`type-promotion`. +- Unless stated otherwise, floating-point operations must adhere to IEEE 754-2019. + +## Objects in API + + + +(function-all)= +### all(x, /, *, axis=None, keepdims=False) + +Tests whether all input array elements evaluate to `True` along a specified axis. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which to perform a logical AND reduction. By default, a logical AND reduction must be performed over the entire array. If a tuple of integers, logical AND reductions must be performed over multiple axes. A valid `axis` must be an integer on the interval `[-N, N)`, where `N` is the rank (number of dimensions) of `x`. If an `axis` is specified as a negative integer, the function must determine the axis along which to perform a reduction by counting backward from the last dimension (where `-1` refers to the last dimension). If provided an invalid `axis`, the function must raise an exception. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if a logical AND reduction was performed over the entire array, the returned array must be a zero-dimensional array containing the test result; otherwise, the returned array must be a non-zero-dimensional array containing the test results. The returned array must have a data type of `bool`. + +(function-any)= +### any(x, /, *, axis=None, keepdims=False) + +Tests whether any input array element evaluates to `True` along a specified axis. + +#### Parameters + +- **x**: _<array>_ + + - input array. + +- **axis**: _Optional\[ Union\[ int, Tuple\[ int, ... ] ] ]_ + + - axis or axes along which to perform a logical OR reduction. By default, a logical OR reduction must be performed over the entire array. If a tuple of integers, logical OR reductions must be performed over multiple axes. A valid `axis` must be an integer on the interval `[-N, N)`, where `N` is the rank (number of dimensions) of `x`. If an `axis` is specified as a negative integer, the function must determine the axis along which to perform a reduction by counting backward from the last dimension (where `-1` refers to the last dimension). If provided an invalid `axis`, the function must raise an exception. Default: `None`. + +- **keepdims**: _bool_ + + - If `True`, the reduced axes (dimensions) must be included in the result as singleton dimensions, and, accordingly, the result must be compatible with the input array (see {ref}`broadcasting`). Otherwise, if `False`, the reduced axes (dimensions) must not be included in the result. Default: `False`. + +#### Returns + +- **out**: _<array>_ + + - if a logical OR reduction was performed over the entire array, the returned array must be a zero-dimensional array containing the test result; otherwise, the returned array must be a non-zero-dimensional array containing the test results. The returned array must have a data type of `bool`. diff --git a/latest/_sources/assumptions.md.txt b/latest/_sources/assumptions.md.txt new file mode 100644 index 000000000..3a315e6cd --- /dev/null +++ b/latest/_sources/assumptions.md.txt @@ -0,0 +1,77 @@ +(Assumptions)= + +# Assumptions + +## Hardware and software environments + +No assumptions on a specific hardware environment are made. It must be possible +to create an array library adhering to this standard that runs (efficiently) on +a variety of different hardware: CPUs with different architectures, GPUs, +distributed systems and TPUs and other emerging accelerators. + +The same applies to software environments: it must be possible to create an +array library adhering to this standard that runs efficiently independent of +what compilers, build-time or run-time execution environment, or distribution +and install method is employed. Parallel execution, JIT compilation, and +delayed (lazy) evaluation must all be possible. + +The variety of hardware and software environments puts _constraints_ on choices +made in the API standard. For example, JIT compilers may require output dtypes +of functions to be predictable from input dtypes only rather than input values. + + +(assumptions-dependencies)= + +## Dependencies + +The only dependency that's assumed in this standard is that on Python itself. +Python >= 3.8 is assumed, motivated by the use of positional-only parameters +(see [function and method signatures](API_specification/function_and_method_signatures.md)). + +Importantly, array libraries are not assumed to be aware of each other, or of +a common array-specific layer. The [use cases](use_cases.md) do not require +such a dependency, and building and evolving an array library is easier without +such a coupling. Facilitation support of multiple array types in downstream +libraries is an important use case however, the assumed dependency structure +for that is: + +![dependency assumptions diagram](_static/images/dependency_assumption_diagram.png) + +Array libraries may know how to interoperate with each other, for example by +constructing their own array type from that of another library or by shared +memory use of an array (see [Data interchange mechanisms](design_topics/data_interchange.md)). +This can be done without a dependency though - only adherence to a protocol is +enough. + +Array-consuming libraries will have to depend on one or more array libraries. +That could be a "soft dependency" though, meaning retrieving an array library +namespace from array instances that are passed in, but not explicitly doing +`import arraylib_name`. + + +## Backwards compatibility + +The assumption made during creation of this standard is that libraries are +constrained by backwards compatibility guarantees to their users, and are +likely unwilling to make significant backwards-incompatible changes for the +purpose of conforming to this standard. Therefore it is assumed that the +standard will be made available in a new namespace within each library, or the +library will provide a way to retrieve a module or module-like object that +adheres to this standard. See {ref}`how-to-adopt-this-api` for more details. + + +## Production code & interactive use + +It is assumed that the primary use case is writing production code, for example +in array-consuming libraries. As a consequence, making it easy to ensure that +code is written as intended and has unambiguous semantics is preferred - and +clear exceptions must be raised otherwise. + +It is also assumed that this does not significantly detract from the +interactive user experience. However, in case existing libraries differ in +behavior, the more strict version of that behavior is typically preferred. A +good example is array inputs to functions - while NumPy accepts lists, tuples, +generators, and anything else that could be turned into an array, most other +libraries only accept their own array types. This standard follows the latter choice. +It is likely always possible to put a thin "interactive use convenience layer" +on top of a more strict behavior. diff --git a/latest/_sources/benchmark_suite.md.txt b/latest/_sources/benchmark_suite.md.txt new file mode 100644 index 000000000..da203cbf6 --- /dev/null +++ b/latest/_sources/benchmark_suite.md.txt @@ -0,0 +1,3 @@ +# Benchmark suite + +Adding a benchmark suite is planned in the future. \ No newline at end of file diff --git a/latest/_sources/design_topics/C_API.md.txt b/latest/_sources/design_topics/C_API.md.txt new file mode 100644 index 000000000..96575ba63 --- /dev/null +++ b/latest/_sources/design_topics/C_API.md.txt @@ -0,0 +1,93 @@ +(C-API)= + +# C API + +Use of a C API is out of scope for this array API, as mentioned in {ref}`Scope`. +There are a lot of libraries that do use such an API - in particular via Cython code +or via direct usage of the NumPy C API. When the maintainers of such libraries +want to use this array API standard to support multiple types of arrays, they +need a way to deal with that issue. This section aims to provide some guidance. + +The assumption in the rest of this section is that performance matters for the library, +and hence the goal is to make other array types work without converting to a +`numpy.ndarray` or another particular array type. If that's not the case (e.g. for a +visualization package), then other array types can simply be handled by converting +to the supported array type. + +```{note} + +Often a zero-copy conversion to `numpy.ndarray` is possible, at least for CPU arrays. +If that's the case, this may be a good way to support other array types. +The main difficulty in that case will be getting the return array type right - however, +this standard does provide a Python-level API for array construction that should allow +doing this. A relevant question is if it's possible to know with +certainty that a conversion will be zero-copy. This may indeed be +possible, see {ref}`data-interchange`. +``` + +## Example situations for C/Cython usage + +### Situation 1: a Python package that is mostly pure Python, with a limited number of Cython extensions + +```{note} + +Projects in this situation include Statsmodels, scikit-bio and QuTiP +``` + +Main strategy: documentation. The functionality using Cython code will not support other array types (or only with conversion to/from `numpy.ndarray`), which can be documented per function. + + +### Situation 2: a Python package that contains a lot of Cython code + +```{note} + +Projects in this situation include scikit-learn and scikit-image +``` + +Main strategy: add support for other array types _per submodule_. This keeps it manageable to explain to the user which functionality does and doesn't have support. + +Longer term: specific support for particular array types (e.g. `cupy.ndarray` can be supported with Python-only code via `cupy.ElementwiseKernel`). + + +### Situation 3: a Python package that uses the NumPy or Python C API directly + +```{note} + +Projects in this situation include SciPy and Astropy +``` + +Strategy: similar to _situation 2_, but the number of submodules that can support all array types may be limited. + + +## Device support + +Supporting non-CPU array types in code using the C API or Cython seems problematic, +this almost inevitably will require custom device-specific code (e.g., CUDA, ROCm) or +something like JIT compilation with Numba. + + +## Other longer-term approaches + +### Further Python API standardization + +There may be cases where it makes sense to standardize additional sets of +functions, because they're important enough that array libraries tend to +reimplement them. An example of this may be _special functions_, as provided +by `scipy.special`. Bessel and gamma functions for example are commonly +reimplemented by array libraries. This may avoid having to drop into a +particular implementation that does use a C API (e.g., one can then rely on +`arraylib.special.gamma` rather than having to use `scipy.special.gamma`). + + +### HPy + +[HPy](https://github.com/hpyproject/hpy) is a new project that will provide a higher-level +C API and ABI than CPython offers. A Cython backend targeting HPy will be provided as well. + +- Better PyPy support +- Universal ABI - single binary for all supported Python versions +- Cython backend generating HPy rather than CPython code + +HPy isn't quite ready for mainstream usage today, but once it does it may +help make supporting multiple array libraries or adding non-CPU device +support to Cython more feasible. diff --git a/latest/_sources/design_topics/accuracy.md.txt b/latest/_sources/design_topics/accuracy.md.txt new file mode 100644 index 000000000..1ef6005d0 --- /dev/null +++ b/latest/_sources/design_topics/accuracy.md.txt @@ -0,0 +1,78 @@ +(accuracy)= + +# Accuracy + +> Array API specification for minimum accuracy requirements. + +## Arithmetic Operations + +The results of element-wise arithmetic operations + +- `+` +- `-` +- `*` +- `/` +- `%` + +including the corresponding element-wise array APIs defined in this standard + +- add +- subtract +- multiply +- divide + +for floating-point operands must return the nearest representable value according to IEEE 754-2019 and a supported rounding mode. By default, the rounding mode should be `roundTiesToEven` (i.e., ties rounded toward the nearest value with an even least significant bit). + +## Mathematical Functions + +This specification does **not** precisely define the behavior of the following functions + +- acos +- acosh +- asin +- asinh +- atan +- atan2 +- atanh +- cos +- cosh +- exp +- expm1 +- log +- log1p +- log2 +- log10 +- pow +- sin +- sinh +- tan +- tanh + +except to require specific results for certain argument values that represent boundary cases of interest. + +```{note} + +To help readers identify functions lacking precisely defined accuracy behavior, this specification uses the phrase "implementation-dependent approximation" in function descriptions. +``` + +For other argument values, these functions should compute approximations to the results of respective mathematical functions; however, this specification recognizes that array libraries may be constrained by underlying hardware and/or seek to optimize performance over absolute accuracy and, thus, allows some latitude in the choice of approximation algorithms. + +Although the specification leaves the choice of algorithms to the implementation, this specification recommends (but does not specify) that implementations use the approximation algorithms for IEEE 754-2019 arithmetic contained in [FDLIBM](http://www.netlib.org/fdlibm), the freely distributable mathematical library from Sun Microsystems, or some other comparable IEEE 754-2019 compliant mathematical library. + +```{note} + +With exception of a few mathematical functions, returning results which are indistinguishable from correctly rounded infinitely precise results is difficult, if not impossible, to achieve due to the algorithms involved, the limits of finite-precision, and error propagation. However, this specification recognizes that numerical accuracy alignment among array libraries is desirable in order to ensure portability and reproducibility. Accordingly, for each mathematical function, the specification test suite includes test values which span a function's domain and reports the average and maximum deviation from either a designated standard implementation (e.g., an arbitrary precision arithmetic implementation) or an average computed across a subset of known array library implementations. Such reporting aids users who need to know how accuracy varies among libraries and developers who need to check the validity of their implementations. +``` + +## Statistical Functions + +This specification does not specify accuracy requirements for statistical functions; however, this specification does expect that a conforming implementation of the array API standard will make a best-effort attempt to ensure that its implementations are theoretically sound and numerically robust. + +```{note} + +In order for an array library to pass the specification test suite, an array library's statistical function implementations must satisfy certain bare-minimum accuracy requirements (e.g., accurate summation of a small set of positive integers). Unfortunately, imposing more rigorous accuracy requirements is not possible without severely curtailing possible implementation algorithms and unduly increasing implementation complexity. +``` + +## Linear Algebra + +This specification does not specify accuracy requirements for linear algebra functions; however, this specification does expect that a conforming implementation of the array API standard will make a best-effort attempt to ensure that its implementations are theoretically sound and numerically robust. \ No newline at end of file diff --git a/latest/_sources/design_topics/copies_views_and_mutation.md.txt b/latest/_sources/design_topics/copies_views_and_mutation.md.txt new file mode 100644 index 000000000..1911718b7 --- /dev/null +++ b/latest/_sources/design_topics/copies_views_and_mutation.md.txt @@ -0,0 +1,76 @@ +(copyview-mutability)= + +# Copy-view behaviour and mutability + +Strided array implementations (e.g. NumPy, PyTorch, CuPy, MXNet) typically +have the concept of a "view", meaning an array containing data in memory that +belongs to another array (i.e. a different "view" on the original data). +Views are useful for performance reasons - not copying data to a new location +saves memory and is faster than copying - but can also affect the semantics +of code. This happens when views are combined with _mutating_ operations. +This simple example illustrates that: + +```python +x = ones(1) +y = x[:] # `y` *may* be a view on the data of `x` +y -= 1 # if `y` is a view, this modifies `x` +``` + +Code as simple as the above example will not be portable between array +libraries - for NumPy/PyTorch/CuPy/MXNet `x` will contain the value `0`, +while for TensorFlow/JAX/Dask it will contain the value `1`. The combination +of views and mutability is fundamentally problematic here if the goal is to +be able to write code with unambiguous semantics. + +Views are necessary for getting good performance out of the current strided +array libraries. It is not always clear however when a library will return a +view, and when it will return a copy. This API standard does not attempt to +specify this - libraries can do either. + +There are several types of operations that do in-place mutation of data +contained in arrays. These include: + +1. Inplace operators (e.g. `*=`) +2. Item assignment (e.g. `x[0] = 1`) +3. Slice assignment (e.g., `x[:2, :] = 3`) +4. The `out=` keyword present in some strided array libraries (e.g. `sin(x, out=y`)) + +Libraries like TensorFlow and JAX tend to support inplace operators, provide +alternative syntax for item and slice assignment (e.g. an `update_index` +function or `x.at[idx].set(y)`), and have no need for `out=`. + +A potential solution could be to make views read-only, or use copy-on-write +semantics. Both are hard to implement and would present significant issues +for backwards compatibility for current strided array libraries. Read-only +views would also not be a full solution, given that mutating the original +(base) array will also result in ambiguous semantics. Hence this API standard +does not attempt to go down this route. + +Both inplace operators and item/slice assignment can be mapped onto +equivalent functional expressions (e.g. `x[idx] = val` maps to +`x.at[idx].set(val)`), and given that both inplace operators and item/slice +assignment are very widely used in both library and end user code, this +standard chooses to include them. + +The situation with `out=` is slightly different - it's less heavily used, and +easier to avoid. It's also not an optimal API, because it mixes an +"efficiency of implementation" consideration ("you're allowed to do this +inplace") with the semantics of a function ("the output _must_ be placed into +this array). There are libraries that do some form of tracing or abstract +interpretation over a language that does not support mutation (to make +analysis easier); in those cases implementing `out=` with correct handling of +views may even be impossible to do. There's alternatives, for example the +donated arguments in JAX or working buffers in LAPACK, that allow the user to +express "you _may_ overwrite this data, do whatever is fastest". Given that +those alternatives aren't widely used in array libraries today, this API +standard chooses to (a) leave out `out=`, and (b) not specify another method +of reusing arrays that are no longer needed as buffers. + +This leaves the problem of the initial example - with this API standard it +remains possible to write code that will not work the same for all array +libraries. This is something that the user must be careful about. + +```{note} + +It is recommended that users avoid any mutating operations when a view may be involved. +``` diff --git a/latest/_sources/design_topics/data_interchange.md.txt b/latest/_sources/design_topics/data_interchange.md.txt new file mode 100644 index 000000000..0cfa0c784 --- /dev/null +++ b/latest/_sources/design_topics/data_interchange.md.txt @@ -0,0 +1,131 @@ +(data-interchange)= + +# Data interchange mechanisms + +This section discusses the mechanism to convert one type of array into another. +As discussed in the {ref}`assumptions-dependencies ` section, +_functions_ provided by an array library are not expected to operate on +_array types_ implemented by another library. Instead, the array can be +converted to a "native" array type. + +The interchange mechanism must offer the following: + +1. Data access via a protocol that describes the memory layout of the array + in an implementation-independent manner. + _Rationale: any number of libraries must be able to exchange data, and no + particular package must be needed to do so._ +2. Support for all dtypes in this API standard (see {ref}`data-types`). +3. Device support. It must be possible to determine on what device the array + that is to be converted lives. + _Rationale: there are CPU-only, GPU-only, and multi-device array types; + it's best to support these with a single protocol (with separate + per-device protocols it's hard to figure out unambiguous rules for which + protocol gets used, and the situation will get more complex over time + as TPU's and other accelerators become more widely available)._ +4. Zero-copy semantics where possible, making a copy only if needed (e.g. + when data is not contiguous in memory). + _Rationale: performance._ +5. A Python-side and a C-side interface, the latter with a stable C ABI. + _Rationale: all prominent existing array libraries are implemented in + C/C++, and are released independently from each other. Hence a stable C + ABI is required for packages to work well together._ + +The best candidate for this protocol is DLPack. See the +[RFC to adopt DLPack](https://github.com/data-apis/consortium-feedback/issues/1) +for details. + +```{note} + +The main alternatives to DLPack are device-specific methods: + +- The [buffer protocol](https://docs.python.org/dev/c-api/buffer.html) on CPU +- `__cuda_array_interface__` for CUDA, specified in the Numba documentation + [here](https://numba.pydata.org/numba-doc/0.43.0/cuda/cuda_array_interface.html) + (Python-side only at the moment) + +An issue with device-specific protocols are: if two libraries both +support multiple device types, in which order should the protocols be +tried? A growth in the number of protocols to support each time a new +device gets supported by array libraries (e.g. TPUs, AMD GPUs, emerging +hardware accelerators) also seems undesirable. + +In addition to the above argument, it is also clear from adoption +patterns that DLPack has the widest support. The buffer protocol, despite +being a lot older and standardized as part of Python itself via PEP 3118, +hardly has any support from array libraries. CPU interoperability is +mostly dealt with via the NumPy-specific `__array__` (which, when called, +means the object it is attached to must return a `numpy.ndarray` +containing the data the object holds). +``` + + +## Syntax for data interchange with DLPack + +The array API will offer the following syntax for data interchange: + +1. A `from_dlpack(x)` function, which accepts (array) objects with a + `__dlpack__` method and uses that method to construct a new array + containing the data from `x`. +2. `__dlpack__(self, stream=None)` and `__dlpack_device__` methods on the + array object, which will be called from within `from_dlpack`, to query + what device the array is on (may be needed to pass in the correct + stream, e.g. in the case of multiple GPUs) and to access the data. + + +## Semantics + +DLPack describe the memory layout of strided, n-dimensional arrays. +When a user calls `y = from_dlpack(x)`, the library implementing `x` (the +"producer") will provide access to the data from `x` to the library +containing `from_dlpack` (the "consumer"). If possible, this must be +zero-copy (i.e. `y` will be a _view_ on `x`). If not possible, that library +may make a copy of the data. In both cases: +- the producer keeps owning the memory +- `y` may or may not be a view, therefore the user must keep the + recommendation to avoid mutating `y` in mind - see + {ref}`copyview-mutability`. +- Both `x` and `y` may continue to be used just like arrays created in other ways. + +If an array that is accessed via the interchange protocol lives on a +device that the requesting library does not support, it is recommended to +raise a `TypeError`. + +Stream handling through the `stream` keyword applies to CUDA and ROCm (perhaps +to other devices that have a stream concept as well, however those haven't been +considered in detail). The consumer must pass the stream it will use to the +producer; the producer must synchronize or wait on the stream when necessary. +In the common case of the default stream being used, synchronization will be +unnecessary so asynchronous execution is enabled. + + +## Implementation + +_Note that while this API standard largely tries to avoid discussing implementation details, some discussion and requirements are needed here because data interchange requires coordination between implementers on, e.g., memory management._ + +![Diagram of DLPack structs](/_static/images/DLPack_diagram.png) + +_DLPack diagram. Dark blue are the structs it defines, light blue struct members, gray text enum values of supported devices and data types._ + +The `__dlpack__` method will produce a `PyCapsule` containing a +`DLPackManagedTensor`, which will be consumed immediately within +`from_dlpack` - therefore it is consumed exactly once, and it will not be +visible to users of the Python API. + +The consumer must set the PyCapsule name to `"used_dltensor"`, and call the +`deleter` of the `DLPackManagedTensor` when it no longer needs the data. + +When the `strides` field in the `DLTensor` struct is `NULL`, it indicates a +row-major compact array. If the array is of size zero, the data pointer in +`DLTensor` should be set to either `NULL` or `0`. + +DLPack version used must be `0.2 <= DLPACK_VERSION < 1.0`. For further +details on DLPack design and how to implement support for it, +refer to [github.com/dmlc/dlpack](https://github.com/dmlc/dlpack). + +:::{warning} +DLPack contains a `device_id`, which will be the device ID (an integer, `0, 1, ...`) which the producer library uses. In practice this will likely be the same numbering as that of the consumer, however that is not guaranteed. Depending on the hardware type, it may be possible for the consumer library implementation to look up the actual device from the pointer to the data - this is possible for example for CUDA device pointers. + +It is recommended that implementers of this array API consider and document +whether the `.device` attribute of the array returned from `from_dlpack` is +guaranteed to be in a certain order or not. +::: diff --git a/latest/_sources/design_topics/device_support.md.txt b/latest/_sources/design_topics/device_support.md.txt new file mode 100644 index 000000000..7788e2949 --- /dev/null +++ b/latest/_sources/design_topics/device_support.md.txt @@ -0,0 +1,104 @@ +(device-support)= + +# Device support + +For libraries that support execution on more than a single hardware device - e.g. CPU and GPU, or multiple GPUs - it is important to be able to control on which device newly created arrays get placed and where execution happens. Attempting to be fully implicit doesn't always scale well to situations with multiple GPUs. + +Existing libraries employ one or more of these three methods to exert such control: +1. A global default device, which may be fixed or user-switchable. +2. A context manager to control device assignment within its scope. +3. Local control via explicit keywords and a method to transfer arrays to another device. + +This standard chooses to add support for method 3 (local control), because it's the most explicit and granular, with its only downside being verbosity. A context manager may be added in the future - see {ref}`device-out-of-scope` for details. + + +## Intended usage + +The intended usage for the device support in the current version of the +standard is _device handling in library code_. The assumed pattern is that +users create arrays (for which they can use all the relevant device syntax +that the library they use provides), and that they then pass those arrays +into library code which may have to do the following: + +- Create new arrays on the same device as an array that's passed in. +- Determine whether two input arrays are present on the same device or not. +- Move an array from one device to another. +- Create output arrays on the same device as the input arrays. +- Pass on a specified device to other library code. + +```{note} +Given that there is not much that's currently common in terms of +device-related syntax between different array libraries, the syntax included +in the standard is kept as minimal as possible while enabling the +above-listed use cases. +``` + +## Syntax for device assignment + +The array API will offer the following syntax for device assignment and +cross-device data transfer: + +1. A `.device` property on the array object, which returns a `Device` object + representing the device the data in the array is stored on, and supports + comparing devices for equality with `==` and `!=` within the same library + (e.g., by implementing `__eq__`); comparing device objects from different + libraries is out of scope). +2. A `device=None` keyword for array creation functions, which takes an + instance of a `Device` object. +3. A `.to_device(device)` method on the array object, with `device` again being + a `Device` object, to move an array to a different device. + +```{note} +The only way to obtain a `Device` object is from the `.device` property on +the array object, hence there is no `Device` object in the array API itself +that can be instantiated to point to a specific physical or logical device. +``` + + +## Semantics + +Handling devices is complex, and some frameworks have elaborate policies for +handling device placement. Therefore this section only gives recommendations, +rather than hard requirements: + +- Respect explicit device assignment (i.e. if the input to the `device=` keyword + is not `None`, guarantee that the array is created on the given device, and + raise an exception otherwise). +- Preserve device assignment as much as possible (e.g. output arrays from a + function are expected to be on the same device as input arrays to the + function). +- Raise an exception if an operation involves arrays on different devices + (i.e. avoid implicit data transfer between devices). +- Use a default for `device=None` which is consistent between functions + within the same library. +- If a library has multiple ways of controlling device placement, the most + explicit method should have the highest priority. For example: + 1. If `device=` keyword is specified, that always takes precedence + 2. If `device=None`, then use the setting from a context manager, if set. + 3. If no context manager was used, then use the global default device/strategy + + +(device-out-of-scope)= + +## Out of scope for device support + +Individual libraries may offers APIs for one or more of the following topics, +however those are out of scope for this standard: + +- Identifying a specific physical or logical device across libraries +- Setting a default device globally +- Stream/queue control +- Distributed allocation +- Memory pinning +- A context manager for device control + +```{note} +A context manager for controlling the default device is present in most existing array +libraries (NumPy being the exception). There are concerns with using a +context manager however. A context manager can be tricky to use at a high +level, since it may affect library code below function calls (non-local +effects). See, e.g., [this PyTorch issue](https://github.com/pytorch/pytorch/issues/27878) +for a discussion on a good context manager API. + +Adding a context manager may be considered in a future version of this API standard. +``` diff --git a/latest/_sources/design_topics/index.rst.txt b/latest/_sources/design_topics/index.rst.txt new file mode 100644 index 000000000..6e41899ca --- /dev/null +++ b/latest/_sources/design_topics/index.rst.txt @@ -0,0 +1,14 @@ +Design topics & constraints +=========================== + +.. toctree:: + :caption: Design topics & constraints + :maxdepth: 1 + + copies_views_and_mutation + data_interchange + device_support + static_typing + accuracy + C_API + parallelism diff --git a/latest/_sources/design_topics/parallelism.md.txt b/latest/_sources/design_topics/parallelism.md.txt new file mode 100644 index 000000000..38ccb9343 --- /dev/null +++ b/latest/_sources/design_topics/parallelism.md.txt @@ -0,0 +1,23 @@ +# Parallelism + +Parallelism is mostly, but not completely, an execution or runtime concern +rather than an API concern. Execution semantics are out of scope for this API +standard, and hence won't be discussed further here. The API related part +involves how libraries allow users to exercise control over the parallelism +they offer, such as: + +- Via environment variables. This is the method of choice for BLAS libraries and libraries using OpenMP. +- Via a keyword to individual functions or methods. Examples include the `n_jobs` keyword used in scikit-learn and the `workers` keyword used in SciPy. +- Build-time settings to enable a parallel or distributed backend. +- Via letting the user set chunk sizes. Dask uses this approach. + +When combining multiple libraries, one has to deal with auto-parallelization +semantics and nested parallelism. Two things that could help improve the +coordination of parallelization behavior in a stack of Python libraries are: + +1. A common API pattern for enabling parallelism +2. A common library providing a parallelization layer + +Option (1) may possibly fit in a future version of this array API standard. +[array-api issue 4](https://github.com/data-apis/array-api/issues/4) contains +more detailed discussion on the topic of parallelism. \ No newline at end of file diff --git a/latest/_sources/design_topics/static_typing.md.txt b/latest/_sources/design_topics/static_typing.md.txt new file mode 100644 index 000000000..cc744ca0f --- /dev/null +++ b/latest/_sources/design_topics/static_typing.md.txt @@ -0,0 +1,48 @@ +# Static typing + +Good support for static typing both in array libraries and array-consuming +code is desirable. Therefore the exact type or set of types for each +parameter, keyword and return value is specified for functions and methods - +see {ref}`function-and-method-signatures`. That section specifies arrays +simply as `array`; what that means is dealt with in this section. + +Introducing type annotations in libraries became more relevant only when +Python 2.7 support was dropped at the start of 2020. As a consequence, using +type annotations with array libraries is largely still a work in progress. +This version of the API standard does not deal with trying to type _array +properties_ like shape, dimensionality or dtype, because that's not a solved +problem in individual array libraries yet. + +An `array` type annotation can mean either the type of one specific array +object, or some superclass or typing Protocol - as long as it is consistent +with the array object specified in {ref}`array-object`. To illustrate by +example: + +```python +# `Array` is a particular class in the library +def sin(x: Array, / ...) -> Array: + ... +``` + +and + +```python +# There's some base class `_BaseArray`, and there may be multiple +# array subclasses inside the library +A = TypeVar('A', bound=_BaseArray) +def sin(x: A, / ...) -> A: + ... +``` +should both be fine. There may be other variations possible. Also note that +this standard does not require that input and output array types are the same +(they're expected to be defined in the same library though). Given that +array libraries don't have to be aware of other types of arrays defined in +other libraries (see {ref}`assumptions-dependencies`), this should be enough +for a single array library. + +That said, an array-consuming library aiming to support multiple array types +may need more - for example a protocol to enable structural subtyping. This +API standard currently takes the position that it does not provide any +reference implementation or package that can or should be relied on at +runtime, hence no such protocol is defined here. This may be dealt with in a +future version of this standard. diff --git a/latest/_sources/future_API_evolution.md.txt b/latest/_sources/future_API_evolution.md.txt new file mode 100644 index 000000000..719b554e3 --- /dev/null +++ b/latest/_sources/future_API_evolution.md.txt @@ -0,0 +1,60 @@ +(future-API-evolution)= + +# Future API standard evolution + +## Scope extensions + +Proposals for scope extensions in a future version of the API standard will follow +the process documented at https://github.com/data-apis/governance/blob/master/process_document.md + +In summary, proposed new APIs go through several maturity stages, and will only be +accepted in a future version of this API standard once they have reached the "Final" +maturity stage, which means multiple array libraries have compliant implementations +and real-world experience from use of those implementations is available. + + +## Backwards compatibility + +Functions, objects, keywords and specified behavior are added to this API standard +only if those are already present in multiple existing array libraries, and if there is +data that those APIs are used. Therefore it is highly unlikely that future versions +of this standard will make backwards-incompatible changes. + +The aim is for future versions to be 100% backwards compatible with older versions. +Any exceptions must have strong rationales and be clearly documented in the updated +API specification. + + +(api-versioning)= + +## Versioning + +This API standard uses the following versioning scheme: + +- The version is date-based, in the form `yyyy.mm` (e.g., `2020.12`). +- The version shall not include a standard way to do `alpha`/`beta`/`rc` or + `.post`/`.dev` type versions. + _Rationale: that's for Python packages, not for a standard._ +- The version must be made available at runtime via an attribute + `__array_api_version__` by a compliant implementation, in `'yyyy.mm'` format + as a string, in the namespace that implements the API standard. + _Rationale: dunder version strings are the standard way of doing this._ + +No utilities for dealing with version comparisons need to be provided; given +the format simple string comparisons with Python operators (`=-`, `<`, `>=`, +etc.) will be enough. + +```{note} + +Rationale for the `yyyy.mm` versioning scheme choice: +the API will be provided as part of a library, which already has a versioning +scheme (typically PEP 440 compliant and in the form `major.minor.bugfix`), +and a way to access it via `module.__version__`. The API standard version is +completely independent from the package version. Given the standardization +process, it resembles a C/C++ versioning scheme (e.g. `C99`, `C++14`) more +than Python package versioning. +``` + +The frequency of releasing a new version of an API standard will likely be at +regular intervals and on the order of one year, however no assumption on +frequency of new versions appearing must be made. \ No newline at end of file diff --git a/latest/_sources/index.rst.txt b/latest/_sources/index.rst.txt new file mode 100644 index 000000000..e7a466413 --- /dev/null +++ b/latest/_sources/index.rst.txt @@ -0,0 +1,29 @@ +Python array API standard +========================= + +Contents +-------- + +.. toctree:: + :caption: Context + :maxdepth: 1 + + purpose_and_scope + use_cases + assumptions + +.. toctree:: + :caption: API + :maxdepth: 1 + + design_topics/index + future_API_evolution + API_specification/index + +.. toctree:: + :caption: Methodology and Usage + :maxdepth: 1 + + usage_data + verification_test_suite + benchmark_suite diff --git a/latest/_sources/purpose_and_scope.md.txt b/latest/_sources/purpose_and_scope.md.txt new file mode 100644 index 000000000..a8fb596c6 --- /dev/null +++ b/latest/_sources/purpose_and_scope.md.txt @@ -0,0 +1,435 @@ +# Purpose and scope + +## Introduction + +Python users have a wealth of choice for libraries and frameworks for +numerical computing, data science, machine learning, and deep learning. New +frameworks pushing forward the state of the art in these fields are appearing +every year. One unintended consequence of all this activity and creativity +has been fragmentation in multidimensional array (a.k.a. tensor) libraries - +which are the fundamental data structure for these fields. Choices include +NumPy, Tensorflow, PyTorch, Dask, JAX, CuPy, MXNet, Xarray, and others. + +The APIs of each of these libraries are largely similar, but with enough +differences that it's quite difficult to write code that works with multiple +(or all) of these libraries. This array API standard aims to address that +issue, by specifying an API for the most common ways arrays are constructed +and used. + +Why not simply pick an existing API and bless that as the standard? In short, +because there are often good reasons for the current inconsistencies between +libraries. The most obvious candidate for that existing API is NumPy. However +NumPy was not designed with non-CPU devices, graph-based libraries, or JIT +compilers in mind. Other libraries often deviate from NumPy for good +(necessary) reasons. Choices made in this API standard are often the same +ones NumPy makes, or close to it, but are different where necessary to make +sure all existing array libraries can adopt this API. + + +### This API standard + +This document aims to standardize functionality that exists in most/all array +libraries and either is commonly used or is needed for +consistency/completeness. Usage is determined via analysis of downstream +libraries, see {ref}`usage-data`. An example of consistency is: there are +functional equivalents for all Python operators (including the rarely used +ones). + +Beyond usage and consistency, there's a set of use cases that inform the API +design to ensure it's fit for a wide range of users and situations - see +{ref}`use-cases`. + +A question that may arise when reading this document is: _"what about +functionality that's not present in this document?_ This: + +- means that there is no guarantee the functionality is present in libraries + adhering to the standard +- does _not_ mean that that functionality is unimportant +- may indicate that that functionality, if present in a particular array + library, is unlikely to be present in all other libraries + +```{note} + +This document is ready for wider community review, but still contains a +number of TODOs, and is expected to change and evolve before a first +official release. See {ref}`future-API-evolution` for proposed +versioning. +``` + +### History + +The first library for numerical and scientific computing in Python was +Numeric, developed in the mid-1990s. In the early 2000s a second, similar +library, Numarray, was created. In 2005 NumPy was written, superceding both +Numeric and Numarray and resolving the fragmentation at that time. For +roughly a decade, NumPy was the only widely used array library. Over the past +~5 years, mainly due to the emergence of new hardware and the rise of deep +learning, many other libraries have appeared, leading to more severe +fragmentation. Concepts and APIs in newer libraries were often inspired by +(or copied from) those in older ones - and then changed or improved upon to +fit new needs and use cases. Individual library authors discussed ideas, +however there was never (before this array API standard) an serious attempt +to coordinate between all libraries to avoid fragmentation and arrive at a +common API standard. + +The idea for this array API standard grew gradually out of many conversations +between maintainers during 2019-2020. It quickly became clear that any +attempt to write a new "reference library" to fix the current fragmentation +was infeasible - unlike in 2005, there are now too many different use cases +and too many stakeholders, and the speed of innovation is too high. In May +2020 an initial group of maintainers was assembled in the [Consortium for +Python Data API Standards](https://data-apis.org/) to start drafting a +specification for an array API that could be adopted by each of the existing +array and tensor libraries. That resulted in this document, describing that +API. + + +(Scope)= + +## Scope (includes out-of-scope / non-goals) + +This section outlines what is in scope and out of scope for this API standard. + +### In scope + +The scope of the array API standard includes: + +- Functionality which needs to be included in an array library for it to adhere + to this standard. +- Names of functions, methods, classes and other objects. +- Function signatures, including type annotations. +- Semantics of functions and methods. I.e. expected outputs including precision + for and dtypes of numerical results. +- Semantics in the presence of `nan`'s, `inf`'s, empty arrays (i.e. arrays + including one or more dimensions of size `0`). +- Casting rules, broadcasting, indexing +- Data interchange. I.e. protocols to convert one type of array into another + type, potentially sharing memory. +- Device support. + +Furthermore, meta-topics included in this standard include: + +- Use cases for the API standard and assumptions made in it +- API standard adoption +- API standard versioning +- Future API standard evolution +- Array library and API standard versioning +- Verification of API standard conformance + +The concrete set of functionality that is in scope for this version of the +standard is shown in this diagram (_TODO: update after deciding on how optional +extensions are dealt with_): + +![Scope of array API](_static/images/scope_of_array_API.png) + + +**Goals** for the API standard include: + +- Make it possible for array-consuming libraries to start using multiple types + of arrays as inputs. +- Enable more sharing and reuse of code built on top of the core functionality + in the API standard. +- For authors of new array libraries, provide a concrete API that can be + adopted as is, rather than each author having to decide what to borrow from + where and where to deviate. +- Make the learning curve for users less steep when they switch from one array + library to another one. + + +### Out of scope + +1. Implementations of the standard are out of scope. + + _Rationale: the standard will consist of a document and an accompanying test + suite with which the conformance of an implementation can be verified. Actual + implementations will live in array libraries; no reference implementation is + planned._ + +2. Execution semantics are out of scope. This includes single-threaded vs. + parallel execution, task scheduling and synchronization, eager vs. delayed + evaluation, performance characteristics of a particular implementation of the + standard, and other such topics. + + _Rationale: execution is the domain of implementations. Attempting to specify + execution behavior in a standard is likely to require much more fine-grained + coordination between developers of implementations, and hence is likely to + become an obstable to adoption._ + +3. Non-Python API standardization (e.g., Cython or NumPy C APIs) + + _Rationale: this is an important topic for some array-consuming libraries, + but there is no widely shared C/Cython API and hence it doesn't make sense at + this point in time to standardize anything. See + the [C API section](design_topics/C_API.md) for more details._ + +4. Standardization of these dtypes is out of scope: bfloat16, complex, extended + precision floating point, datetime, string, object and void dtypes. + + _Rationale: these dtypes aren't uniformly supported, and their inclusion at + this point in time could put a significant implementation burden on + libraries. It is expected that some of these dtypes - in particular + `bfloat16`, `complex64`, and `complex128` - will be included in a future + version of the standard._ + +5. The following topics are out of scope: I/O, polynomials, error handling, + testing routines, building and packaging related functionality, methods of + binding compiled code (e.g., `cffi`, `ctypes`), subclassing of an array + class, masked arrays, and missing data. + + _Rationale: these topics are not core functionality for an array library, + and/or are too tied to implementation details._ + +6. NumPy (generalized) universal functions, i.e. ufuncs and gufuncs. + + _Rationale: these are NumPy-specific concepts, and are mostly just a + particular way of building regular functions with a few extra + methods/properties._ + +7. Behaviour for unexpected/invalid input to functions and methods. + + _Rationale: there are a huge amount of ways in which users can provide + invalid or unspecified input to functionality in the standard. Exception + types or other resulting behaviour cannot be completely covered and would + be hard to make consistent between libraries._ + + +**Non-goals** for the API standard include: + +- Making array libraries identical so they can be merged. + + _Each library will keep having its own particular strength, whether it's + offering functionality beyond what's in the standard, performance advantages + for a given use case, specific hardware or software environment support, or + more._ + +- Implement a backend or runtime switching system to be able to switch from one + array library to another with a single setting or line of code. + + _This may be feasible, however it's assumed that when an array-consuming + library switches from one array type to another, some testing and possibly + code adjustment for performance or other reasons may be needed._ + +- Making it possible to mix multiple array libraries in function calls. + + _Most array libraries do not know about other libraries, and the functions + they implement may try to convert "foreign" input, or raise an exception. + This behaviour is hard to specify; ensuring only a single array type is + used is best left to the end user._ + + +### TBD whether or not in scope, or for a later version + +- Random number generation, Fourier transforms, and miscellaneous functionality + like a padding function. + + _This will be decided later, depending on whether "optional extensions" will + be added to the standard._ + + +### Implications of in/out of scope + +If something is out of scope and therefore will not be part of (the current +version of) the API standard, that means that there are no guarantees that that +functionality works the same way, or even exists at all, across the set of +array libraries that conform to the standard. It does _not_ imply that this +functionality is less important or should not be used. + + +## Stakeholders + +Arrays are fundamental to scientific computing, data science, and machine +learning and deep learning. Hence there are many stakeholders for an array API +standard. The _direct_ stakeholders of this standard are **authors/maintainers of +Python array libraries**. There are many more types of _indirect_ stakeholders +though, including: + +- maintainers of libraries and other programs which depend on array libraries + (called "array-consuming libraries" in the rest of this document) +- authors of non-Python array libraries +- developers of compilers and runtimes with array-specific functionality +- end users + +Libraries that are being actively considered - in terms of current behaviour and +API surface - during the creation of the first version of this standard +include: + +- [NumPy](https://numpy.org) +- [TensorFlow](https://www.tensorflow.org/) +- [PyTorch](https://pytorch.org/) +- [MXNet](https://numpy.mxnet.io/) +- [JAX](https://github.com/google/jax) +- [Dask](https://dask.org/) +- [CuPy](https://cupy.chainer.org/) + +Other Python array libraries that are currently under active development and +could adopt this API standard include: + +- [xarray](https://xarray.pydata.org/) +- [PyData/Sparse](https://sparse.pydata.org) +- [Weld](https://github.com/weld-project/weld) +- [Bohrium](https://bohrium.readthedocs.io/) +- [Arkouda](https://github.com/mhmerrill/arkouda) +- [Legate](https://research.nvidia.com/publication/2019-11_Legate-NumPy%3A-Accelerated) + +There are a huge amount of array-consuming libraries; some of the most +prominent ones that are being taken into account - in terms of current array +API usage or impact of design decisions on them - include (this list is likely +to grow it over time): + +- [Pandas](https://pandas.pydata.org/) +- [SciPy](https://github.com/scipy/scipy) +- [scikit-learn](https://scikit-learn.org/) +- [Matplotlib](https://matplotlib.org/) +- [scikit-image](https://scikit-image.org/) +- [NetworkX](https://networkx.github.io/) + +Array libraries in other languages, some of which may grow a Python API in the +future or have taken inspiration from NumPy or other array libraries, include: + +- [Xtensor](https://xtensor.readthedocs.io) (C++, cross-language) +- [XND](https://xnd.io/) (C, cross-language) +- [stdlib](https://stdlib.io/) (JavaScript) +- [rust-ndarray](https://github.com/rust-ndarray/ndarray) (Rust) +- [rray](https://github.com/r-lib/rray) (R) +- [ND4J](https://github.com/deeplearning4j/nd4j) (JVM) +- [NumSharp](https://github.com/SciSharp/NumSharp) (C#) + +Compilers, runtimes, and dispatching layers for which this API standard may be +relevant: + +- [Cython](https://cython.org/) +- [Numba](http://numba.pydata.org/) +- [Pythran](https://pythran.readthedocs.io/en/latest/) +- [Transonic](https://transonic.readthedocs.io) +- [ONNX](https://onnx.ai/) +- [Apache TVM](https://tvm.apache.org/) +- [MLIR](https://mlir.llvm.org/) +- [TACO](https://github.com/tensor-compiler/taco) +- [unumpy](https://github.com/Quansight-Labs/unumpy) +- [einops](https://github.com/arogozhnikov/einops) +- [Apache Arrow](https://arrow.apache.org/) + + + +## How to read this document + +For guidance on how to read and understand the type annotations included in this specification, consult the Python [documentation](https://docs.python.org/3/library/typing.html). + + +(how-to-adopt-this-api)= + +## How to adopt this API + +Most (all) existing array libraries will find something in this API standard +that is incompatible with a current implementation, and that they cannot +change due to backwards compatibility concerns. Therefore we expect that each +of those libraries will want to offer a standard-compliant API in a _new +namespace_. The question then becomes: how does a user access this namespace? + +The simplest method is: document the import to use to directly access the +namespace (e.g. `import package_name.array_api`). This has two issues though: + +1. Array-consuming libraries that want to support multiple array libraries + then have to explicitly import each library. +2. It is difficult to _version_ the array API standard implementation (see + {ref}`api-versioning`). + +To address both issues, a uniform way must be provided by a conforming +implementation to access the API namespace, namely a [method on the array +object](method-__array_namespace__): + +``` +xp = x.__array_namespace__() +``` + +The method must take one keyword, `api_version=None`, to make it possible to +request a specific API version: + +``` +xp = x.__array_namespace__(api_version='2020.10') +``` + +```{note} + +This is inspired by [NEP 37](https://numpy.org/neps/nep-0037-array-module.html#how-to-use-get-array-module), +however it avoids adding a dependency on NumPy or having to provide a +separate package just to do `get_array_module(x)` + +NEP 37 is still in flux (it was just accepted by JAX and TensorFlow on an +experimental basis), and it's possible that that should be accepted instead. + +TBD: a decision must be made on this topic before a first version of the +standard can become final. We prefer to delay this decision, to see how +NEP 37 adoption will work out. +``` + +The `xp` namespace must contain all functionality specified in +{ref}`api-specification`. It may contain other functionality, however it is +recommended not to add other functions or objects, because that may make it +harder for users to write code that will work with multiple array libraries. + + +* * * + +## Conformance + +A conforming implementation of the array API standard must provide and support +all the functions, arguments, data types, syntax, and semantics described in +this specification. + +A conforming implementation of the array API standard may provide additional +values, objects, properties, data types, and functions beyond those described +in this specification. + +Libraries which aim to provide a conforming implementation but haven't yet +completed such an implementation may, and are encouraged to, provide details on +the level of (non-)conformance. For details on how to do this, see +[Verification - measuring conformance](verification_test_suite.md). + + +* * * + +## Terms and Definitions + +For the purposes of this specification, the following terms and definitions apply. + + + +**array**: +a (usually fixed-size) multidimensional container of items of the same type and size. + +**axis**: +an array dimension. + +**broadcast**: +automatic (implicit) expansion of array dimensions to be of equal sizes without copying array data for the purpose of making arrays with different shapes have compatible shapes for element-wise operations. + +**compatible**: +two arrays whose dimensions are compatible (i.e., where the size of each dimension in one array is either equal to one or to the size of the corresponding dimension in a second array). + +**element-wise**: +an operation performed element-by-element, in which individual array elements are considered in isolation and independently of other elements within the same array. + +**matrix**: +a two-dimensional array. + +**rank**: +number of array dimensions (not to be confused with the number of linearly independent columns of a matrix). + +**shape**: +a tuple of `N` non-negative integers that specify the sizes of each dimension and where `N` corresponds to the number of dimensions. + +**singleton dimension**: +a dimension whose size is one. + +**vector**: +a one-dimensional array. + +* * * + +## Normative References + +The following referenced documents are indispensable for the application of this specification. + +- __IEEE 754-2019: IEEE Standard for Floating-Point Arithmetic.__ Institute of Electrical and Electronic Engineers, New York (2019). +- Scott Bradner. 1997. "Key words for use in RFCs to Indicate Requirement Levels". RFC 2119. doi:[10.17487/rfc2119](https://tools.ietf.org/html/rfc2119). diff --git a/latest/_sources/usage_data.md.txt b/latest/_sources/usage_data.md.txt new file mode 100644 index 000000000..7963333ff --- /dev/null +++ b/latest/_sources/usage_data.md.txt @@ -0,0 +1,86 @@ +(usage-data)= + +# Usage Data + +> Summary of existing array API design and usage. + +## Introduction + +With rare exception, technical standardization ("standardization") occurs neither in a vacuum nor from first principles. Instead, standardization finds its origins in two or more, sometimes competing, implementations differing in design and behavior. These differences introduce friction as those (e.g., downstream end-users and library authors) who operate at higher levels of abstraction must either focus on an implementation subset (e.g., only NumPy-like array libraries) or accommodate variation through increased complexity (e.g., if NumPy array, call method `.foo()`; else if Dask array, call method `.bar()`). + +Standardization aspires to reduce this friction and is a process which codifies that which is common, while still encouraging experimentation and innovation. Through the process of standardization, implementations can align around a subset of established practices and channel development resources toward that which is new and novel. In short, standardization aims to thwart reinventing the proverbial wheel. + +A foundational step in standardization is articulating a subset of established practices and defining those practices in unambiguous terms. To this end, the standardization process must approach the problem from two directions: **design** and **usage**. The former direction seeks to understand + +- current implementation design (APIs, names, signatures, classes, and objects) +- current implementation semantics (calling conventions and behavior) + +while the latter direction seeks to quantify API + +- consumers (e.g., which downstream libraries utilize an API?) +- usage frequency (e.g., how often is an API consumed?) +- consumption patterns (e.g., which optional arguments are provided and in what context?) + +By analyzing both design and usage, the standardization process grounds specification decisions in empirical data and analysis. + +## Design + +To understand API design, standardization follows the following process. + +- Identify a representative sample of commonly used Python array libraries (e.g., NumPy, Dask Array, CuPy, MXNet, JAX, TensorFlow, and PyTorch). +- Acquire public APIs (e.g., by analyzing module exports and scraping public documentation). +- Unify and standardize public API data representation for subsequent analysis. +- Extract commonalities and differences by analyzing the intersection and complement of available APIs. +- Derive a common API subset suitable for standardization (based on prevalence and ease of implementation), where such a subset may include attribute names, method names, and positional and keyword arguments. +- Leverage usage data to validate API need and to inform naming conventions, supported data types, and/or optional arguments. +- Summarize findings and provide tooling for additional analysis and exploration. + +See the [`array-api-comparison`](https://github.com/data-apis/array-api-comparison) +repository for design data and summary analysis. + +## Usage + +To understand usage patterns, standardization follows the following process. + +- Identify a representative sample of commonly used Python libraries ("downstream libraries") which consume the subset of array libraries identified during design analysis (e.g., pandas, Matplotlib, SciPy, Xarray, scikit-learn, and scikit-image). +- Instrument downstream libraries in order to record Python array API calls. +- Collect traces while running downstream library test suites. +- Transform trace data into structured data (e.g., as JSON) for subsequent analysis. +- Generate empirical APIs based on provided arguments and associated types, noting which downstream library called which empirical API and at what frequency. +- Derive a single inferred API which unifies the individual empirical API calling semantics. +- Organize API results in human-readable form as type definition files. +- Compare the inferred API to the documented API. + +The following is an inferred API for `numpy.arange`. The docstring includes the number of lines of code that invoked this function for each downstream library when running downstream library test suites. + +```python +def arange( + _0: object, + /, + *_args: object, + dtype: Union[type, str, numpy.dtype, None] = ..., + step: Union[int, float] = ..., + stop: int = ..., +): + """ + usage.dask: 347 + usage.matplotlib: 359 + usage.pandas: 894 + usage.sample-usage: 4 + usage.scipy: 1173 + usage.skimage: 174 + usage.sklearn: 373 + usage.xarray: 666 + """ + ... +``` + +See the [`python-record-api`](https://github.com/data-apis/python-record-api) repository for source code, usage data, and analysis. To perform a similar analysis on additional downstream libraries, including those not publicly released, see the published PyPI [package](https://pypi.org/project/record_api/). + +## Use in Decision-Making + +Design and usage data support specification decision-making in the following ways. + +- Validate user stories to ensure that proposals satisfy existing needs. +- Define scope to ensure that proposals address general array library design requirements (i.e., proposals must have broad applicability and be possible to implement with a reasonable amount of effort). +- Inform technical design discussions to ensure that proposals are grounded in empirical data. \ No newline at end of file diff --git a/latest/_sources/use_cases.md.txt b/latest/_sources/use_cases.md.txt new file mode 100644 index 000000000..bd9f4888e --- /dev/null +++ b/latest/_sources/use_cases.md.txt @@ -0,0 +1,235 @@ +(use-cases)= + +# Use cases + +Use cases inform the requirements for, and design choices made in, this array +API standard. This section first discusses what types of use cases are +considered, and then works out a few concrete use cases in more detail. + +## Types of use cases + +- Packages that depend on a specific array library currently, and would like + to support multiple of them (e.g. for GPU or distributed array support, for + improved performance, or for reaching a wider user base). +- Writing new libraries/tools that wrap multiple array libraries. +- Projects that implement new types of arrays with, e.g., hardware-specific + optimizations or auto-parallelization behavior, and need an API to put on + top that is familiar to end users. +- End users that want to switch from one library to another without learning + about all the small differences between those libraries. + + +## Concrete use cases + +- {ref}`use-case-scipy` +- {ref}`use-case-einops` +- {ref}`use-case-xtensor` +- {ref}`use-case-numba` + + +(use-case-scipy)= + +### Use case 1: add hardware accelerator and distributed support to SciPy + +When surveying a representative set of advanced users and research software +engineers in 2019 (for [this NSF proposal](https://figshare.com/articles/Mid-Scale_Research_Infrastructure_-_The_Scientific_Python_Ecosystem/8009441)), +the single most common pain point brought up about SciPy was performance. + +SciPy heavily relies on NumPy (its only non-optional runtime dependency). +NumPy provides an array implementation that's in-memory, CPU-only and +single-threaded. Common performance-related wishes users have are: + +- parallel algorithms (can be multi-threaded or multiprocessing based) +- support for distributed arrays (with Dask in particular) +- support for GPUs and other hardware accelerators (shortened to just "GPU" + in the rest of this use case) + +Some parallelism can be supported in SciPy, it has a `workers` keyword +(similar to scikit-learn's `n_jobs` keyword) that allows specifying to use +parallelism in some algorithms. However SciPy itself will not directly start +depending on a GPU or distributed array implementation, or contain (e.g.) +CUDA code - that's not maintainable given the resources for development. +_However_, there is a way to provide distributed or GPU support. Part of the +solution is provided by NumPy's "array protocols" (see gh-1), that allow +dispatching to other array implementations. The main problem then becomes how +to know whether this will work with a particular distributed or GPU array +implementation - given that there are zero other array implementations that +are even close to providing full NumPy compatibility - without adding that +array implementation as a dependency. + +It's clear that SciPy functionality that relies on compiled extensions (C, +C++, Cython, Fortran) directly can't easily be run on another array library +than NumPy (see [C API](design_topics/C_API.md) for more details about this topic). Pure Python +code can work though. There's two main possibilities: + +1. Testing with another package, manually or in CI, and simply provide a list + of functionality that is found to work. Then make ad-hoc fixes to expand + the set that works. +2. Start relying on a well-defined subset of the NumPy API (or a new + NumPy-like API), for which compatibility is guaranteed. + +Option (2) seems strongly preferable, and that "well-defined subset" is _what +an API standard should provide_. Testing will still be needed, to ensure there +are no critical corner cases or bugs between array implementations, however +that's then a very tractable task. + +As a concrete example, consider the spectral analysis functions in `scipy.signal`. +All of those functions (e.g., `periodogram`, `spectrogram`, `csd`, `welch`, `stft`, +`istft`) are pure Python - with the exception of `lombscargle` which is ~40 +lines of Cython - and uses NumPy function calls, array attributes and +indexing. The beginning of each function could be changed to retrieve the +module that implements the array API standard for the given input array type, +and then functions from that module could be used instead of NumPy functions. + +If the user has another array type, say a CuPy or PyTorch array `x` on their +GPU, doing: +``` +from scipy import signal + +signal.welch(x) +``` +will result in: +``` +# For CuPy +ValueError: object __array__ method not producing an array + +# For PyTorch +TypeError: can't convert cuda:0 device type tensor to numpy. +``` +and therefore the user will have to explicitly convert to and from a +`numpy.ndarray` (which is quite inefficient): +``` +# For CuPy +x_np = cupy.asnumpy(x) +freq, Pxx = (cupy.asarray(res) for res in signal.welch(x_np)) + +# For PyTorch +x_np = x.cpu().numpy() +# Note: ends up with tensors on CPU, may still have to move them back +freq, Pxx = (torch.tensor(res) for res in signal.welch(x_np)) +``` +This code will look a little different for each array library. The end goal +here is to be able to write this instead as: +``` +freq, Pxx = signal.welch(x) +``` +and have `freq`, `Pxx` be arrays of the same type and on the same device as `x`. + +```{note} + +This type of use case applies to many other libraries, from scikit-learn +and scikit-image to domain-specific libraries like AstroPy and +scikit-bio, to code written for a single purpose or user. +``` + +(use-case-einops)= + +### Use case 2: simplify einops by removing the backend system + +[einops](https://github.com/arogozhnikov/einops) is a library that provides flexible tensor operations and supports many array libraries (NumPy, TensorFlow, PyTorch, CuPy, MXNet, JAX). +Most of the code in `einops` is: + +- [einops.py](https://github.com/arogozhnikov/einops/blob/master/einops/einops.py) + contains the functions it offers as public API (`rearrange`, `reduce`, `repeat`). +- [_backends.py](https://github.com/arogozhnikov/einops/blob/master/einops/_backends.py) + contains the glue code needed to support that many array libraries. + +The amount of code in each of those two files is almost the same (~550 LoC each). +The typical pattern in `einops.py` is: +``` +def some_func(x): + ... + backend = get_backend(x) + shape = backend.shape(x) + result = backend.reduce(x) + ... +``` +With a standard array API, the `_backends.py` glue layer could almost completely disappear, +because the purpose it serves (providing a unified interface to array operations from each +of the supported backends) is already addressed by the array API standard. +Hence the complete `einops` code base could be close to 50% smaller, and easier to maintain or add to. + +```{note} + +Other libraries that have a similar backend system to support many array libraries +include [TensorLy](https://github.com/tensorly/tensorly), the (now discontinued) +multi-backend version of [Keras](https://github.com/keras-team/keras), +[Unumpy](https://github.com/Quansight-Labs/unumpy) and +[EagerPy](https://github.com/jonasrauber/eagerpy). Many end users and +organizations will also have such glue code - it tends to be needed whenever +one tries to support multiple array types in a single API. +``` + + +(use-case-xtensor)= + +### Use case 3: adding a Python API to xtensor + +[xtensor](https://github.com/xtensor-stack/xtensor) is a C++ array library +that is NumPy-inspired and provides lazy arrays. It has Python (and Julia and R) +bindings, however it does not have a Python array API. + +Xtensor aims to follow NumPy closely, however it only implements a subset of functionality +and documents some API differences in +[Notable differences with NumPy](https://xtensor.readthedocs.io/en/latest/numpy-differences.html). + +Note that other libraries document similar differences, see for example +[this page for JAX](https://jax.readthedocs.io/en/latest/jax.numpy.html) and +[this page for TensorFlow](https://www.tensorflow.org/guide/tf_numpy). + +Each time an array library author designs a new API, they have to choose (a) +what subset of NumPy makes sense to implement, and (b) where to deviate +because NumPy's API for a particular function is suboptimal or the semantics +don't fit their execution model. + +This array API standard aims to provide an API that can be readily adopted, +without having to make the above-mentioned choices. + +```{note} + +XND is another array library, written in C, that still needs a Python API. +Array implementations in other languages are often in a similar situation, +and could translate this array API standard 1:1 to their language. +``` + + +(use-case-numba)= + +### Use case 4: make JIT compilation of array computations easier and more robust + +[Numba](https://github.com/numba/numba) is a Just-In-Time (JIT) compiler for +numerical functions in Python; it is NumPy-aware. [PyPy](https://pypy.org) +is an implementation of Python with a JIT at its core; its NumPy support relies +on running NumPy itself through a compatibility layer (`cpyext`), while a +previous attempt to implement NumPy support directly was unsuccessful. + +Other array libraries may have an internal JIT (e.g., TensorFlow, PyTorch, +JAX, MXNet) or work with an external JIT like +[XLA](https://www.tensorflow.org/xla) or [VTA](https://tvm.apache.org/docs/vta/index.html). + +Numba currently has to jump through some hoops to accommodate NumPy's casting rules +and may not attain full compatibility with NumPy in some cases - see, e.g., +[this](https://github.com/numba/numba/issues/4749) or +[this](https://github.com/numba/numba/issues/5907) example issue regarding (array) scalar +return values. + +An [explicit suggestion from a Numba developer](https://twitter.com/esc___/status/1295389487485333505) +for this array API standard was: + +> for JIT compilers (e.g. Numba) it will be important, that the type of the + returned value(s) depends only on the *types* of the input but not on the + *values*. + +A concrete goal for this use case is to have better matching between +JIT-compiled and non-JIT execution. Here is an example from the Numba code +base, the need for which should be avoided in the future: + +``` +def check(x, y): + got = cfunc(x, y) + np.testing.assert_array_almost_equal(got, pyfunc(x, y)) + # Check the power operation conserved the input's dtype + # (this is different from Numpy, whose behaviour depends on + # the *values* of the arguments -- see PyArray_CanCastArrayTo). + self.assertEqual(got.dtype, x.dtype) +``` \ No newline at end of file diff --git a/latest/_sources/verification_test_suite.md.txt b/latest/_sources/verification_test_suite.md.txt new file mode 100644 index 000000000..cbe770e48 --- /dev/null +++ b/latest/_sources/verification_test_suite.md.txt @@ -0,0 +1,62 @@ +# Verification - test suite + +## Measuring conformance + +In addition to the specification documents, a test suite is being developed to +aid library developers check conformance to the spec. **NOTE: The test suite +is still a work in progress.** It can be found at +. + +It is important to note that while the aim of the array API test suite is to +cover as much of the spec as possible, there are necessarily some aspects of +the spec that are not covered by the test suite, typically because they are +impossible to effectively test. Furthermore, if the test suite appears to +diverge in any way from what the spec documents say, this should be considered +a bug in the test suite. The specification is the ground source of truth. + +## Running the tests + +To run the tests, first clone the [test suite +repo](https://github.com/data-apis/array-api-tests), and install the testing +dependencies, + + pip install pytest hypothesis + +or + + conda install pytest hypothesis + +as well as the array libraries that you want to test. To run the tests, you +need to specify the array library that is to be tested. There are two ways to +do this. One way is to set the `ARRAY_API_TESTS_MODULE` environment variable. +For example + + ARRAY_API_TESTS_MODULE=numpy pytest + +Alternatively, edit the `array_api_tests/_array_module.py` file and change the +line + +```py +array_module = None +``` + +to + +```py +import numpy as array_module +``` + +(replacing `numpy` with the array module namespace to be tested). + +In either case, the tests should be run with the `pytest` command. + +Aside from the two testing dependencies (`pytest` and `hypothesis`), the test +suite has no dependencies. In particular, it does not depend on any specific +array libraries such as NumPy. All tests are run using only the array library +that is being tested, comparing results against the behavior as defined in the +spec. The test suite is designed to be standalone so that it can easily be vendored. + +See the +[README](https://github.com/data-apis/array-api-tests/blob/master/README.md) +in the test suite repo for more information about how to run and interpret the +test suite results. diff --git a/latest/_static/basic.css b/latest/_static/basic.css new file mode 100644 index 000000000..ca5600c13 --- /dev/null +++ b/latest/_static/basic.css @@ -0,0 +1 @@ +@charset "utf-8"; div.clearer{clear:both}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}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:.25em;box-sizing:border-box}div.sphinxsidebar #searchbox input[type=submit]{float:left;width:20%;border-left:none;padding:.25em;box-sizing:border-box}img{border:0;max-width:100%}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}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%}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:0}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:.4em}div.genindex-jumpbox{border-top:1px solid #ddd;border-bottom:1px solid #ddd;margin:1em 0 1em 0;padding:.4em}table.modindextable td{padding:2px;border-collapse:collapse}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}a.brackets:before,span.brackets>a:before{content:"["}a.brackets:after,span.brackets>a:after{content:"]"}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}img.align-default,.figure.align-default{display:block;margin-left:auto;margin-right:auto}.align-left{text-align:left}.align-center{text-align:center}.align-default{text-align:center}.align-right{text-align:right}div.sidebar{margin:0 0 .5em 1em;border:1px solid #ddb;padding:7px;background-color:#ffe;width:40%;float:right;clear:right;overflow-x:auto}p.sidebar-title{font-weight:bold}div.admonition,div.topic,pre,div[class|="highlight"]{clear:both}div.topic{border:1px solid #ccc;padding:7px;margin:10px 0 10px 0;overflow-x:auto}p.topic-title{font-size:1.1em;font-weight:bold;margin-top:10px}div.admonition{margin-top:10px;margin-bottom:10px;padding:7px;overflow-x:auto}div.admonition dt{font-weight:bold}p.admonition-title{margin:0 10px 5px 0;font-weight:bold}div.body p.centered{text-align:center;margin-top:25px}div.sidebar>:last-child,div.topic>:last-child,div.admonition>:last-child{margin-bottom:0}table.docutils{margin-top:10px;margin-bottom:10px;border:0;border-collapse:collapse}table.align-center{margin-left:auto;margin-right:auto}table.align-default{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}th>:first-child,td>:first-child{margin-top:0}th>:last-child,td>:last-child{margin-bottom:0}div.figure{margin:.5em;padding:.5em}div.figure p.caption{padding:.3em}div.figure p.caption span.caption-number{font-style:italic}div.figure p.caption span.caption-text{}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}table.hlist{margin:1em 0}table.hlist td{vertical-align:top}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}ol>li:first-child>:first-child,ul>li:first-child>:first-child{margin-top:0}ol ol>li:first-child>:first-child,ol ul>li:first-child>:first-child,ul ol>li:first-child>:first-child,ul ul>li:first-child>:first-child{margin-top:revert}ol>li:last-child>:last-child,ul>li:last-child>:last-child{margin-bottom:0}ol ol>li:last-child>:last-child,ol ul>li:last-child>:last-child,ul ol>li:last-child>:last-child,ul ul>li:last-child>:last-child{margin-bottom:revert}dl.footnote>dt,dl.citation>dt{float:left;margin-right:.5em}dl.footnote>dd,dl.citation>dd{margin-bottom:0}dl.footnote>dd:after,dl.citation>dd:after{content:"";clear:both}dl.field-list{display:grid;grid-template-columns:fit-content(30%) auto}dl.field-list>dt{font-weight:bold;word-break:break-word;padding-left:.5em;padding-right:5px}dl.field-list>dt:after{content:":"}dl.field-list>dd{padding-left:.5em;margin-top:0;margin-left:0;margin-bottom:0}dl{margin-bottom:15px}dd>:first-child{margin-top:0}dd ul,dd table{margin-bottom:10px}dd{margin-top:3px;margin-bottom:10px;margin-left:30px}dl>dd:last-child,dl>dd:last-child>:last-child{margin-bottom:0}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}.classifier:before{font-style:normal;margin:.5em;content:":"}abbr,acronym{border-bottom:dotted 1px;cursor:help}pre{overflow:auto;overflow-y:hidden}span.pre{-moz-hyphens:none;-ms-hyphens:none;-webkit-hyphens:none;hyphens:none}div[class^="highlight-"]{margin:1em 0}td.linenos pre{border:0;background-color:transparent;color:#aaa}table.highlighttable{display:block}table.highlighttable tbody{display:block}table.highlighttable tr{display:flex}table.highlighttable td{margin:0;padding:0}table.highlighttable td.linenos{padding-right:.5em}table.highlighttable td.code{flex:1;overflow:hidden}.highlight .hll{display:block}div.highlight pre,table.highlighttable pre{margin:0}div.code-block-caption + div{margin-top:0}div.code-block-caption{margin-top:1em;padding:2px 5px;font-size:small}div.code-block-caption code{background-color:transparent}table.highlighttable td.linenos,div.doctest>div.highlight span.gp{user-select:none}div.code-block-caption span.caption-number{padding:.1em .3em;font-style:italic}div.code-block-caption span.caption-text{}div.literal-block-wrapper{margin:1em 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}img.math{vertical-align:middle}div.body div.math p{text-align:center}span.eqno{float:right}span.eqno a.headerlink{position:absolute;z-index:1}div.math:hover a.headerlink{visibility:visible}@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/latest/_static/clipboard.min.js b/latest/_static/clipboard.min.js new file mode 100644 index 000000000..02c549e35 --- /dev/null +++ b/latest/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n + + + + diff --git a/latest/_static/copybutton.css b/latest/_static/copybutton.css new file mode 100644 index 000000000..85df518cb --- /dev/null +++ b/latest/_static/copybutton.css @@ -0,0 +1 @@ +@charset "utf-8"; a.copybtn{position:absolute;top:.2em;right:.2em;width:1em;height:1em;opacity:.3;transition:opacity .5s;border:0;user-select:none}div.highlight{position:relative}a.copybtn>img{vertical-align:top;margin:0;top:0;left:0;position:absolute}.highlight:hover .copybtn{opacity:1}.o-tooltip--left{position:relative}.o-tooltip--left:after{opacity:0;visibility:hidden;position:absolute;content:attr(data-tooltip);padding:2px;top:0;left:-.2em;background:grey;font-size:1rem;color:white;white-space:nowrap;z-index:2;border-radius:2px;transform:translateX(-102%) translateY(0);transition:opacity .2s cubic-bezier(0.64,0.09,0.08,1),transform .2s cubic-bezier(0.64,0.09,0.08,1)}.o-tooltip--left:hover:after{display:block;opacity:1;visibility:visible;transform:translateX(-100%) translateY(0);transition:opacity .2s cubic-bezier(0.64,0.09,0.08,1),transform .2s cubic-bezier(0.64,0.09,0.08,1);transition-delay:.5s} \ No newline at end of file diff --git a/latest/_static/copybutton.js b/latest/_static/copybutton.js new file mode 100644 index 000000000..65a59167a --- /dev/null +++ b/latest/_static/copybutton.js @@ -0,0 +1,153 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for two seconds, then changes it back +const temporarilyChangeTooltip = (el, newText) => { + const oldText = el.getAttribute('data-tooltip') + el.setAttribute('data-tooltip', newText) + setTimeout(() => el.setAttribute('data-tooltip', oldText), 2000) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const codeCells = document.querySelectorAll('div.highlight pre') + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + const pre_bg = getComputedStyle(codeCell).backgroundColor; + + const clipboardButton = id => + ` + ${messages[locale]['copy_to_clipboard']} + ` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true) { + + var regexp; + var match; + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match) { + promptFound = true + if (removePrompts) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + } else { + if (!onlyCopyPromptLines) { + outputLines.push(line) + } + } + } + + // If no lines with the prompt were found then just use original lines + if (promptFound) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + return formatCopyText(target.innerText, '', false, true, true) +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy_success']) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/latest/_static/copybutton_funcs.js b/latest/_static/copybutton_funcs.js new file mode 100644 index 000000000..57caa5585 --- /dev/null +++ b/latest/_static/copybutton_funcs.js @@ -0,0 +1,47 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true) { + + var regexp; + var match; + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match) { + promptFound = true + if (removePrompts) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + } else { + if (!onlyCopyPromptLines) { + outputLines.push(line) + } + } + } + + // If no lines with the prompt were found then just use original lines + if (promptFound) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/latest/_static/doctools.js b/latest/_static/doctools.js new file mode 100644 index 000000000..daccd209d --- /dev/null +++ b/latest/_static/doctools.js @@ -0,0 +1,315 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2020 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 rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + 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); + 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() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + 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); + $('') + .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).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { + 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/latest/_static/documentation_options.js b/latest/_static/documentation_options.js new file mode 100644 index 000000000..910469029 --- /dev/null +++ b/latest/_static/documentation_options.js @@ -0,0 +1,12 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '2021.01-DRAFT', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false +}; \ No newline at end of file diff --git a/latest/_static/file.png b/latest/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/latest/_static/file.png differ diff --git a/latest/_static/fonts/font-awesome.css b/latest/_static/fonts/font-awesome.css new file mode 100644 index 000000000..e7dcefb82 --- /dev/null +++ b/latest/_static/fonts/font-awesome.css @@ -0,0 +1 @@ +@charset "utf-8";/*!* Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license(Font:SIL OFL 1.1,CSS:MIT License) */@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(specimen/FontAwesome.woff2) format("woff2"),url(specimen/FontAwesome.woff) format("woff"),url(specimen/FontAwesome.ttf) format("truetype")}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0,mirror=1)";-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2,mirror=1)";-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} \ No newline at end of file diff --git a/latest/_static/fonts/material-icons.css b/latest/_static/fonts/material-icons.css new file mode 100644 index 000000000..76de20cb1 --- /dev/null +++ b/latest/_static/fonts/material-icons.css @@ -0,0 +1 @@ +@charset "utf-8";/*!* Licensed under the Apache License,Version 2.0(the "License");you may not * use this file except in compliance with the License. You may obtain a copy * of the License at:* * http://www.apache.org/licenses/LICENSE-2.0 * * UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING,SOFTWARE * DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,EITHER EXPRESS OR IMPLIED. * SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND * LIMITATIONS UNDER THE LICENSE. */@font-face{font-display:swap;font-family:"Material Icons";font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url(specimen/MaterialIcons-Regular.woff2) format("woff2"),url(specimen/MaterialIcons-Regular.woff) format("woff"),url(specimen/MaterialIcons-Regular.ttf) format("truetype")} \ No newline at end of file diff --git a/latest/_static/fonts/specimen/FontAwesome.ttf b/latest/_static/fonts/specimen/FontAwesome.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/latest/_static/fonts/specimen/FontAwesome.ttf differ diff --git a/latest/_static/fonts/specimen/FontAwesome.woff b/latest/_static/fonts/specimen/FontAwesome.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/latest/_static/fonts/specimen/FontAwesome.woff differ diff --git a/latest/_static/fonts/specimen/FontAwesome.woff2 b/latest/_static/fonts/specimen/FontAwesome.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/latest/_static/fonts/specimen/FontAwesome.woff2 differ diff --git a/latest/_static/fonts/specimen/MaterialIcons-Regular.ttf b/latest/_static/fonts/specimen/MaterialIcons-Regular.ttf new file mode 100644 index 000000000..7015564ad Binary files /dev/null and b/latest/_static/fonts/specimen/MaterialIcons-Regular.ttf differ diff --git a/latest/_static/fonts/specimen/MaterialIcons-Regular.woff b/latest/_static/fonts/specimen/MaterialIcons-Regular.woff new file mode 100644 index 000000000..b648a3eea Binary files /dev/null and b/latest/_static/fonts/specimen/MaterialIcons-Regular.woff differ diff --git a/latest/_static/fonts/specimen/MaterialIcons-Regular.woff2 b/latest/_static/fonts/specimen/MaterialIcons-Regular.woff2 new file mode 100644 index 000000000..9fa211252 Binary files /dev/null and b/latest/_static/fonts/specimen/MaterialIcons-Regular.woff2 differ diff --git a/latest/_static/images/DLPack_diagram.png b/latest/_static/images/DLPack_diagram.png new file mode 100644 index 000000000..a84598532 Binary files /dev/null and b/latest/_static/images/DLPack_diagram.png differ diff --git a/latest/_static/images/dependency_assumption_diagram.png b/latest/_static/images/dependency_assumption_diagram.png new file mode 100644 index 000000000..f77f11f45 Binary files /dev/null and b/latest/_static/images/dependency_assumption_diagram.png differ diff --git a/latest/_static/images/dtype_promotion_complex.png b/latest/_static/images/dtype_promotion_complex.png new file mode 100644 index 000000000..3503b07f5 Binary files /dev/null and b/latest/_static/images/dtype_promotion_complex.png differ diff --git a/latest/_static/images/dtype_promotion_lattice.png b/latest/_static/images/dtype_promotion_lattice.png new file mode 100644 index 000000000..669d30476 Binary files /dev/null and b/latest/_static/images/dtype_promotion_lattice.png differ diff --git a/latest/_static/images/favicon.png b/latest/_static/images/favicon.png new file mode 100644 index 000000000..76d17f57a Binary files /dev/null and b/latest/_static/images/favicon.png differ diff --git a/latest/_static/images/icons/bitbucket.1b09e088.svg b/latest/_static/images/icons/bitbucket.1b09e088.svg new file mode 100644 index 000000000..cf58c14fb --- /dev/null +++ b/latest/_static/images/icons/bitbucket.1b09e088.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/latest/_static/images/icons/bitbucket.svg b/latest/_static/images/icons/bitbucket.svg new file mode 100644 index 000000000..cf58c14fb --- /dev/null +++ b/latest/_static/images/icons/bitbucket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/latest/_static/images/icons/github.f0b8504a.svg b/latest/_static/images/icons/github.f0b8504a.svg new file mode 100644 index 000000000..3d13b1975 --- /dev/null +++ b/latest/_static/images/icons/github.f0b8504a.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/latest/_static/images/icons/github.svg b/latest/_static/images/icons/github.svg new file mode 100644 index 000000000..3d13b1975 --- /dev/null +++ b/latest/_static/images/icons/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/latest/_static/images/icons/gitlab.6dd19c00.svg b/latest/_static/images/icons/gitlab.6dd19c00.svg new file mode 100644 index 000000000..1d9fffa74 --- /dev/null +++ b/latest/_static/images/icons/gitlab.6dd19c00.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/latest/_static/images/icons/gitlab.svg b/latest/_static/images/icons/gitlab.svg new file mode 100644 index 000000000..1d9fffa74 --- /dev/null +++ b/latest/_static/images/icons/gitlab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/latest/_static/images/scope_of_array_API.png b/latest/_static/images/scope_of_array_API.png new file mode 100644 index 000000000..55253288c Binary files /dev/null and b/latest/_static/images/scope_of_array_API.png differ diff --git a/latest/_static/javascripts/application.js b/latest/_static/javascripts/application.js new file mode 100644 index 000000000..7c724d2e4 --- /dev/null +++ b/latest/_static/javascripts/application.js @@ -0,0 +1,2540 @@ +! function(e, t) { + for (var n in t) e[n] = t[n] +}(window, function(n) { + var r = {}; + + function i(e) { + if (r[e]) return r[e].exports; + var t = r[e] = { + i: e, + l: !1, + exports: {} + }; + return n[e].call(t.exports, t, t.exports, i), t.l = !0, t.exports + } + return i.m = n, i.c = r, i.d = function(e, t, n) { + i.o(e, t) || Object.defineProperty(e, t, { + enumerable: !0, + get: n + }) + }, i.r = function(e) { + "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { + value: "Module" + }), Object.defineProperty(e, "__esModule", { + value: !0 + }) + }, i.t = function(t, e) { + if (1 & e && (t = i(t)), 8 & e) return t; + if (4 & e && "object" == typeof t && t && t.__esModule) return t; + var n = Object.create(null); + if (i.r(n), Object.defineProperty(n, "default", { + enumerable: !0, + value: t + }), 2 & e && "string" != typeof t) + for (var r in t) i.d(n, r, function(e) { + return t[e] + }.bind(null, r)); + return n + }, i.n = function(e) { + var t = e && e.__esModule ? function() { + return e.default + } : function() { + return e + }; + return i.d(t, "a", t), t + }, i.o = function(e, t) { + return Object.prototype.hasOwnProperty.call(e, t) + }, i.p = "", i(i.s = 13) +}([function(e, t, n) { + "use strict"; + var r = { + Listener: function() { + function e(e, t, n) { + var r = this; + this.els_ = Array.prototype.slice.call("string" == typeof e ? document.querySelectorAll(e) : [].concat(e)), this.handler_ = "function" == typeof n ? { + update: n + } : n, this.events_ = [].concat(t), this.update_ = function(e) { + return r.handler_.update(e) + } + } + var t = e.prototype; + return t.listen = function() { + var n = this; + this.els_.forEach(function(t) { + n.events_.forEach(function(e) { + t.addEventListener(e, n.update_, !1) + }) + }), "function" == typeof this.handler_.setup && this.handler_.setup() + }, t.unlisten = function() { + var n = this; + this.els_.forEach(function(t) { + n.events_.forEach(function(e) { + t.removeEventListener(e, n.update_) + }) + }), "function" == typeof this.handler_.reset && this.handler_.reset() + }, e + }(), + MatchMedia: function(e, t) { + this.handler_ = function(e) { + e.matches ? t.listen() : t.unlisten() + }; + var n = window.matchMedia(e); + n.addListener(this.handler_), this.handler_(n) + } + }, + i = { + Shadow: function() { + function e(e, t) { + var n = "string" == typeof e ? document.querySelector(e) : e; + if (!(n instanceof HTMLElement && n.parentNode instanceof HTMLElement)) throw new ReferenceError; + if (this.el_ = n.parentNode, !((n = "string" == typeof t ? document.querySelector(t) : t) instanceof HTMLElement)) throw new ReferenceError; + this.header_ = n, this.height_ = 0, this.active_ = !1 + } + var t = e.prototype; + return t.setup = function() { + for (var e = this.el_; e = e.previousElementSibling;) { + if (!(e instanceof HTMLElement)) throw new ReferenceError; + this.height_ += e.offsetHeight + } + this.update() + }, t.update = function(e) { + if (!e || "resize" !== e.type && "orientationchange" !== e.type) { + var t = window.pageYOffset >= this.height_; + t !== this.active_ && (this.header_.dataset.mdState = (this.active_ = t) ? "shadow" : "") + } else this.height_ = 0, this.setup() + }, t.reset = function() { + this.header_.dataset.mdState = "", this.height_ = 0, this.active_ = !1 + }, e + }(), + Title: function() { + function e(e, t) { + var n = "string" == typeof e ? document.querySelector(e) : e; + if (!(n instanceof HTMLElement)) throw new ReferenceError; + if (this.el_ = n, !((n = "string" == typeof t ? document.querySelector(t) : t) instanceof HTMLHeadingElement)) throw new ReferenceError; + this.header_ = n, this.active_ = !1 + } + var t = e.prototype; + return t.setup = function() { + var t = this; + Array.prototype.forEach.call(this.el_.children, function(e) { + e.style.width = t.el_.offsetWidth - 20 + "px" + }) + }, t.update = function(e) { + var t = this, + n = window.pageYOffset >= this.header_.offsetTop; + n !== this.active_ && (this.el_.dataset.mdState = (this.active_ = n) ? "active" : ""), "resize" !== e.type && "orientationchange" !== e.type || Array.prototype.forEach.call(this.el_.children, function(e) { + e.style.width = t.el_.offsetWidth - 20 + "px" + }) + }, t.reset = function() { + this.el_.dataset.mdState = "", this.el_.style.width = "", this.active_ = !1 + }, e + }() + }, + o = { + Blur: function() { + function e(e) { + this.els_ = "string" == typeof e ? document.querySelectorAll(e) : e, this.index_ = 0, this.offset_ = window.pageYOffset, this.dir_ = !1, this.anchors_ = [].reduce.call(this.els_, function(e, t) { + var n = decodeURIComponent(t.hash); + return e.concat(document.getElementById(n.substring(1)) || []) + }, []) + } + var t = e.prototype; + return t.setup = function() { + this.update() + }, t.update = function() { + var e = window.pageYOffset, + t = this.offset_ - e < 0; + if (this.dir_ !== t && (this.index_ = this.index_ = t ? 0 : this.els_.length - 1), 0 !== this.anchors_.length) { + if (this.offset_ <= e) + for (var n = this.index_ + 1; n < this.els_.length && this.anchors_[n].offsetTop - 80 <= e; n++) 0 < n && (this.els_[n - 1].dataset.mdState = "blur"), this.index_ = n; + else + for (var r = this.index_; 0 <= r; r--) { + if (!(this.anchors_[r].offsetTop - 80 > e)) { + this.index_ = r; + break + } + 0 < r && (this.els_[r - 1].dataset.mdState = "") + } + this.offset_ = e, this.dir_ = t + } + }, t.reset = function() { + Array.prototype.forEach.call(this.els_, function(e) { + e.dataset.mdState = "" + }), this.index_ = 0, this.offset_ = window.pageYOffset + }, e + }(), + Collapse: function() { + function e(e) { + var t = "string" == typeof e ? document.querySelector(e) : e; + if (!(t instanceof HTMLElement)) throw new ReferenceError; + this.el_ = t + } + var t = e.prototype; + return t.setup = function() { + var e = this.el_.getBoundingClientRect().height; + this.el_.style.display = e ? "block" : "none", this.el_.style.overflow = e ? "visible" : "hidden" + }, t.update = function() { + var e = this, + t = this.el_.getBoundingClientRect().height; + this.el_.style.display = "block", this.el_.style.overflow = ""; + var r = this.el_.previousElementSibling.previousElementSibling.checked; + if (r) this.el_.style.maxHeight = t + "px", requestAnimationFrame(function() { + e.el_.setAttribute("data-md-state", "animate"), e.el_.style.maxHeight = "0px" + }); + else { + this.el_.setAttribute("data-md-state", "expand"), this.el_.style.maxHeight = ""; + var n = this.el_.getBoundingClientRect().height; + this.el_.removeAttribute("data-md-state"), this.el_.style.maxHeight = "0px", requestAnimationFrame(function() { + e.el_.setAttribute("data-md-state", "animate"), e.el_.style.maxHeight = n + "px" + }) + } + this.el_.addEventListener("transitionend", function e(t) { + var n = t.target; + if (!(n instanceof HTMLElement)) throw new ReferenceError; + n.removeAttribute("data-md-state"), n.style.maxHeight = "", n.style.display = r ? "none" : "block", n.style.overflow = r ? "hidden" : "visible", n.removeEventListener("transitionend", e) + }, !1) + }, t.reset = function() { + this.el_.dataset.mdState = "", this.el_.style.maxHeight = "", this.el_.style.display = "", this.el_.style.overflow = "" + }, e + }(), + Scrolling: function() { + function e(e) { + var t = "string" == typeof e ? document.querySelector(e) : e; + if (!(t instanceof HTMLElement)) throw new ReferenceError; + this.el_ = t + } + var t = e.prototype; + return t.setup = function() { + this.el_.children[this.el_.children.length - 1].style.webkitOverflowScrolling = "touch"; + var e = this.el_.querySelectorAll("[data-md-toggle]"); + Array.prototype.forEach.call(e, function(e) { + if (!(e instanceof HTMLInputElement)) throw new ReferenceError; + if (e.checked) { + var t = e.nextElementSibling; + if (!(t instanceof HTMLElement)) throw new ReferenceError; + for (; + "NAV" !== t.tagName && t.nextElementSibling;) t = t.nextElementSibling; + if (!(e.parentNode instanceof HTMLElement && e.parentNode.parentNode instanceof HTMLElement)) throw new ReferenceError; + var n = e.parentNode.parentNode, + r = t.children[t.children.length - 1]; + n.style.webkitOverflowScrolling = "", r.style.webkitOverflowScrolling = "touch" + } + }) + }, t.update = function(e) { + var t = e.target; + if (!(t instanceof HTMLElement)) throw new ReferenceError; + var n = t.nextElementSibling; + if (!(n instanceof HTMLElement)) throw new ReferenceError; + for (; + "NAV" !== n.tagName && n.nextElementSibling;) n = n.nextElementSibling; + if (!(t.parentNode instanceof HTMLElement && t.parentNode.parentNode instanceof HTMLElement)) throw new ReferenceError; + var r = t.parentNode.parentNode, + i = n.children[n.children.length - 1]; + if (r.style.webkitOverflowScrolling = "", i.style.webkitOverflowScrolling = "", !t.checked) { + n.addEventListener("transitionend", function e() { + n instanceof HTMLElement && (r.style.webkitOverflowScrolling = "touch", n.removeEventListener("transitionend", e)) + }, !1) + } + if (t.checked) { + n.addEventListener("transitionend", function e() { + n instanceof HTMLElement && (i.style.webkitOverflowScrolling = "touch", n.removeEventListener("transitionend", e)) + }, !1) + } + }, t.reset = function() { + this.el_.children[1].style.webkitOverflowScrolling = ""; + var e = this.el_.querySelectorAll("[data-md-toggle]"); + Array.prototype.forEach.call(e, function(e) { + if (!(e instanceof HTMLInputElement)) throw new ReferenceError; + if (e.checked) { + var t = e.nextElementSibling; + if (!(t instanceof HTMLElement)) throw new ReferenceError; + for (; + "NAV" !== t.tagName && t.nextElementSibling;) t = t.nextElementSibling; + if (!(e.parentNode instanceof HTMLElement && e.parentNode.parentNode instanceof HTMLElement)) throw new ReferenceError; + var n = e.parentNode.parentNode, + r = t.children[t.children.length - 1]; + n.style.webkitOverflowScrolling = "", r.style.webkitOverflowScrolling = "" + } + }) + }, e + }() + }, + a = { + Lock: function() { + function e(e) { + var t = "string" == typeof e ? document.querySelector(e) : e; + if (!(t instanceof HTMLInputElement)) throw new ReferenceError; + if (this.el_ = t, !document.body) throw new ReferenceError; + this.lock_ = document.body + } + var t = e.prototype; + return t.setup = function() { + this.update() + }, t.update = function() { + var e = this; + this.el_.checked ? (this.offset_ = window.pageYOffset, setTimeout(function() { + window.scrollTo(0, 0), e.el_.checked && (e.lock_.dataset.mdState = "lock") + }, 400)) : (this.lock_.dataset.mdState = "", setTimeout(function() { + void 0 !== e.offset_ && window.scrollTo(0, e.offset_) + }, 100)) + }, t.reset = function() { + "lock" === this.lock_.dataset.mdState && window.scrollTo(0, this.offset_), this.lock_.dataset.mdState = "" + }, e + }(), + Result: n(9).a + }, + s = { + Position: function() { + function e(e, t) { + var n = "string" == typeof e ? document.querySelector(e) : e; + if (!(n instanceof HTMLElement && n.parentNode instanceof HTMLElement)) throw new ReferenceError; + if (this.el_ = n, this.parent_ = n.parentNode, !((n = "string" == typeof t ? document.querySelector(t) : t) instanceof HTMLElement)) throw new ReferenceError; + this.header_ = n, this.height_ = 0, this.pad_ = "fixed" === window.getComputedStyle(this.header_).position + } + var t = e.prototype; + return t.setup = function() { + var e = Array.prototype.reduce.call(this.parent_.children, function(e, t) { + return Math.max(e, t.offsetTop) + }, 0); + this.offset_ = e - (this.pad_ ? this.header_.offsetHeight : 0), this.update() + }, t.update = function(e) { + var t = window.pageYOffset, + n = window.innerHeight; + e && "resize" === e.type && this.setup(); + var r = this.pad_ ? this.header_.offsetHeight : 0, + i = this.parent_.offsetTop + this.parent_.offsetHeight, + o = n - r - Math.max(0, this.offset_ - t) - Math.max(0, t + n - i); + o !== this.height_ && (this.el_.style.height = (this.height_ = o) + "px"), t >= this.offset_ ? "lock" !== this.el_.dataset.mdState && (this.el_.dataset.mdState = "lock") : "lock" === this.el_.dataset.mdState && (this.el_.dataset.mdState = "") + }, t.reset = function() { + this.el_.dataset.mdState = "", this.el_.style.height = "", this.height_ = 0 + }, e + }() + }, + c = n(6), + l = n.n(c); + var u = { + Adapter: { + GitHub: function(o) { + var e, t; + + function n(e) { + var t; + t = o.call(this, e) || this; + var n = /^.+github\.com\/([^/]+)\/?([^/]+)?.*$/.exec(t.base_); + if (n && 3 === n.length) { + var r = n[1], + i = n[2]; + t.base_ = "https://api.github.com/users/" + r + "/repos", t.name_ = i + } + return t + } + return t = o, (e = n).prototype = Object.create(t.prototype), (e.prototype.constructor = e).__proto__ = t, n.prototype.fetch_ = function() { + var i = this; + return function n(r) { + return void 0 === r && (r = 0), fetch(i.base_ + "?per_page=30&page=" + r).then(function(e) { + return e.json() + }).then(function(e) { + if (!(e instanceof Array)) throw new TypeError; + if (i.name_) { + var t = e.find(function(e) { + return e.name === i.name_ + }); + return t || 30 !== e.length ? t ? [i.format_(t.stargazers_count) + " Stars", i.format_(t.forks_count) + " Forks"] : [] : n(r + 1) + } + return [e.length + " Repositories"] + }) + }() + }, n + }(function() { + function e(e) { + var t = "string" == typeof e ? document.querySelector(e) : e; + if (!(t instanceof HTMLAnchorElement)) throw new ReferenceError; + this.el_ = t, this.base_ = this.el_.href, this.salt_ = this.hash_(this.base_) + } + var t = e.prototype; + return t.fetch = function() { + var n = this; + return new Promise(function(t) { + var e = l.a.getJSON(n.salt_ + ".cache-source"); + void 0 !== e ? t(e) : n.fetch_().then(function(e) { + l.a.set(n.salt_ + ".cache-source", e, { + expires: 1 / 96 + }), t(e) + }) + }) + }, t.fetch_ = function() { + throw new Error("fetch_(): Not implemented") + }, t.format_ = function(e) { + return 1e4 < e ? (e / 1e3).toFixed(0) + "k" : 1e3 < e ? (e / 1e3).toFixed(1) + "k" : "" + e + }, t.hash_ = function(e) { + var t = 0; + if (0 === e.length) return t; + for (var n = 0, r = e.length; n < r; n++) t = (t << 5) - t + e.charCodeAt(n), t |= 0; + return t + }, e + }()) + }, + Repository: n(10).a + }, + f = { + Toggle: function() { + function e(e) { + var t = "string" == typeof e ? document.querySelector(e) : e; + if (!(t instanceof Node)) throw new ReferenceError; + this.el_ = t; + var n = document.querySelector("[data-md-component=header]"); + this.height_ = n.offsetHeight, this.active_ = !1 + } + var t = e.prototype; + return t.update = function() { + var e = window.pageYOffset >= this.el_.children[0].offsetTop + (5 - this.height_); + e !== this.active_ && (this.el_.dataset.mdState = (this.active_ = e) ? "hidden" : "") + }, t.reset = function() { + this.el_.dataset.mdState = "", this.active_ = !1 + }, e + }() + }; + t.a = { + Event: r, + Header: i, + Nav: o, + Search: a, + Sidebar: s, + Source: u, + Tabs: f + } +}, function(t, e, n) { + (function(e) { + t.exports = e.lunr = n(24) + }).call(this, n(4)) +}, function(e, f, d) { + "use strict"; + (function(t) { + var e = d(8), + n = setTimeout; + + function r() {} + + function o(e) { + if (!(this instanceof o)) throw new TypeError("Promises must be constructed via new"); + if ("function" != typeof e) throw new TypeError("not a function"); + this._state = 0, this._handled = !1, this._value = void 0, this._deferreds = [], u(e, this) + } + + function i(n, r) { + for (; 3 === n._state;) n = n._value; + 0 !== n._state ? (n._handled = !0, o._immediateFn(function() { + var e = 1 === n._state ? r.onFulfilled : r.onRejected; + if (null !== e) { + var t; + try { + t = e(n._value) + } catch (e) { + return void s(r.promise, e) + } + a(r.promise, t) + } else(1 === n._state ? a : s)(r.promise, n._value) + })) : n._deferreds.push(r) + } + + function a(t, e) { + try { + if (e === t) throw new TypeError("A promise cannot be resolved with itself."); + if (e && ("object" == typeof e || "function" == typeof e)) { + var n = e.then; + if (e instanceof o) return t._state = 3, t._value = e, void c(t); + if ("function" == typeof n) return void u((r = n, i = e, function() { + r.apply(i, arguments) + }), t) + } + t._state = 1, t._value = e, c(t) + } catch (e) { + s(t, e) + } + var r, i + } + + function s(e, t) { + e._state = 2, e._value = t, c(e) + } + + function c(e) { + 2 === e._state && 0 === e._deferreds.length && o._immediateFn(function() { + e._handled || o._unhandledRejectionFn(e._value) + }); + for (var t = 0, n = e._deferreds.length; t < n; t++) i(e, e._deferreds[t]); + e._deferreds = null + } + + function l(e, t, n) { + this.onFulfilled = "function" == typeof e ? e : null, this.onRejected = "function" == typeof t ? t : null, this.promise = n + } + + function u(e, t) { + var n = !1; + try { + e(function(e) { + n || (n = !0, a(t, e)) + }, function(e) { + n || (n = !0, s(t, e)) + }) + } catch (e) { + if (n) return; + n = !0, s(t, e) + } + } + o.prototype.catch = function(e) { + return this.then(null, e) + }, o.prototype.then = function(e, t) { + var n = new this.constructor(r); + return i(this, new l(e, t, n)), n + }, o.prototype.finally = e.a, o.all = function(t) { + return new o(function(r, i) { + if (!t || void 0 === t.length) throw new TypeError("Promise.all accepts an array"); + var o = Array.prototype.slice.call(t); + if (0 === o.length) return r([]); + var a = o.length; + + function s(t, e) { + try { + if (e && ("object" == typeof e || "function" == typeof e)) { + var n = e.then; + if ("function" == typeof n) return void n.call(e, function(e) { + s(t, e) + }, i) + } + o[t] = e, 0 == --a && r(o) + } catch (e) { + i(e) + } + } + for (var e = 0; e < o.length; e++) s(e, o[e]) + }) + }, o.resolve = function(t) { + return t && "object" == typeof t && t.constructor === o ? t : new o(function(e) { + e(t) + }) + }, o.reject = function(n) { + return new o(function(e, t) { + t(n) + }) + }, o.race = function(i) { + return new o(function(e, t) { + for (var n = 0, r = i.length; n < r; n++) i[n].then(e, t) + }) + }, o._immediateFn = "function" == typeof t && function(e) { + t(e) + } || function(e) { + n(e, 0) + }, o._unhandledRejectionFn = function(e) { + "undefined" != typeof console && console && console.warn("Possible Unhandled Promise Rejection:", e) + }, f.a = o + }).call(this, d(21).setImmediate) +}, function(e, t, n) { + "use strict"; + + function r(e, t) { + var n = document.createElement(e); + t && Array.prototype.forEach.call(Object.keys(t), function(e) { + n.setAttribute(e, t[e]) + }); + for (var r = arguments.length, i = new Array(2 < r ? r - 2 : 0), o = 2; o < r; o++) i[o - 2] = arguments[o]; + return function t(e) { + Array.prototype.forEach.call(e, function(e) { + "string" == typeof e || "number" == typeof e ? n.textContent += e : Array.isArray(e) ? t(e) : void 0 !== e.__html ? n.innerHTML += e.__html : e instanceof Node && n.appendChild(e) + }) + }(i), n + } + n.r(t), n.d(t, "createElement", function() { + return r + }) +}, function(e, t) { + var n; + n = function() { + return this + }(); + try { + n = n || new Function("return this")() + } catch (e) { + "object" == typeof window && (n = window) + } + e.exports = n +}, function(e, t, n) { + var r; + r = function() { + return function(n) { + var r = {}; + + function i(e) { + if (r[e]) return r[e].exports; + var t = r[e] = { + i: e, + l: !1, + exports: {} + }; + return n[e].call(t.exports, t, t.exports, i), t.l = !0, t.exports + } + return i.m = n, i.c = r, i.d = function(e, t, n) { + i.o(e, t) || Object.defineProperty(e, t, { + enumerable: !0, + get: n + }) + }, i.r = function(e) { + "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { + value: "Module" + }), Object.defineProperty(e, "__esModule", { + value: !0 + }) + }, i.t = function(t, e) { + if (1 & e && (t = i(t)), 8 & e) return t; + if (4 & e && "object" == typeof t && t && t.__esModule) return t; + var n = Object.create(null); + if (i.r(n), Object.defineProperty(n, "default", { + enumerable: !0, + value: t + }), 2 & e && "string" != typeof t) + for (var r in t) i.d(n, r, function(e) { + return t[e] + }.bind(null, r)); + return n + }, i.n = function(e) { + var t = e && e.__esModule ? function() { + return e.default + } : function() { + return e + }; + return i.d(t, "a", t), t + }, i.o = function(e, t) { + return Object.prototype.hasOwnProperty.call(e, t) + }, i.p = "", i(i.s = 0) + }([function(e, t, n) { + "use strict"; + var i = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e + }, + o = function() { + function r(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) + } + } + return function(e, t, n) { + return t && r(e.prototype, t), n && r(e, n), e + } + }(), + a = r(n(1)), + s = r(n(3)), + c = r(n(4)); + + function r(e) { + return e && e.__esModule ? e : { + default: e + } + } + var l = function(e) { + function r(e, t) { + ! function(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, r); + var n = function(e, t) { + if (!e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + return !t || "object" != typeof t && "function" != typeof t ? e : t + }(this, (r.__proto__ || Object.getPrototypeOf(r)).call(this)); + return n.resolveOptions(t), n.listenClick(e), n + } + return function(e, t) { + if ("function" != typeof t && null !== t) throw new TypeError("Super expression must either be null or a function, not " + typeof t); + e.prototype = Object.create(t && t.prototype, { + constructor: { + value: e, + enumerable: !1, + writable: !0, + configurable: !0 + } + }), t && (Object.setPrototypeOf ? Object.setPrototypeOf(e, t) : e.__proto__ = t) + }(r, s.default), o(r, [{ + key: "resolveOptions", + value: function() { + var e = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; + this.action = "function" == typeof e.action ? e.action : this.defaultAction, this.target = "function" == typeof e.target ? e.target : this.defaultTarget, this.text = "function" == typeof e.text ? e.text : this.defaultText, this.container = "object" === i(e.container) ? e.container : document.body + } + }, { + key: "listenClick", + value: function(e) { + var t = this; + this.listener = (0, c.default)(e, "click", function(e) { + return t.onClick(e) + }) + } + }, { + key: "onClick", + value: function(e) { + var t = e.delegateTarget || e.currentTarget; + this.clipboardAction && (this.clipboardAction = null), this.clipboardAction = new a.default({ + action: this.action(t), + target: this.target(t), + text: this.text(t), + container: this.container, + trigger: t, + emitter: this + }) + } + }, { + key: "defaultAction", + value: function(e) { + return u("action", e) + } + }, { + key: "defaultTarget", + value: function(e) { + var t = u("target", e); + if (t) return document.querySelector(t) + } + }, { + key: "defaultText", + value: function(e) { + return u("text", e) + } + }, { + key: "destroy", + value: function() { + this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), this.clipboardAction = null) + } + }], [{ + key: "isSupported", + value: function() { + var e = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ["copy", "cut"], + t = "string" == typeof e ? [e] : e, + n = !!document.queryCommandSupported; + return t.forEach(function(e) { + n = n && !!document.queryCommandSupported(e) + }), n + } + }]), r + }(); + + function u(e, t) { + var n = "data-clipboard-" + e; + if (t.hasAttribute(n)) return t.getAttribute(n) + } + e.exports = l + }, function(e, t, n) { + "use strict"; + var r, i = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) { + return typeof e + } : function(e) { + return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e + }, + o = function() { + function r(e, t) { + for (var n = 0; n < t.length; n++) { + var r = t[n]; + r.enumerable = r.enumerable || !1, r.configurable = !0, "value" in r && (r.writable = !0), Object.defineProperty(e, r.key, r) + } + } + return function(e, t, n) { + return t && r(e.prototype, t), n && r(e, n), e + } + }(), + a = n(2), + s = (r = a) && r.__esModule ? r : { + default: r + }; + var c = function() { + function t(e) { + ! function(e, t) { + if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function") + }(this, t), this.resolveOptions(e), this.initSelection() + } + return o(t, [{ + key: "resolveOptions", + value: function() { + var e = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; + this.action = e.action, this.container = e.container, this.emitter = e.emitter, this.target = e.target, this.text = e.text, this.trigger = e.trigger, this.selectedText = "" + } + }, { + key: "initSelection", + value: function() { + this.text ? this.selectFake() : this.target && this.selectTarget() + } + }, { + key: "selectFake", + value: function() { + var e = this, + t = "rtl" == document.documentElement.getAttribute("dir"); + this.removeFake(), this.fakeHandlerCallback = function() { + return e.removeFake() + }, this.fakeHandler = this.container.addEventListener("click", this.fakeHandlerCallback) || !0, this.fakeElem = document.createElement("textarea"), this.fakeElem.style.fontSize = "12pt", this.fakeElem.style.border = "0", this.fakeElem.style.padding = "0", this.fakeElem.style.margin = "0", this.fakeElem.style.position = "absolute", this.fakeElem.style[t ? "right" : "left"] = "-9999px"; + var n = window.pageYOffset || document.documentElement.scrollTop; + this.fakeElem.style.top = n + "px", this.fakeElem.setAttribute("readonly", ""), this.fakeElem.value = this.text, this.container.appendChild(this.fakeElem), this.selectedText = (0, s.default)(this.fakeElem), this.copyText() + } + }, { + key: "removeFake", + value: function() { + this.fakeHandler && (this.container.removeEventListener("click", this.fakeHandlerCallback), this.fakeHandler = null, this.fakeHandlerCallback = null), this.fakeElem && (this.container.removeChild(this.fakeElem), this.fakeElem = null) + } + }, { + key: "selectTarget", + value: function() { + this.selectedText = (0, s.default)(this.target), this.copyText() + } + }, { + key: "copyText", + value: function() { + var t = void 0; + try { + t = document.execCommand(this.action) + } catch (e) { + t = !1 + } + this.handleResult(t) + } + }, { + key: "handleResult", + value: function(e) { + this.emitter.emit(e ? "success" : "error", { + action: this.action, + text: this.selectedText, + trigger: this.trigger, + clearSelection: this.clearSelection.bind(this) + }) + } + }, { + key: "clearSelection", + value: function() { + this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges() + } + }, { + key: "destroy", + value: function() { + this.removeFake() + } + }, { + key: "action", + set: function() { + var e = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : "copy"; + if (this._action = e, "copy" !== this._action && "cut" !== this._action) throw new Error('Invalid "action" value, use either "copy" or "cut"') + }, + get: function() { + return this._action + } + }, { + key: "target", + set: function(e) { + if (void 0 !== e) { + if (!e || "object" !== (void 0 === e ? "undefined" : i(e)) || 1 !== e.nodeType) throw new Error('Invalid "target" value, use a valid Element'); + if ("copy" === this.action && e.hasAttribute("disabled")) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + if ("cut" === this.action && (e.hasAttribute("readonly") || e.hasAttribute("disabled"))) throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + this._target = e + } + }, + get: function() { + return this._target + } + }]), t + }(); + e.exports = c + }, function(e, t) { + e.exports = function(e) { + var t; + if ("SELECT" === e.nodeName) e.focus(), t = e.value; + else if ("INPUT" === e.nodeName || "TEXTAREA" === e.nodeName) { + var n = e.hasAttribute("readonly"); + n || e.setAttribute("readonly", ""), e.select(), e.setSelectionRange(0, e.value.length), n || e.removeAttribute("readonly"), t = e.value + } else { + e.hasAttribute("contenteditable") && e.focus(); + var r = window.getSelection(), + i = document.createRange(); + i.selectNodeContents(e), r.removeAllRanges(), r.addRange(i), t = r.toString() + } + return t + } + }, function(e, t) { + function n() {} + n.prototype = { + on: function(e, t, n) { + var r = this.e || (this.e = {}); + return (r[e] || (r[e] = [])).push({ + fn: t, + ctx: n + }), this + }, + once: function(e, t, n) { + var r = this; + + function i() { + r.off(e, i), t.apply(n, arguments) + } + return i._ = t, this.on(e, i, n) + }, + emit: function(e) { + for (var t = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[e] || []).slice(), r = 0, i = n.length; r < i; r++) n[r].fn.apply(n[r].ctx, t); + return this + }, + off: function(e, t) { + var n = this.e || (this.e = {}), + r = n[e], + i = []; + if (r && t) + for (var o = 0, a = r.length; o < a; o++) r[o].fn !== t && r[o].fn._ !== t && i.push(r[o]); + return i.length ? n[e] = i : delete n[e], this + } + }, e.exports = n + }, function(e, t, n) { + var d = n(5), + h = n(6); + e.exports = function(e, t, n) { + if (!e && !t && !n) throw new Error("Missing required arguments"); + if (!d.string(t)) throw new TypeError("Second argument must be a String"); + if (!d.fn(n)) throw new TypeError("Third argument must be a Function"); + if (d.node(e)) return u = t, f = n, (l = e).addEventListener(u, f), { + destroy: function() { + l.removeEventListener(u, f) + } + }; + if (d.nodeList(e)) return a = e, s = t, c = n, Array.prototype.forEach.call(a, function(e) { + e.addEventListener(s, c) + }), { + destroy: function() { + Array.prototype.forEach.call(a, function(e) { + e.removeEventListener(s, c) + }) + } + }; + if (d.string(e)) return r = e, i = t, o = n, h(document.body, r, i, o); + throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList"); + var r, i, o, a, s, c, l, u, f + } + }, function(e, n) { + n.node = function(e) { + return void 0 !== e && e instanceof HTMLElement && 1 === e.nodeType + }, n.nodeList = function(e) { + var t = Object.prototype.toString.call(e); + return void 0 !== e && ("[object NodeList]" === t || "[object HTMLCollection]" === t) && "length" in e && (0 === e.length || n.node(e[0])) + }, n.string = function(e) { + return "string" == typeof e || e instanceof String + }, n.fn = function(e) { + return "[object Function]" === Object.prototype.toString.call(e) + } + }, function(e, t, n) { + var a = n(7); + + function o(e, t, n, r, i) { + var o = function(t, n, e, r) { + return function(e) { + e.delegateTarget = a(e.target, n), e.delegateTarget && r.call(t, e) + } + }.apply(this, arguments); + return e.addEventListener(n, o, i), { + destroy: function() { + e.removeEventListener(n, o, i) + } + } + } + e.exports = function(e, t, n, r, i) { + return "function" == typeof e.addEventListener ? o.apply(null, arguments) : "function" == typeof n ? o.bind(null, document).apply(null, arguments) : ("string" == typeof e && (e = document.querySelectorAll(e)), Array.prototype.map.call(e, function(e) { + return o(e, t, n, r, i) + })) + } + }, function(e, t) { + if ("undefined" != typeof Element && !Element.prototype.matches) { + var n = Element.prototype; + n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector + } + e.exports = function(e, t) { + for (; e && 9 !== e.nodeType;) { + if ("function" == typeof e.matches && e.matches(t)) return e; + e = e.parentNode + } + } + }]) + }, e.exports = r() +}, function(r, i, o) { + var a, s; + ! function(e) { + if (void 0 === (s = "function" == typeof(a = e) ? a.call(i, o, i, r) : a) || (r.exports = s), !0, r.exports = e(), !!0) { + var t = window.Cookies, + n = window.Cookies = e(); + n.noConflict = function() { + return window.Cookies = t, n + } + } + }(function() { + function m() { + for (var e = 0, t = {}; e < arguments.length; e++) { + var n = arguments[e]; + for (var r in n) t[r] = n[r] + } + return t + } + return function e(h) { + function p(e, t, n) { + var r; + if ("undefined" != typeof document) { + if (1 < arguments.length) { + if ("number" == typeof(n = m({ + path: "/" + }, p.defaults, n)).expires) { + var i = new Date; + i.setMilliseconds(i.getMilliseconds() + 864e5 * n.expires), n.expires = i + } + n.expires = n.expires ? n.expires.toUTCString() : ""; + try { + r = JSON.stringify(t), /^[\{\[]/.test(r) && (t = r) + } catch (e) {} + t = h.write ? h.write(t, e) : encodeURIComponent(String(t)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent), e = (e = (e = encodeURIComponent(String(e))).replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent)).replace(/[\(\)]/g, escape); + var o = ""; + for (var a in n) n[a] && (o += "; " + a, !0 !== n[a] && (o += "=" + n[a])); + return document.cookie = e + "=" + t + o + } + e || (r = {}); + for (var s = document.cookie ? document.cookie.split("; ") : [], c = /(%[0-9A-Z]{2})+/g, l = 0; l < s.length; l++) { + var u = s[l].split("="), + f = u.slice(1).join("="); + this.json || '"' !== f.charAt(0) || (f = f.slice(1, -1)); + try { + var d = u[0].replace(c, decodeURIComponent); + if (f = h.read ? h.read(f, d) : h(f, d) || f.replace(c, decodeURIComponent), this.json) try { + f = JSON.parse(f) + } catch (e) {} + if (e === d) { + r = f; + break + } + e || (r[d] = f) + } catch (e) {} + } + return r + } + } + return (p.set = p).get = function(e) { + return p.call(p, e) + }, p.getJSON = function() { + return p.apply({ + json: !0 + }, [].slice.call(arguments)) + }, p.defaults = {}, p.remove = function(e, t) { + p(e, "", m(t, { + expires: -1 + })) + }, p.withConverter = e, p + }(function() {}) + }) +}, function(e, t, n) { + "use strict"; + n.r(t); + var r = "function" == typeof fetch ? fetch.bind() : function(i, o) { + return o = o || {}, new Promise(function(e, t) { + var n = new XMLHttpRequest; + for (var r in n.open(o.method || "get", i, !0), o.headers) n.setRequestHeader(r, o.headers[r]); + + function s() { + var r, i = [], + o = [], + a = {}; + return n.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, function(e, t, n) { + i.push(t = t.toLowerCase()), o.push([t, n]), r = a[t], a[t] = r ? r + "," + n : n + }), { + ok: 2 == (n.status / 100 | 0), + status: n.status, + statusText: n.statusText, + url: n.responseURL, + clone: s, + text: function() { + return Promise.resolve(n.responseText) + }, + json: function() { + return Promise.resolve(n.responseText).then(JSON.parse) + }, + blob: function() { + return Promise.resolve(new Blob([n.response])) + }, + headers: { + keys: function() { + return i + }, + entries: function() { + return o + }, + get: function(e) { + return a[e.toLowerCase()] + }, + has: function(e) { + return e.toLowerCase() in a + } + } + } + } + n.withCredentials = "include" == o.credentials, n.onload = function() { + e(s()) + }, n.onerror = t, n.send(o.body || null) + }) + }; + t.default = r +}, function(e, t, n) { + "use strict"; + t.a = function(t) { + var n = this.constructor; + return this.then(function(e) { + return n.resolve(t()).then(function() { + return e + }) + }, function(e) { + return n.resolve(t()).then(function() { + return n.reject(e) + }) + }) + } +}, function(e, n, r) { + "use strict"; + (function(f) { + r.d(n, "a", function() { + return t + }); + var e = r(1), + d = r.n(e), + h = function(e) { + var t = document.getElementsByName("lang:" + e)[0]; + if (!(t instanceof HTMLMetaElement)) throw new ReferenceError; + return t.content + }, + t = function() { + function e(e, t) { + var n = "string" == typeof e ? document.querySelector(e) : e; + if (!(n instanceof HTMLElement)) throw new ReferenceError; + this.el_ = n; + var r = Array.prototype.slice.call(this.el_.children), + i = r[0], + o = r[1]; + this.data_ = t, this.meta_ = i, this.list_ = o, this.message_ = { + placeholder: this.meta_.textContent, + none: h("search.result.none"), + one: h("search.result.one"), + other: h("search.result.other") + }; + var a = h("search.tokenizer"); + a.length && (d.a.tokenizer.separator = a), this.lang_ = h("search.language").split(",").filter(Boolean).map(function(e) { + return e.trim() + }) + } + return e.prototype.update = function(e) { + var t, a = this; + if ("focus" !== e.type || this.index_) { + if ("focus" === e.type || "keyup" === e.type) { + var n = e.target; + if (!(n instanceof HTMLInputElement)) throw new ReferenceError; + if (!this.index_ || n.value === this.value_) return; + for (; this.list_.firstChild;) this.list_.removeChild(this.list_.firstChild); + if (this.value_ = n.value, 0 === this.value_.length) return void(this.meta_.textContent = this.message_.placeholder); + var r = this.index_.query(function(t) { + a.value_.toLowerCase().split(" ").filter(Boolean).forEach(function(e) { + t.term(e, { + wildcard: d.a.Query.wildcard.TRAILING + }) + }) + }).reduce(function(e, t) { + var n = a.docs_.get(t.ref); + if (n.parent) { + var r = n.parent.location; + e.set(r, (e.get(r) || []).concat(t)) + } else { + var i = n.location; + e.set(i, e.get(i) || []) + } + return e + }, new Map), + i = (t = this.value_.trim(), t.replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&")).replace(new RegExp(d.a.tokenizer.separator, "img"), "|"), + s = new RegExp("(^|" + d.a.tokenizer.separator + ")(" + i + ")", "img"), + c = function(e, t, n) { + return t + "" + n + "" + }; + this.stack_ = [], r.forEach(function(e, t) { + var n, r = a.docs_.get(t), + i = f.createElement("li", { + class: "md-search-result__item" + }, f.createElement("a", { + href: r.location, + title: r.title, + class: "md-search-result__link", + tabindex: "-1" + }, f.createElement("article", { + class: "md-search-result__article md-search-result__article--document" + }, f.createElement("h1", { + class: "md-search-result__title" + }, { + __html: r.title.replace(s, c) + }), r.text.length ? f.createElement("p", { + class: "md-search-result__teaser" + }, { + __html: r.text.replace(s, c) + }) : {}))), + o = e.map(function(t) { + return function() { + var e = a.docs_.get(t.ref); + i.appendChild(f.createElement("a", { + href: e.location, + title: e.title, + class: "md-search-result__link", + "data-md-rel": "anchor", + tabindex: "-1" + }, f.createElement("article", { + class: "md-search-result__article" + }, f.createElement("h1", { + class: "md-search-result__title" + }, { + __html: e.title.replace(s, c) + }), e.text.length ? f.createElement("p", { + class: "md-search-result__teaser" + }, { + __html: function(e, t) { + var n = t; + if (e.length > n) { + for (; + " " !== e[n] && 0 < --n;); + return e.substring(0, n) + "..." + } + return e + }(e.text.replace(s, c), 400) + }) : {}))) + } + }); + (n = a.stack_).push.apply(n, [function() { + return a.list_.appendChild(i) + }].concat(o)) + }); + var o = this.el_.parentNode; + if (!(o instanceof HTMLElement)) throw new ReferenceError; + for (; this.stack_.length && o.offsetHeight >= o.scrollHeight - 16;) this.stack_.shift()(); + var l = this.list_.querySelectorAll("[data-md-rel=anchor]"); + switch (Array.prototype.forEach.call(l, function(r) { + ["click", "keydown"].forEach(function(n) { + r.addEventListener(n, function(e) { + if ("keydown" !== n || 13 === e.keyCode) { + var t = document.querySelector("[data-md-toggle=search]"); + if (!(t instanceof HTMLInputElement)) throw new ReferenceError; + t.checked && (t.checked = !1, t.dispatchEvent(new CustomEvent("change"))), e.preventDefault(), setTimeout(function() { + document.location.href = r.href + }, 100) + } + }) + }) + }), r.size) { + case 0: + this.meta_.textContent = this.message_.none; + break; + case 1: + this.meta_.textContent = this.message_.one; + break; + default: + this.meta_.textContent = this.message_.other.replace("#", r.size) + } + } + } else { + var u = function(e) { + a.docs_ = e.reduce(function(e, t) { + var n, r, i, o = t.location.split("#"), + a = o[0], + s = o[1]; + return t.text = (n = t.text, r = document.createTextNode(n), (i = document.createElement("p")).appendChild(r), i.innerHTML), s && (t.parent = e.get(a), t.parent && !t.parent.done && (t.parent.title = t.title, t.parent.text = t.text, t.parent.done = !0)), t.text = t.text.replace(/\n/g, " ").replace(/\s+/g, " ").replace(/\s+([,.:;!?])/g, function(e, t) { + return t + }), t.parent && t.parent.title === t.title || e.set(t.location, t), e + }, new Map); + var i = a.docs_, + o = a.lang_; + a.stack_ = [], a.index_ = d()(function() { + var e, t = this, + n = { + "search.pipeline.trimmer": d.a.trimmer, + "search.pipeline.stopwords": d.a.stopWordFilter + }, + r = Object.keys(n).reduce(function(e, t) { + return h(t).match(/^false$/i) || e.push(n[t]), e + }, []); + this.pipeline.reset(), r && (e = this.pipeline).add.apply(e, r), 1 === o.length && "en" !== o[0] && d.a[o[0]] ? this.use(d.a[o[0]]) : 1 < o.length && this.use(d.a.multiLanguage.apply(d.a, o)), this.field("title", { + boost: 10 + }), this.field("text"), this.ref("location"), i.forEach(function(e) { + return t.add(e) + }) + }); + var t = a.el_.parentNode; + if (!(t instanceof HTMLElement)) throw new ReferenceError; + t.addEventListener("scroll", function() { + for (; a.stack_.length && t.scrollTop + t.offsetHeight >= t.scrollHeight - 16;) a.stack_.splice(0, 10).forEach(function(e) { + return e() + }) + }) + }; + setTimeout(function() { + return "function" == typeof a.data_ ? a.data_().then(u) : u(a.data_) + }, 250) + } + }, e + }() + }).call(this, r(3)) +}, function(e, n, r) { + "use strict"; + (function(t) { + r.d(n, "a", function() { + return e + }); + var e = function() { + function e(e) { + var t = "string" == typeof e ? document.querySelector(e) : e; + if (!(t instanceof HTMLElement)) throw new ReferenceError; + this.el_ = t + } + return e.prototype.initialize = function(e) { + e.length && this.el_.children.length && this.el_.children[this.el_.children.length - 1].appendChild(t.createElement("ul", { + class: "md-source__facts" + }, e.map(function(e) { + return t.createElement("li", { + class: "md-source__fact" + }, e) + }))), this.el_.dataset.mdState = "done" + }, e + }() + }).call(this, r(3)) +}, , , function(e, n, c) { + "use strict"; + c.r(n), + function(o) { + c.d(n, "app", function() { + return t + }); + c(14), c(15), c(16), c(17), c(18), c(19), c(20); + var r = c(2), + e = c(5), + a = c.n(e), + i = c(0); + window.Promise = window.Promise || r.a; + var s = function(e) { + var t = document.getElementsByName("lang:" + e)[0]; + if (!(t instanceof HTMLMetaElement)) throw new ReferenceError; + return t.content + }; + var t = { + initialize: function(t) { + new i.a.Event.Listener(document, "DOMContentLoaded", function() { + if (!(document.body instanceof HTMLElement)) throw new ReferenceError; + Modernizr.addTest("ios", function() { + return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g) + }); + var e = document.querySelectorAll("table:not([class])"); + if (Array.prototype.forEach.call(e, function(e) { + var t = o.createElement("div", { + class: "md-typeset__scrollwrap" + }, o.createElement("div", { + class: "md-typeset__table" + })); + e.nextSibling ? e.parentNode.insertBefore(t, e.nextSibling) : e.parentNode.appendChild(t), t.children[0].appendChild(e) + }), a.a.isSupported()) { + var t = document.querySelectorAll(".codehilite > pre, pre > code"); + Array.prototype.forEach.call(t, function(e, t) { + var n = "__code_" + t, + r = o.createElement("button", { + class: "md-clipboard", + title: s("clipboard.copy"), + "data-clipboard-target": "#" + n + " pre, #" + n + " code" + }, o.createElement("span", { + class: "md-clipboard__message" + })), + i = e.parentNode; + i.id = n, i.insertBefore(r, e) + }), new a.a(".md-clipboard").on("success", function(e) { + var t = e.trigger.querySelector(".md-clipboard__message"); + if (!(t instanceof HTMLElement)) throw new ReferenceError; + e.clearSelection(), t.dataset.mdTimer && clearTimeout(parseInt(t.dataset.mdTimer, 10)), t.classList.add("md-clipboard__message--active"), t.innerHTML = s("clipboard.copied"), t.dataset.mdTimer = setTimeout(function() { + t.classList.remove("md-clipboard__message--active"), t.dataset.mdTimer = "" + }, 2e3).toString() + }) + } + if (!Modernizr.details) { + var n = document.querySelectorAll("details > summary"); + Array.prototype.forEach.call(n, function(e) { + e.addEventListener("click", function(e) { + var t = e.target.parentNode; + t.hasAttribute("open") ? t.removeAttribute("open") : t.setAttribute("open", "") + }) + }) + } + var r = function() { + if (document.location.hash) { + var e = document.getElementById(document.location.hash.substring(1)); + if (!e) return; + for (var t = e.parentNode; t && !(t instanceof HTMLDetailsElement);) t = t.parentNode; + if (t && !t.open) { + t.open = !0; + var n = location.hash; + location.hash = " ", location.hash = n + } + } + }; + if (window.addEventListener("hashchange", r), r(), Modernizr.ios) { + var i = document.querySelectorAll("[data-md-scrollfix]"); + Array.prototype.forEach.call(i, function(t) { + t.addEventListener("touchstart", function() { + var e = t.scrollTop; + 0 === e ? t.scrollTop = 1 : e + t.offsetHeight === t.scrollHeight && (t.scrollTop = e - 1) + }) + }) + } + }).listen(), new i.a.Event.Listener(window, ["scroll", "resize", "orientationchange"], new i.a.Header.Shadow("[data-md-component=container]", "[data-md-component=header]")).listen(), new i.a.Event.Listener(window, ["scroll", "resize", "orientationchange"], new i.a.Header.Title("[data-md-component=title]", ".md-typeset h1")).listen(), document.querySelector("[data-md-component=hero]") && new i.a.Event.Listener(window, ["scroll", "resize", "orientationchange"], new i.a.Tabs.Toggle("[data-md-component=hero]")).listen(), document.querySelector("[data-md-component=tabs]") && new i.a.Event.Listener(window, ["scroll", "resize", "orientationchange"], new i.a.Tabs.Toggle("[data-md-component=tabs]")).listen(), new i.a.Event.MatchMedia("(min-width: 1220px)", new i.a.Event.Listener(window, ["scroll", "resize", "orientationchange"], new i.a.Sidebar.Position("[data-md-component=navigation]", "[data-md-component=header]"))), document.querySelector("[data-md-component=toc]") && new i.a.Event.MatchMedia("(min-width: 960px)", new i.a.Event.Listener(window, ["scroll", "resize", "orientationchange"], new i.a.Sidebar.Position("[data-md-component=toc]", "[data-md-component=header]"))), new i.a.Event.MatchMedia("(min-width: 960px)", new i.a.Event.Listener(window, "scroll", new i.a.Nav.Blur("[data-md-component=toc] .md-nav__link"))); + var e = document.querySelectorAll("[data-md-component=collapsible]"); + Array.prototype.forEach.call(e, function(e) { + new i.a.Event.MatchMedia("(min-width: 1220px)", new i.a.Event.Listener(e.previousElementSibling, "click", new i.a.Nav.Collapse(e))) + }), new i.a.Event.MatchMedia("(max-width: 1219px)", new i.a.Event.Listener("[data-md-component=navigation] [data-md-toggle]", "change", new i.a.Nav.Scrolling("[data-md-component=navigation] nav"))), document.querySelector("[data-md-component=search]") && (new i.a.Event.MatchMedia("(max-width: 959px)", new i.a.Event.Listener("[data-md-toggle=search]", "change", new i.a.Search.Lock("[data-md-toggle=search]")))), + new i.a.Event.Listener(document.body, "keydown", function(e) { + if (9 === e.keyCode) { + var t = document.querySelectorAll("[data-md-component=navigation] .md-nav__link[for]:not([tabindex])"); + Array.prototype.forEach.call(t, function(e) { + e.offsetHeight && (e.tabIndex = 0) + }) + } + }).listen(), new i.a.Event.Listener(document.body, "mousedown", function() { + var e = document.querySelectorAll("[data-md-component=navigation] .md-nav__link[tabindex]"); + Array.prototype.forEach.call(e, function(e) { + e.removeAttribute("tabIndex") + }) + }).listen(), document.body.addEventListener("click", function() { + "tabbing" === document.body.dataset.mdState && (document.body.dataset.mdState = "") + }), new i.a.Event.MatchMedia("(max-width: 959px)", new i.a.Event.Listener("[data-md-component=navigation] [href^='#']", "click", function() { + var e = document.querySelector("[data-md-toggle=drawer]"); + if (!(e instanceof HTMLInputElement)) throw new ReferenceError; + e.checked && (e.checked = !1, e.dispatchEvent(new CustomEvent("change"))) + })), + function() { + var e = document.querySelector("[data-md-source]"); + if (!e) return r.a.resolve([]); + if (!(e instanceof HTMLAnchorElement)) throw new ReferenceError; + switch (e.dataset.mdSource) { + case "github": + return new i.a.Source.Adapter.GitHub(e).fetch(); + default: + return r.a.resolve([]) + } + }().then(function(t) { + var e = document.querySelectorAll("[data-md-source]"); + Array.prototype.forEach.call(e, function(e) { + new i.a.Source.Repository(e).initialize(t) + }) + }); + var n = function() { + var e = document.querySelectorAll("details"); + Array.prototype.forEach.call(e, function(e) { + e.setAttribute("open", "") + }) + }; + new i.a.Event.MatchMedia("print", { + listen: n, + unlisten: function() {} + }), window.onbeforeprint = n + } + } + }.call(this, c(3)) +}, function(e, t, n) { + e.exports = n.p + "assets/images/icons/bitbucket.1b09e088.svg" +}, function(e, t, n) { + e.exports = n.p + "assets/images/icons/github.f0b8504a.svg" +}, function(e, t, n) { + e.exports = n.p + "assets/images/icons/gitlab.6dd19c00.svg" +}, function(e, t) { + e.exports = "/Users/squidfunk/Desktop/General/Sources/mkdocs-material/material/application.4031d38b.css" +}, function(e, t) { + e.exports = "/Users/squidfunk/Desktop/General/Sources/mkdocs-material/material/application-palette.224b79ff.css" +}, function(e, t) { + ! function() { + if ("undefined" != typeof window) try { + var e = new window.CustomEvent("test", { + cancelable: !0 + }); + if (e.preventDefault(), !0 !== e.defaultPrevented) throw new Error("Could not prevent default") + } catch (e) { + var t = function(e, t) { + var n, r; + return (t = t || {}).bubbles = !!t.bubbles, t.cancelable = !!t.cancelable, (n = document.createEvent("CustomEvent")).initCustomEvent(e, t.bubbles, t.cancelable, t.detail), r = n.preventDefault, n.preventDefault = function() { + r.call(this); + try { + Object.defineProperty(this, "defaultPrevented", { + get: function() { + return !0 + } + }) + } catch (e) { + this.defaultPrevented = !0 + } + }, n + }; + t.prototype = window.Event.prototype, window.CustomEvent = t + } + }() +}, function(e, t, n) { + window.fetch || (window.fetch = n(7).default || n(7)) +}, function(e, i, o) { + (function(e) { + var t = void 0 !== e && e || "undefined" != typeof self && self || window, + n = Function.prototype.apply; + + function r(e, t) { + this._id = e, this._clearFn = t + } + i.setTimeout = function() { + return new r(n.call(setTimeout, t, arguments), clearTimeout) + }, i.setInterval = function() { + return new r(n.call(setInterval, t, arguments), clearInterval) + }, i.clearTimeout = i.clearInterval = function(e) { + e && e.close() + }, r.prototype.unref = r.prototype.ref = function() {}, r.prototype.close = function() { + this._clearFn.call(t, this._id) + }, i.enroll = function(e, t) { + clearTimeout(e._idleTimeoutId), e._idleTimeout = t + }, i.unenroll = function(e) { + clearTimeout(e._idleTimeoutId), e._idleTimeout = -1 + }, i._unrefActive = i.active = function(e) { + clearTimeout(e._idleTimeoutId); + var t = e._idleTimeout; + 0 <= t && (e._idleTimeoutId = setTimeout(function() { + e._onTimeout && e._onTimeout() + }, t)) + }, o(22), i.setImmediate = "undefined" != typeof self && self.setImmediate || void 0 !== e && e.setImmediate || this && this.setImmediate, i.clearImmediate = "undefined" != typeof self && self.clearImmediate || void 0 !== e && e.clearImmediate || this && this.clearImmediate + }).call(this, o(4)) +}, function(e, t, n) { + (function(e, p) { + ! function(n, r) { + "use strict"; + if (!n.setImmediate) { + var i, o, t, a, e, s = 1, + c = {}, + l = !1, + u = n.document, + f = Object.getPrototypeOf && Object.getPrototypeOf(n); + f = f && f.setTimeout ? f : n, i = "[object process]" === {}.toString.call(n.process) ? function(e) { + p.nextTick(function() { + h(e) + }) + } : function() { + if (n.postMessage && !n.importScripts) { + var e = !0, + t = n.onmessage; + return n.onmessage = function() { + e = !1 + }, n.postMessage("", "*"), n.onmessage = t, e + } + }() ? (a = "setImmediate$" + Math.random() + "$", e = function(e) { + e.source === n && "string" == typeof e.data && 0 === e.data.indexOf(a) && h(+e.data.slice(a.length)) + }, n.addEventListener ? n.addEventListener("message", e, !1) : n.attachEvent("onmessage", e), function(e) { + n.postMessage(a + e, "*") + }) : n.MessageChannel ? ((t = new MessageChannel).port1.onmessage = function(e) { + h(e.data) + }, function(e) { + t.port2.postMessage(e) + }) : u && "onreadystatechange" in u.createElement("script") ? (o = u.documentElement, function(e) { + var t = u.createElement("script"); + t.onreadystatechange = function() { + h(e), t.onreadystatechange = null, o.removeChild(t), t = null + }, o.appendChild(t) + }) : function(e) { + setTimeout(h, 0, e) + }, f.setImmediate = function(e) { + "function" != typeof e && (e = new Function("" + e)); + for (var t = new Array(arguments.length - 1), n = 0; n < t.length; n++) t[n] = arguments[n + 1]; + var r = { + callback: e, + args: t + }; + return c[s] = r, i(s), s++ + }, f.clearImmediate = d + } + + function d(e) { + delete c[e] + } + + function h(e) { + if (l) setTimeout(h, 0, e); + else { + var t = c[e]; + if (t) { + l = !0; + try { + ! function(e) { + var t = e.callback, + n = e.args; + switch (n.length) { + case 0: + t(); + break; + case 1: + t(n[0]); + break; + case 2: + t(n[0], n[1]); + break; + case 3: + t(n[0], n[1], n[2]); + break; + default: + t.apply(r, n) + } + }(t) + } finally { + d(e), l = !1 + } + } + } + } + }("undefined" == typeof self ? void 0 === e ? this : e : self) + }).call(this, n(4), n(23)) +}, function(e, t) { + var n, r, i = e.exports = {}; + + function o() { + throw new Error("setTimeout has not been defined") + } + + function a() { + throw new Error("clearTimeout has not been defined") + } + + function s(t) { + if (n === setTimeout) return setTimeout(t, 0); + if ((n === o || !n) && setTimeout) return n = setTimeout, setTimeout(t, 0); + try { + return n(t, 0) + } catch (e) { + try { + return n.call(null, t, 0) + } catch (e) { + return n.call(this, t, 0) + } + } + }! function() { + try { + n = "function" == typeof setTimeout ? setTimeout : o + } catch (e) { + n = o + } + try { + r = "function" == typeof clearTimeout ? clearTimeout : a + } catch (e) { + r = a + } + }(); + var c, l = [], + u = !1, + f = -1; + + function d() { + u && c && (u = !1, c.length ? l = c.concat(l) : f = -1, l.length && h()) + } + + function h() { + if (!u) { + var e = s(d); + u = !0; + for (var t = l.length; t;) { + for (c = l, l = []; ++f < t;) c && c[f].run(); + f = -1, t = l.length + } + c = null, u = !1, + function(t) { + if (r === clearTimeout) return clearTimeout(t); + if ((r === a || !r) && clearTimeout) return r = clearTimeout, clearTimeout(t); + try { + r(t) + } catch (e) { + try { + return r.call(null, t) + } catch (e) { + return r.call(this, t) + } + } + }(e) + } + } + + function p(e, t) { + this.fun = e, this.array = t + } + + function m() {} + i.nextTick = function(e) { + var t = new Array(arguments.length - 1); + if (1 < arguments.length) + for (var n = 1; n < arguments.length; n++) t[n - 1] = arguments[n]; + l.push(new p(e, t)), 1 !== l.length || u || s(h) + }, p.prototype.run = function() { + this.fun.apply(null, this.array) + }, i.title = "browser", i.browser = !0, i.env = {}, i.argv = [], i.version = "", i.versions = {}, i.on = m, i.addListener = m, i.once = m, i.off = m, i.removeListener = m, i.removeAllListeners = m, i.emit = m, i.prependListener = m, i.prependOnceListener = m, i.listeners = function(e) { + return [] + }, i.binding = function(e) { + throw new Error("process.binding is not supported") + }, i.cwd = function() { + return "/" + }, i.chdir = function(e) { + throw new Error("process.chdir is not supported") + }, i.umask = function() { + return 0 + } +}, function(i, o, a) { + var s, c; + /** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.6 + * Copyright (C) 2019 Oliver Nightingale + * @license MIT + */ + ! function() { + var t, l, u, e, n, f, d, h, p, m, y, v, g, w, _, E, x, b, k, S, T, L, R, O, C, r, D = function(e) { + var t = new D.Builder; + return t.pipeline.add(D.trimmer, D.stopWordFilter, D.stemmer), t.searchPipeline.add(D.stemmer), e.call(t, t), t.build() + }; + D.version = "2.3.6", D.utils = {}, D.utils.warn = (t = this, function(e) { + t.console && console.warn && console.warn(e) + }), D.utils.asString = function(e) { + return null == e ? "" : e.toString() + }, D.utils.clone = function(e) { + if (null == e) return e; + for (var t = Object.create(null), n = Object.keys(e), r = 0; r < n.length; r++) { + var i = n[r], + o = e[i]; + if (Array.isArray(o)) t[i] = o.slice(); + else { + if ("string" != typeof o && "number" != typeof o && "boolean" != typeof o) throw new TypeError("clone is not deep and does not support nested objects"); + t[i] = o + } + } + return t + }, D.FieldRef = function(e, t, n) { + this.docRef = e, this.fieldName = t, this._stringValue = n + }, D.FieldRef.joiner = "/", D.FieldRef.fromString = function(e) { + var t = e.indexOf(D.FieldRef.joiner); + if (-1 === t) throw "malformed field ref string"; + var n = e.slice(0, t), + r = e.slice(t + 1); + return new D.FieldRef(r, n, e) + }, D.FieldRef.prototype.toString = function() { + return null == this._stringValue && (this._stringValue = this.fieldName + D.FieldRef.joiner + this.docRef), this._stringValue + }, D.Set = function(e) { + if (this.elements = Object.create(null), e) { + this.length = e.length; + for (var t = 0; t < this.length; t++) this.elements[e[t]] = !0 + } else this.length = 0 + }, D.Set.complete = { + intersect: function(e) { + return e + }, + union: function(e) { + return e + }, + contains: function() { + return !0 + } + }, D.Set.empty = { + intersect: function() { + return this + }, + union: function(e) { + return e + }, + contains: function() { + return !1 + } + }, D.Set.prototype.contains = function(e) { + return !!this.elements[e] + }, D.Set.prototype.intersect = function(e) { + var t, n, r, i = []; + if (e === D.Set.complete) return this; + if (e === D.Set.empty) return e; + n = this.length < e.length ? (t = this, e) : (t = e, this), r = Object.keys(t.elements); + for (var o = 0; o < r.length; o++) { + var a = r[o]; + a in n.elements && i.push(a) + } + return new D.Set(i) + }, D.Set.prototype.union = function(e) { + return e === D.Set.complete ? D.Set.complete : e === D.Set.empty ? this : new D.Set(Object.keys(this.elements).concat(Object.keys(e.elements))) + }, D.idf = function(e, t) { + var n = 0; + for (var r in e) "_index" != r && (n += Object.keys(e[r]).length); + var i = (t - n + .5) / (n + .5); + return Math.log(1 + Math.abs(i)) + }, D.Token = function(e, t) { + this.str = e || "", this.metadata = t || {} + }, D.Token.prototype.toString = function() { + return this.str + }, D.Token.prototype.update = function(e) { + return this.str = e(this.str, this.metadata), this + }, D.Token.prototype.clone = function(e) { + return e = e || function(e) { + return e + }, new D.Token(e(this.str, this.metadata), this.metadata) + }, D.tokenizer = function(e, t) { + if (null == e || null == e) return []; + if (Array.isArray(e)) return e.map(function(e) { + return new D.Token(D.utils.asString(e).toLowerCase(), D.utils.clone(t)) + }); + for (var n = e.toString().trim().toLowerCase(), r = n.length, i = [], o = 0, a = 0; o <= r; o++) { + var s = o - a; + if (n.charAt(o).match(D.tokenizer.separator) || o == r) { + if (0 < s) { + var c = D.utils.clone(t) || {}; + c.position = [a, s], c.index = i.length, i.push(new D.Token(n.slice(a, o), c)) + } + a = o + 1 + } + } + return i + }, D.tokenizer.separator = /[\s\-]+/, D.Pipeline = function() { + this._stack = [] + }, D.Pipeline.registeredFunctions = Object.create(null), D.Pipeline.registerFunction = function(e, t) { + t in this.registeredFunctions && D.utils.warn("Overwriting existing registered function: " + t), e.label = t, D.Pipeline.registeredFunctions[e.label] = e + }, D.Pipeline.warnIfFunctionNotRegistered = function(e) { + e.label && e.label in this.registeredFunctions || D.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n", e) + }, D.Pipeline.load = function(e) { + var n = new D.Pipeline; + return e.forEach(function(e) { + var t = D.Pipeline.registeredFunctions[e]; + if (!t) throw new Error("Cannot load unregistered function: " + e); + n.add(t) + }), n + }, D.Pipeline.prototype.add = function() { + Array.prototype.slice.call(arguments).forEach(function(e) { + D.Pipeline.warnIfFunctionNotRegistered(e), this._stack.push(e) + }, this) + }, D.Pipeline.prototype.after = function(e, t) { + D.Pipeline.warnIfFunctionNotRegistered(t); + var n = this._stack.indexOf(e); + if (-1 == n) throw new Error("Cannot find existingFn"); + n += 1, this._stack.splice(n, 0, t) + }, D.Pipeline.prototype.before = function(e, t) { + D.Pipeline.warnIfFunctionNotRegistered(t); + var n = this._stack.indexOf(e); + if (-1 == n) throw new Error("Cannot find existingFn"); + this._stack.splice(n, 0, t) + }, D.Pipeline.prototype.remove = function(e) { + var t = this._stack.indexOf(e); - 1 != t && this._stack.splice(t, 1) + }, D.Pipeline.prototype.run = function(e) { + for (var t = this._stack.length, n = 0; n < t; n++) { + for (var r = this._stack[n], i = [], o = 0; o < e.length; o++) { + var a = r(e[o], o, e); + if (void 0 !== a && "" !== a) + if (Array.isArray(a)) + for (var s = 0; s < a.length; s++) i.push(a[s]); + else i.push(a) + } + e = i + } + return e + }, D.Pipeline.prototype.runString = function(e, t) { + var n = new D.Token(e, t); + return this.run([n]).map(function(e) { + return e.toString() + }) + }, D.Pipeline.prototype.reset = function() { + this._stack = [] + }, D.Pipeline.prototype.toJSON = function() { + return this._stack.map(function(e) { + return D.Pipeline.warnIfFunctionNotRegistered(e), e.label + }) + }, D.Vector = function(e) { + this._magnitude = 0, this.elements = e || [] + }, D.Vector.prototype.positionForIndex = function(e) { + if (0 == this.elements.length) return 0; + for (var t = 0, n = this.elements.length / 2, r = n - t, i = Math.floor(r / 2), o = this.elements[2 * i]; 1 < r && (o < e && (t = i), e < o && (n = i), o != e);) r = n - t, i = t + Math.floor(r / 2), o = this.elements[2 * i]; + return o == e ? 2 * i : e < o ? 2 * i : o < e ? 2 * (i + 1) : void 0 + }, D.Vector.prototype.insert = function(e, t) { + this.upsert(e, t, function() { + throw "duplicate index" + }) + }, D.Vector.prototype.upsert = function(e, t, n) { + this._magnitude = 0; + var r = this.positionForIndex(e); + this.elements[r] == e ? this.elements[r + 1] = n(this.elements[r + 1], t) : this.elements.splice(r, 0, e, t) + }, D.Vector.prototype.magnitude = function() { + if (this._magnitude) return this._magnitude; + for (var e = 0, t = this.elements.length, n = 1; n < t; n += 2) { + var r = this.elements[n]; + e += r * r + } + return this._magnitude = Math.sqrt(e) + }, D.Vector.prototype.dot = function(e) { + for (var t = 0, n = this.elements, r = e.elements, i = n.length, o = r.length, a = 0, s = 0, c = 0, l = 0; c < i && l < o;)(a = n[c]) < (s = r[l]) ? c += 2 : s < a ? l += 2 : a == s && (t += n[c + 1] * r[l + 1], c += 2, l += 2); + return t + }, D.Vector.prototype.similarity = function(e) { + return this.dot(e) / this.magnitude() || 0 + }, D.Vector.prototype.toArray = function() { + for (var e = new Array(this.elements.length / 2), t = 1, n = 0; t < this.elements.length; t += 2, n++) e[n] = this.elements[t]; + return e + }, D.Vector.prototype.toJSON = function() { + return this.elements + }, D.stemmer = (l = { + ational: "ate", + tional: "tion", + enci: "ence", + anci: "ance", + izer: "ize", + bli: "ble", + alli: "al", + entli: "ent", + eli: "e", + ousli: "ous", + ization: "ize", + ation: "ate", + ator: "ate", + alism: "al", + iveness: "ive", + fulness: "ful", + ousness: "ous", + aliti: "al", + iviti: "ive", + biliti: "ble", + logi: "log" + }, u = { + icate: "ic", + ative: "", + alize: "al", + iciti: "ic", + ical: "ic", + ful: "", + ness: "" + }, e = "[aeiouy]", n = "[^aeiou][^aeiouy]*", f = new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*"), d = new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*[aeiouy][aeiou]*[^aeiou][^aeiouy]*"), h = new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy][aeiou]*[^aeiou][^aeiouy]*([aeiouy][aeiou]*)?$"), p = new RegExp("^([^aeiou][^aeiouy]*)?[aeiouy]"), m = /^(.+?)(ss|i)es$/, y = /^(.+?)([^s])s$/, v = /^(.+?)eed$/, g = /^(.+?)(ed|ing)$/, w = /.$/, _ = /(at|bl|iz)$/, E = new RegExp("([^aeiouylsz])\\1$"), x = new RegExp("^" + n + e + "[^aeiouwxy]$"), b = /^(.+?[^aeiou])y$/, k = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/, S = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/, T = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/, L = /^(.+?)(s|t)(ion)$/, R = /^(.+?)e$/, O = /ll$/, C = new RegExp("^" + n + e + "[^aeiouwxy]$"), r = function(e) { + var t, n, r, i, o, a, s; + if (e.length < 3) return e; + if ("y" == (r = e.substr(0, 1)) && (e = r.toUpperCase() + e.substr(1)), o = y, (i = m).test(e) ? e = e.replace(i, "$1$2") : o.test(e) && (e = e.replace(o, "$1$2")), o = g, (i = v).test(e)) { + var c = i.exec(e); + (i = f).test(c[1]) && (i = w, e = e.replace(i, "")) + } else if (o.test(e)) { + t = (c = o.exec(e))[1], (o = p).test(t) && (a = E, s = x, (o = _).test(e = t) ? e += "e" : a.test(e) ? (i = w, e = e.replace(i, "")) : s.test(e) && (e += "e")) + }(i = b).test(e) && (e = (t = (c = i.exec(e))[1]) + "i"); + (i = k).test(e) && (t = (c = i.exec(e))[1], n = c[2], (i = f).test(t) && (e = t + l[n])); + (i = S).test(e) && (t = (c = i.exec(e))[1], n = c[2], (i = f).test(t) && (e = t + u[n])); + if (o = L, (i = T).test(e)) t = (c = i.exec(e))[1], (i = d).test(t) && (e = t); + else if (o.test(e)) { + t = (c = o.exec(e))[1] + c[2], (o = d).test(t) && (e = t) + }(i = R).test(e) && (t = (c = i.exec(e))[1], o = h, a = C, ((i = d).test(t) || o.test(t) && !a.test(t)) && (e = t)); + return o = d, (i = O).test(e) && o.test(e) && (i = w, e = e.replace(i, "")), "y" == r && (e = r.toLowerCase() + e.substr(1)), e + }, function(e) { + return e.update(r) + }), D.Pipeline.registerFunction(D.stemmer, "stemmer"), D.generateStopWordFilter = function(e) { + var t = e.reduce(function(e, t) { + return e[t] = t, e + }, {}); + return function(e) { + if (e && t[e.toString()] !== e.toString()) return e + } + }, D.stopWordFilter = D.generateStopWordFilter(["a", "able", "about", "across", "after", "all", "almost", "also", "am", "among", "an", "and", "any", "are", "as", "at", "be", "because", "been", "but", "by", "can", "cannot", "could", "dear", "did", "do", "does", "either", "else", "ever", "every", "for", "from", "get", "got", "had", "has", "have", "he", "her", "hers", "him", "his", "how", "however", "i", "if", "in", "into", "is", "it", "its", "just", "least", "let", "like", "likely", "may", "me", "might", "most", "must", "my", "neither", "no", "nor", "not", "of", "off", "often", "on", "only", "or", "other", "our", "own", "rather", "said", "say", "says", "she", "should", "since", "so", "some", "than", "that", "the", "their", "them", "then", "there", "these", "they", "this", "tis", "to", "too", "twas", "us", "wants", "was", "we", "were", "what", "when", "where", "which", "while", "who", "whom", "why", "will", "with", "would", "yet", "you", "your"]), D.Pipeline.registerFunction(D.stopWordFilter, "stopWordFilter"), D.trimmer = function(e) { + return e.update(function(e) { + return e.replace(/^\W+/, "").replace(/\W+$/, "") + }) + }, D.Pipeline.registerFunction(D.trimmer, "trimmer"), D.TokenSet = function() { + this.final = !1, this.edges = {}, this.id = D.TokenSet._nextId, D.TokenSet._nextId += 1 + }, D.TokenSet._nextId = 1, D.TokenSet.fromArray = function(e) { + for (var t = new D.TokenSet.Builder, n = 0, r = e.length; n < r; n++) t.insert(e[n]); + return t.finish(), t.root + }, D.TokenSet.fromClause = function(e) { + return "editDistance" in e ? D.TokenSet.fromFuzzyString(e.term, e.editDistance) : D.TokenSet.fromString(e.term) + }, D.TokenSet.fromFuzzyString = function(e, t) { + for (var n = new D.TokenSet, r = [{ + node: n, + editsRemaining: t, + str: e + }]; r.length;) { + var i = r.pop(); + if (0 < i.str.length) { + var o, a = i.str.charAt(0); + a in i.node.edges ? o = i.node.edges[a] : (o = new D.TokenSet, i.node.edges[a] = o), 1 == i.str.length && (o.final = !0), r.push({ + node: o, + editsRemaining: i.editsRemaining, + str: i.str.slice(1) + }) + } + if (0 != i.editsRemaining) { + if ("*" in i.node.edges) var s = i.node.edges["*"]; + else { + s = new D.TokenSet; + i.node.edges["*"] = s + } + if (0 == i.str.length && (s.final = !0), r.push({ + node: s, + editsRemaining: i.editsRemaining - 1, + str: i.str + }), 1 < i.str.length && r.push({ + node: i.node, + editsRemaining: i.editsRemaining - 1, + str: i.str.slice(1) + }), 1 == i.str.length && (i.node.final = !0), 1 <= i.str.length) { + if ("*" in i.node.edges) var c = i.node.edges["*"]; + else { + c = new D.TokenSet; + i.node.edges["*"] = c + } + 1 == i.str.length && (c.final = !0), r.push({ + node: c, + editsRemaining: i.editsRemaining - 1, + str: i.str.slice(1) + }) + } + if (1 < i.str.length) { + var l, u = i.str.charAt(0), + f = i.str.charAt(1); + f in i.node.edges ? l = i.node.edges[f] : (l = new D.TokenSet, i.node.edges[f] = l), 1 == i.str.length && (l.final = !0), r.push({ + node: l, + editsRemaining: i.editsRemaining - 1, + str: u + i.str.slice(2) + }) + } + } + } + return n + }, D.TokenSet.fromString = function(e) { + for (var t = new D.TokenSet, n = t, r = 0, i = e.length; r < i; r++) { + var o = e[r], + a = r == i - 1; + if ("*" == o)(t.edges[o] = t).final = a; + else { + var s = new D.TokenSet; + s.final = a, t.edges[o] = s, t = s + } + } + return n + }, D.TokenSet.prototype.toArray = function() { + for (var e = [], t = [{ + prefix: "", + node: this + }]; t.length;) { + var n = t.pop(), + r = Object.keys(n.node.edges), + i = r.length; + n.node.final && (n.prefix.charAt(0), e.push(n.prefix)); + for (var o = 0; o < i; o++) { + var a = r[o]; + t.push({ + prefix: n.prefix.concat(a), + node: n.node.edges[a] + }) + } + } + return e + }, D.TokenSet.prototype.toString = function() { + if (this._str) return this._str; + for (var e = this.final ? "1" : "0", t = Object.keys(this.edges).sort(), n = t.length, r = 0; r < n; r++) { + var i = t[r]; + e = e + i + this.edges[i].id + } + return e + }, D.TokenSet.prototype.intersect = function(e) { + for (var t = new D.TokenSet, n = void 0, r = [{ + qNode: e, + output: t, + node: this + }]; r.length;) { + n = r.pop(); + for (var i = Object.keys(n.qNode.edges), o = i.length, a = Object.keys(n.node.edges), s = a.length, c = 0; c < o; c++) + for (var l = i[c], u = 0; u < s; u++) { + var f = a[u]; + if (f == l || "*" == l) { + var d = n.node.edges[f], + h = n.qNode.edges[l], + p = d.final && h.final, + m = void 0; + f in n.output.edges ? (m = n.output.edges[f]).final = m.final || p : ((m = new D.TokenSet).final = p, n.output.edges[f] = m), r.push({ + qNode: h, + output: m, + node: d + }) + } + } + } + return t + }, D.TokenSet.Builder = function() { + this.previousWord = "", this.root = new D.TokenSet, this.uncheckedNodes = [], this.minimizedNodes = {} + }, D.TokenSet.Builder.prototype.insert = function(e) { + var t, n = 0; + if (e < this.previousWord) throw new Error("Out of order word insertion"); + for (var r = 0; r < e.length && r < this.previousWord.length && e[r] == this.previousWord[r]; r++) n++; + this.minimize(n), t = 0 == this.uncheckedNodes.length ? this.root : this.uncheckedNodes[this.uncheckedNodes.length - 1].child; + for (r = n; r < e.length; r++) { + var i = new D.TokenSet, + o = e[r]; + t.edges[o] = i, this.uncheckedNodes.push({ + parent: t, + char: o, + child: i + }), t = i + } + t.final = !0, this.previousWord = e + }, D.TokenSet.Builder.prototype.finish = function() { + this.minimize(0) + }, D.TokenSet.Builder.prototype.minimize = function(e) { + for (var t = this.uncheckedNodes.length - 1; e <= t; t--) { + var n = this.uncheckedNodes[t], + r = n.child.toString(); + r in this.minimizedNodes ? n.parent.edges[n.char] = this.minimizedNodes[r] : (n.child._str = r, this.minimizedNodes[r] = n.child), this.uncheckedNodes.pop() + } + }, D.Index = function(e) { + this.invertedIndex = e.invertedIndex, this.fieldVectors = e.fieldVectors, this.tokenSet = e.tokenSet, this.fields = e.fields, this.pipeline = e.pipeline + }, D.Index.prototype.search = function(t) { + return this.query(function(e) { + new D.QueryParser(t, e).parse() + }) + }, D.Index.prototype.query = function(e) { + for (var t = new D.Query(this.fields), n = Object.create(null), r = Object.create(null), i = Object.create(null), o = Object.create(null), a = Object.create(null), s = 0; s < this.fields.length; s++) r[this.fields[s]] = new D.Vector; + e.call(t, t); + for (s = 0; s < t.clauses.length; s++) { + var c = t.clauses[s], + l = null, + u = D.Set.complete; + l = c.usePipeline ? this.pipeline.runString(c.term, { + fields: c.fields + }) : [c.term]; + for (var f = 0; f < l.length; f++) { + var d = l[f]; + c.term = d; + var h = D.TokenSet.fromClause(c), + p = this.tokenSet.intersect(h).toArray(); + if (0 === p.length && c.presence === D.Query.presence.REQUIRED) { + for (var m = 0; m < c.fields.length; m++) { + o[Q = c.fields[m]] = D.Set.empty + } + break + } + for (var y = 0; y < p.length; y++) { + var v = p[y], + g = this.invertedIndex[v], + w = g._index; + for (m = 0; m < c.fields.length; m++) { + var _ = g[Q = c.fields[m]], + E = Object.keys(_), + x = v + "/" + Q, + b = new D.Set(E); + if (c.presence == D.Query.presence.REQUIRED && (u = u.union(b), void 0 === o[Q] && (o[Q] = D.Set.complete)), c.presence != D.Query.presence.PROHIBITED) { + if (r[Q].upsert(w, c.boost, function(e, t) { + return e + t + }), !i[x]) { + for (var k = 0; k < E.length; k++) { + var S, T = E[k], + L = new D.FieldRef(T, Q), + R = _[T]; + void 0 === (S = n[L]) ? n[L] = new D.MatchData(v, Q, R) : S.add(v, Q, R) + } + i[x] = !0 + } + } else void 0 === a[Q] && (a[Q] = D.Set.empty), a[Q] = a[Q].union(b) + } + } + } + if (c.presence === D.Query.presence.REQUIRED) + for (m = 0; m < c.fields.length; m++) { + o[Q = c.fields[m]] = o[Q].intersect(u) + } + } + var O = D.Set.complete, + C = D.Set.empty; + for (s = 0; s < this.fields.length; s++) { + var Q; + o[Q = this.fields[s]] && (O = O.intersect(o[Q])), a[Q] && (C = C.union(a[Q])) + } + var P = Object.keys(n), + A = [], + I = Object.create(null); + if (t.isNegated()) { + P = Object.keys(this.fieldVectors); + for (s = 0; s < P.length; s++) { + L = P[s]; + var M = D.FieldRef.fromString(L); + n[L] = new D.MatchData + } + } + for (s = 0; s < P.length; s++) { + var N = (M = D.FieldRef.fromString(P[s])).docRef; + if (O.contains(N) && !C.contains(N)) { + var j, F = this.fieldVectors[M], + H = r[M.fieldName].similarity(F); + if (void 0 !== (j = I[N])) j.score += H, j.matchData.combine(n[M]); + else { + var q = { + ref: N, + score: H, + matchData: n[M] + }; + I[N] = q, A.push(q) + } + } + } + return A.sort(function(e, t) { + return t.score - e.score + }) + }, D.Index.prototype.toJSON = function() { + var e = Object.keys(this.invertedIndex).sort().map(function(e) { + return [e, this.invertedIndex[e]] + }, this), + t = Object.keys(this.fieldVectors).map(function(e) { + return [e, this.fieldVectors[e].toJSON()] + }, this); + return { + version: D.version, + fields: this.fields, + fieldVectors: t, + invertedIndex: e, + pipeline: this.pipeline.toJSON() + } + }, D.Index.load = function(e) { + var t = {}, + n = {}, + r = e.fieldVectors, + i = Object.create(null), + o = e.invertedIndex, + a = new D.TokenSet.Builder, + s = D.Pipeline.load(e.pipeline); + e.version != D.version && D.utils.warn("Version mismatch when loading serialised index. Current version of lunr '" + D.version + "' does not match serialized index '" + e.version + "'"); + for (var c = 0; c < r.length; c++) { + var l = (f = r[c])[0], + u = f[1]; + n[l] = new D.Vector(u) + } + for (c = 0; c < o.length; c++) { + var f, d = (f = o[c])[0], + h = f[1]; + a.insert(d), i[d] = h + } + return a.finish(), t.fields = e.fields, t.fieldVectors = n, t.invertedIndex = i, t.tokenSet = a.root, t.pipeline = s, new D.Index(t) + }, D.Builder = function() { + this._ref = "id", this._fields = Object.create(null), this._documents = Object.create(null), this.invertedIndex = Object.create(null), this.fieldTermFrequencies = {}, this.fieldLengths = {}, this.tokenizer = D.tokenizer, this.pipeline = new D.Pipeline, this.searchPipeline = new D.Pipeline, this.documentCount = 0, this._b = .75, this._k1 = 1.2, this.termIndex = 0, this.metadataWhitelist = [] + }, D.Builder.prototype.ref = function(e) { + this._ref = e + }, D.Builder.prototype.field = function(e, t) { + if (/\//.test(e)) throw new RangeError("Field '" + e + "' contains illegal character '/'"); + this._fields[e] = t || {} + }, D.Builder.prototype.b = function(e) { + this._b = e < 0 ? 0 : 1 < e ? 1 : e + }, D.Builder.prototype.k1 = function(e) { + this._k1 = e + }, D.Builder.prototype.add = function(e, t) { + var n = e[this._ref], + r = Object.keys(this._fields); + this._documents[n] = t || {}, this.documentCount += 1; + for (var i = 0; i < r.length; i++) { + var o = r[i], + a = this._fields[o].extractor, + s = a ? a(e) : e[o], + c = this.tokenizer(s, { + fields: [o] + }), + l = this.pipeline.run(c), + u = new D.FieldRef(n, o), + f = Object.create(null); + this.fieldTermFrequencies[u] = f, this.fieldLengths[u] = 0, this.fieldLengths[u] += l.length; + for (var d = 0; d < l.length; d++) { + var h = l[d]; + if (null == f[h] && (f[h] = 0), f[h] += 1, null == this.invertedIndex[h]) { + var p = Object.create(null); + p._index = this.termIndex, this.termIndex += 1; + for (var m = 0; m < r.length; m++) p[r[m]] = Object.create(null); + this.invertedIndex[h] = p + } + null == this.invertedIndex[h][o][n] && (this.invertedIndex[h][o][n] = Object.create(null)); + for (var y = 0; y < this.metadataWhitelist.length; y++) { + var v = this.metadataWhitelist[y], + g = h.metadata[v]; + null == this.invertedIndex[h][o][n][v] && (this.invertedIndex[h][o][n][v] = []), this.invertedIndex[h][o][n][v].push(g) + } + } + } + }, D.Builder.prototype.calculateAverageFieldLengths = function() { + for (var e = Object.keys(this.fieldLengths), t = e.length, n = {}, r = {}, i = 0; i < t; i++) { + var o = D.FieldRef.fromString(e[i]), + a = o.fieldName; + r[a] || (r[a] = 0), r[a] += 1, n[a] || (n[a] = 0), n[a] += this.fieldLengths[o] + } + var s = Object.keys(this._fields); + for (i = 0; i < s.length; i++) { + var c = s[i]; + n[c] = n[c] / r[c] + } + this.averageFieldLength = n + }, D.Builder.prototype.createFieldVectors = function() { + for (var e = {}, t = Object.keys(this.fieldTermFrequencies), n = t.length, r = Object.create(null), i = 0; i < n; i++) { + for (var o = D.FieldRef.fromString(t[i]), a = o.fieldName, s = this.fieldLengths[o], c = new D.Vector, l = this.fieldTermFrequencies[o], u = Object.keys(l), f = u.length, d = this._fields[a].boost || 1, h = this._documents[o.docRef].boost || 1, p = 0; p < f; p++) { + var m, y, v, g = u[p], + w = l[g], + _ = this.invertedIndex[g]._index; + void 0 === r[g] ? (m = D.idf(this.invertedIndex[g], this.documentCount), r[g] = m) : m = r[g], y = m * ((this._k1 + 1) * w) / (this._k1 * (1 - this._b + this._b * (s / this.averageFieldLength[a])) + w), y *= d, y *= h, v = Math.round(1e3 * y) / 1e3, c.insert(_, v) + } + e[o] = c + } + this.fieldVectors = e + }, D.Builder.prototype.createTokenSet = function() { + this.tokenSet = D.TokenSet.fromArray(Object.keys(this.invertedIndex).sort()) + }, D.Builder.prototype.build = function() { + return this.calculateAverageFieldLengths(), this.createFieldVectors(), this.createTokenSet(), new D.Index({ + invertedIndex: this.invertedIndex, + fieldVectors: this.fieldVectors, + tokenSet: this.tokenSet, + fields: Object.keys(this._fields), + pipeline: this.searchPipeline + }) + }, D.Builder.prototype.use = function(e) { + var t = Array.prototype.slice.call(arguments, 1); + t.unshift(this), e.apply(this, t) + }, D.MatchData = function(e, t, n) { + for (var r = Object.create(null), i = Object.keys(n || {}), o = 0; o < i.length; o++) { + var a = i[o]; + r[a] = n[a].slice() + } + this.metadata = Object.create(null), void 0 !== e && (this.metadata[e] = Object.create(null), this.metadata[e][t] = r) + }, D.MatchData.prototype.combine = function(e) { + for (var t = Object.keys(e.metadata), n = 0; n < t.length; n++) { + var r = t[n], + i = Object.keys(e.metadata[r]); + null == this.metadata[r] && (this.metadata[r] = Object.create(null)); + for (var o = 0; o < i.length; o++) { + var a = i[o], + s = Object.keys(e.metadata[r][a]); + null == this.metadata[r][a] && (this.metadata[r][a] = Object.create(null)); + for (var c = 0; c < s.length; c++) { + var l = s[c]; + null == this.metadata[r][a][l] ? this.metadata[r][a][l] = e.metadata[r][a][l] : this.metadata[r][a][l] = this.metadata[r][a][l].concat(e.metadata[r][a][l]) + } + } + } + }, D.MatchData.prototype.add = function(e, t, n) { + if (!(e in this.metadata)) return this.metadata[e] = Object.create(null), void(this.metadata[e][t] = n); + if (t in this.metadata[e]) + for (var r = Object.keys(n), i = 0; i < r.length; i++) { + var o = r[i]; + o in this.metadata[e][t] ? this.metadata[e][t][o] = this.metadata[e][t][o].concat(n[o]) : this.metadata[e][t][o] = n[o] + } else this.metadata[e][t] = n + }, D.Query = function(e) { + this.clauses = [], this.allFields = e + }, D.Query.wildcard = new String("*"), D.Query.wildcard.NONE = 0, D.Query.wildcard.LEADING = 1, D.Query.wildcard.TRAILING = 2, D.Query.presence = { + OPTIONAL: 1, + REQUIRED: 2, + PROHIBITED: 3 + }, D.Query.prototype.clause = function(e) { + return "fields" in e || (e.fields = this.allFields), "boost" in e || (e.boost = 1), "usePipeline" in e || (e.usePipeline = !0), "wildcard" in e || (e.wildcard = D.Query.wildcard.NONE), e.wildcard & D.Query.wildcard.LEADING && e.term.charAt(0) != D.Query.wildcard && (e.term = "*" + e.term), e.wildcard & D.Query.wildcard.TRAILING && e.term.slice(-1) != D.Query.wildcard && (e.term = e.term + "*"), "presence" in e || (e.presence = D.Query.presence.OPTIONAL), this.clauses.push(e), this + }, D.Query.prototype.isNegated = function() { + for (var e = 0; e < this.clauses.length; e++) + if (this.clauses[e].presence != D.Query.presence.PROHIBITED) return !1; + return !0 + }, D.Query.prototype.term = function(e, t) { + if (Array.isArray(e)) return e.forEach(function(e) { + this.term(e, D.utils.clone(t)) + }, this), this; + var n = t || {}; + return n.term = e.toString(), this.clause(n), this + }, D.QueryParseError = function(e, t, n) { + this.name = "QueryParseError", this.message = e, this.start = t, this.end = n + }, D.QueryParseError.prototype = new Error, D.QueryLexer = function(e) { + this.lexemes = [], this.str = e, this.length = e.length, this.pos = 0, this.start = 0, this.escapeCharPositions = [] + }, D.QueryLexer.prototype.run = function() { + for (var e = D.QueryLexer.lexText; e;) e = e(this) + }, D.QueryLexer.prototype.sliceString = function() { + for (var e = [], t = this.start, n = this.pos, r = 0; r < this.escapeCharPositions.length; r++) n = this.escapeCharPositions[r], e.push(this.str.slice(t, n)), t = n + 1; + return e.push(this.str.slice(t, this.pos)), this.escapeCharPositions.length = 0, e.join("") + }, D.QueryLexer.prototype.emit = function(e) { + this.lexemes.push({ + type: e, + str: this.sliceString(), + start: this.start, + end: this.pos + }), this.start = this.pos + }, D.QueryLexer.prototype.escapeCharacter = function() { + this.escapeCharPositions.push(this.pos - 1), this.pos += 1 + }, D.QueryLexer.prototype.next = function() { + if (this.pos >= this.length) return D.QueryLexer.EOS; + var e = this.str.charAt(this.pos); + return this.pos += 1, e + }, D.QueryLexer.prototype.width = function() { + return this.pos - this.start + }, D.QueryLexer.prototype.ignore = function() { + this.start == this.pos && (this.pos += 1), this.start = this.pos + }, D.QueryLexer.prototype.backup = function() { + this.pos -= 1 + }, D.QueryLexer.prototype.acceptDigitRun = function() { + for (var e, t; 47 < (t = (e = this.next()).charCodeAt(0)) && t < 58;); + e != D.QueryLexer.EOS && this.backup() + }, D.QueryLexer.prototype.more = function() { + return this.pos < this.length + }, D.QueryLexer.EOS = "EOS", D.QueryLexer.FIELD = "FIELD", D.QueryLexer.TERM = "TERM", D.QueryLexer.EDIT_DISTANCE = "EDIT_DISTANCE", D.QueryLexer.BOOST = "BOOST", D.QueryLexer.PRESENCE = "PRESENCE", D.QueryLexer.lexField = function(e) { + return e.backup(), e.emit(D.QueryLexer.FIELD), e.ignore(), D.QueryLexer.lexText + }, D.QueryLexer.lexTerm = function(e) { + if (1 < e.width() && (e.backup(), e.emit(D.QueryLexer.TERM)), e.ignore(), e.more()) return D.QueryLexer.lexText + }, D.QueryLexer.lexEditDistance = function(e) { + return e.ignore(), e.acceptDigitRun(), e.emit(D.QueryLexer.EDIT_DISTANCE), D.QueryLexer.lexText + }, D.QueryLexer.lexBoost = function(e) { + return e.ignore(), e.acceptDigitRun(), e.emit(D.QueryLexer.BOOST), D.QueryLexer.lexText + }, D.QueryLexer.lexEOS = function(e) { + 0 < e.width() && e.emit(D.QueryLexer.TERM) + }, D.QueryLexer.termSeparator = D.tokenizer.separator, D.QueryLexer.lexText = function(e) { + for (;;) { + var t = e.next(); + if (t == D.QueryLexer.EOS) return D.QueryLexer.lexEOS; + if (92 != t.charCodeAt(0)) { + if (":" == t) return D.QueryLexer.lexField; + if ("~" == t) return e.backup(), 0 < e.width() && e.emit(D.QueryLexer.TERM), D.QueryLexer.lexEditDistance; + if ("^" == t) return e.backup(), 0 < e.width() && e.emit(D.QueryLexer.TERM), D.QueryLexer.lexBoost; + if ("+" == t && 1 === e.width()) return e.emit(D.QueryLexer.PRESENCE), D.QueryLexer.lexText; + if ("-" == t && 1 === e.width()) return e.emit(D.QueryLexer.PRESENCE), D.QueryLexer.lexText; + if (t.match(D.QueryLexer.termSeparator)) return D.QueryLexer.lexTerm + } else e.escapeCharacter() + } + }, D.QueryParser = function(e, t) { + this.lexer = new D.QueryLexer(e), this.query = t, this.currentClause = {}, this.lexemeIdx = 0 + }, D.QueryParser.prototype.parse = function() { + this.lexer.run(), this.lexemes = this.lexer.lexemes; + for (var e = D.QueryParser.parseClause; e;) e = e(this); + return this.query + }, D.QueryParser.prototype.peekLexeme = function() { + return this.lexemes[this.lexemeIdx] + }, D.QueryParser.prototype.consumeLexeme = function() { + var e = this.peekLexeme(); + return this.lexemeIdx += 1, e + }, D.QueryParser.prototype.nextClause = function() { + var e = this.currentClause; + this.query.clause(e), this.currentClause = {} + }, D.QueryParser.parseClause = function(e) { + var t = e.peekLexeme(); + if (null != t) switch (t.type) { + case D.QueryLexer.PRESENCE: + return D.QueryParser.parsePresence; + case D.QueryLexer.FIELD: + return D.QueryParser.parseField; + case D.QueryLexer.TERM: + return D.QueryParser.parseTerm; + default: + var n = "expected either a field or a term, found " + t.type; + throw 1 <= t.str.length && (n += " with value '" + t.str + "'"), new D.QueryParseError(n, t.start, t.end) + } + }, D.QueryParser.parsePresence = function(e) { + var t = e.consumeLexeme(); + if (null != t) { + switch (t.str) { + case "-": + e.currentClause.presence = D.Query.presence.PROHIBITED; + break; + case "+": + e.currentClause.presence = D.Query.presence.REQUIRED; + break; + default: + var n = "unrecognised presence operator'" + t.str + "'"; + throw new D.QueryParseError(n, t.start, t.end) + } + var r = e.peekLexeme(); + if (null == r) { + n = "expecting term or field, found nothing"; + throw new D.QueryParseError(n, t.start, t.end) + } + switch (r.type) { + case D.QueryLexer.FIELD: + return D.QueryParser.parseField; + case D.QueryLexer.TERM: + return D.QueryParser.parseTerm; + default: + n = "expecting term or field, found '" + r.type + "'"; + throw new D.QueryParseError(n, r.start, r.end) + } + } + }, D.QueryParser.parseField = function(e) { + var t = e.consumeLexeme(); + if (null != t) { + if (-1 == e.query.allFields.indexOf(t.str)) { + var n = e.query.allFields.map(function(e) { + return "'" + e + "'" + }).join(", "), + r = "unrecognised field '" + t.str + "', possible fields: " + n; + throw new D.QueryParseError(r, t.start, t.end) + } + e.currentClause.fields = [t.str]; + var i = e.peekLexeme(); + if (null == i) { + r = "expecting term, found nothing"; + throw new D.QueryParseError(r, t.start, t.end) + } + switch (i.type) { + case D.QueryLexer.TERM: + return D.QueryParser.parseTerm; + default: + r = "expecting term, found '" + i.type + "'"; + throw new D.QueryParseError(r, i.start, i.end) + } + } + }, D.QueryParser.parseTerm = function(e) { + var t = e.consumeLexeme(); + if (null != t) { + e.currentClause.term = t.str.toLowerCase(), -1 != t.str.indexOf("*") && (e.currentClause.usePipeline = !1); + var n = e.peekLexeme(); + if (null != n) switch (n.type) { + case D.QueryLexer.TERM: + return e.nextClause(), D.QueryParser.parseTerm; + case D.QueryLexer.FIELD: + return e.nextClause(), D.QueryParser.parseField; + case D.QueryLexer.EDIT_DISTANCE: + return D.QueryParser.parseEditDistance; + case D.QueryLexer.BOOST: + return D.QueryParser.parseBoost; + case D.QueryLexer.PRESENCE: + return e.nextClause(), D.QueryParser.parsePresence; + default: + var r = "Unexpected lexeme type '" + n.type + "'"; + throw new D.QueryParseError(r, n.start, n.end) + } else e.nextClause() + } + }, D.QueryParser.parseEditDistance = function(e) { + var t = e.consumeLexeme(); + if (null != t) { + var n = parseInt(t.str, 10); + if (isNaN(n)) { + var r = "edit distance must be numeric"; + throw new D.QueryParseError(r, t.start, t.end) + } + e.currentClause.editDistance = n; + var i = e.peekLexeme(); + if (null != i) switch (i.type) { + case D.QueryLexer.TERM: + return e.nextClause(), D.QueryParser.parseTerm; + case D.QueryLexer.FIELD: + return e.nextClause(), D.QueryParser.parseField; + case D.QueryLexer.EDIT_DISTANCE: + return D.QueryParser.parseEditDistance; + case D.QueryLexer.BOOST: + return D.QueryParser.parseBoost; + case D.QueryLexer.PRESENCE: + return e.nextClause(), D.QueryParser.parsePresence; + default: + r = "Unexpected lexeme type '" + i.type + "'"; + throw new D.QueryParseError(r, i.start, i.end) + } else e.nextClause() + } + }, D.QueryParser.parseBoost = function(e) { + var t = e.consumeLexeme(); + if (null != t) { + var n = parseInt(t.str, 10); + if (isNaN(n)) { + var r = "boost must be numeric"; + throw new D.QueryParseError(r, t.start, t.end) + } + e.currentClause.boost = n; + var i = e.peekLexeme(); + if (null != i) switch (i.type) { + case D.QueryLexer.TERM: + return e.nextClause(), D.QueryParser.parseTerm; + case D.QueryLexer.FIELD: + return e.nextClause(), D.QueryParser.parseField; + case D.QueryLexer.EDIT_DISTANCE: + return D.QueryParser.parseEditDistance; + case D.QueryLexer.BOOST: + return D.QueryParser.parseBoost; + case D.QueryLexer.PRESENCE: + return e.nextClause(), D.QueryParser.parsePresence; + default: + r = "Unexpected lexeme type '" + i.type + "'"; + throw new D.QueryParseError(r, i.start, i.end) + } else e.nextClause() + } + }, void 0 === (c = "function" == typeof(s = function() { + return D + }) ? s.call(o, a, o, i) : s) || (i.exports = c) + }() +}])); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.da.js b/latest/_static/javascripts/lunr/lunr.da.js new file mode 100644 index 000000000..34910dfe5 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.da.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,m,i;e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=(r=e.stemmerSupport.Among,m=e.stemmerSupport.SnowballProgram,i=new function(){var i,t,n,s=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],o=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],u=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],c=new m;function l(){var e,r=c.limit-c.cursor;c.cursor>=t&&(e=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,c.find_among_b(o,4)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e)}this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var e,r=c.cursor;return function(){var e,r=c.cursor+3;if(t=c.limit,0<=r&&r<=c.limit){for(i=r;;){if(e=c.cursor,c.in_grouping(d,97,248)){c.cursor=e;break}if((c.cursor=e)>=c.limit)return;c.cursor++}for(;!c.out_grouping(d,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(t=c.cursor)=t&&(r=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,e=c.find_among_b(s,32),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:c.in_grouping_b(u,97,229)&&c.slice_del()}}(),c.cursor=c.limit,l(),c.cursor=c.limit,function(){var e,r,i,n=c.limit-c.cursor;if(c.ket=c.cursor,c.eq_s_b(2,"st")&&(c.bra=c.cursor,c.eq_s_b(2,"ig")&&c.slice_del()),c.cursor=c.limit-n,c.cursor>=t&&(r=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,e=c.find_among_b(a,5),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del(),i=c.limit-c.cursor,l(),c.cursor=c.limit-i;break;case 2:c.slice_from("løs")}}(),c.cursor=c.limit,c.cursor>=t&&(e=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,c.out_grouping_b(d,97,248)?(c.bra=c.cursor,n=c.slice_to(n),c.limit_backward=e,c.eq_v_b(n)&&c.slice_del()):c.limit_backward=e),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.de.js b/latest/_static/javascripts/lunr/lunr.de.js new file mode 100644 index 000000000..1529892c8 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.de.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var _,p,r;e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=(_=e.stemmerSupport.Among,p=e.stemmerSupport.SnowballProgram,r=new function(){var r,n,i,s=[new _("",-1,6),new _("U",0,2),new _("Y",0,1),new _("ä",0,3),new _("ö",0,4),new _("ü",0,5)],o=[new _("e",-1,2),new _("em",-1,1),new _("en",-1,2),new _("ern",-1,1),new _("er",-1,1),new _("s",-1,3),new _("es",5,2)],c=[new _("en",-1,1),new _("er",-1,1),new _("st",-1,2),new _("est",2,1)],u=[new _("ig",-1,1),new _("lich",-1,1)],a=[new _("end",-1,1),new _("ig",-1,2),new _("ung",-1,1),new _("lich",-1,3),new _("isch",-1,2),new _("ik",-1,2),new _("heit",-1,3),new _("keit",-1,4)],t=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],d=[117,30,5],l=[117,30,4],m=new p;function h(e,r,n){return!(!m.eq_s(1,e)||(m.ket=m.cursor,!m.in_grouping(t,97,252)))&&(m.slice_from(r),m.cursor=n,!0)}function w(){for(;!m.in_grouping(t,97,252);){if(m.cursor>=m.limit)return!0;m.cursor++}for(;!m.out_grouping(t,97,252);){if(m.cursor>=m.limit)return!0;m.cursor++}return!1}function f(){return i<=m.cursor}function b(){return n<=m.cursor}this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var e=m.cursor;return function(){for(var e,r,n,i,s=m.cursor;;)if(e=m.cursor,m.bra=e,m.eq_s(1,"ß"))m.ket=m.cursor,m.slice_from("ss");else{if(e>=m.limit)break;m.cursor=e+1}for(m.cursor=s;;)for(r=m.cursor;;){if(n=m.cursor,m.in_grouping(t,97,252)){if(i=m.cursor,m.bra=i,h("u","U",n))break;if(m.cursor=i,h("y","Y",n))break}if(n>=m.limit)return m.cursor=r;m.cursor=n+1}}(),m.cursor=e,function(){i=m.limit,n=i;var e=m.cursor+3;0<=e&&e<=m.limit&&(r=e,w()||((i=m.cursor)=m.limit)return;m.cursor++}}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.du.js b/latest/_static/javascripts/lunr/lunr.du.js new file mode 100644 index 000000000..52632004a --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.du.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var v,q,r;console.warn('[Lunr Languages] Please use the "nl" instead of the "du". The "nl" code is the standard code for Dutch language, and "du" will be removed in the next major versions.'),e.du=function(){this.pipeline.reset(),this.pipeline.add(e.du.trimmer,e.du.stopWordFilter,e.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.du.stemmer))},e.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.du.trimmer=e.trimmerSupport.generateTrimmer(e.du.wordCharacters),e.Pipeline.registerFunction(e.du.trimmer,"trimmer-du"),e.du.stemmer=(v=e.stemmerSupport.Among,q=e.stemmerSupport.SnowballProgram,r=new function(){var r,i,u,o=[new v("",-1,6),new v("á",0,1),new v("ä",0,1),new v("é",0,2),new v("ë",0,2),new v("í",0,3),new v("ï",0,3),new v("ó",0,4),new v("ö",0,4),new v("ú",0,5),new v("ü",0,5)],n=[new v("",-1,3),new v("I",0,2),new v("Y",0,1)],t=[new v("dd",-1,-1),new v("kk",-1,-1),new v("tt",-1,-1)],c=[new v("ene",-1,2),new v("se",-1,3),new v("en",-1,2),new v("heden",2,1),new v("s",-1,3)],a=[new v("end",-1,1),new v("ig",-1,2),new v("ing",-1,1),new v("lijk",-1,3),new v("baar",-1,4),new v("bar",-1,5)],l=[new v("aa",-1,-1),new v("ee",-1,-1),new v("oo",-1,-1),new v("uu",-1,-1)],m=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],d=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],f=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],_=new q;function s(e){return(_.cursor=e)>=_.limit||(_.cursor++,!1)}function w(){for(;!_.in_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}for(;!_.out_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}return!1}function b(){return i<=_.cursor}function p(){return r<=_.cursor}function g(){var e=_.limit-_.cursor;_.find_among_b(t,3)&&(_.cursor=_.limit-e,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del()))}function h(){var e;u=!1,_.ket=_.cursor,_.eq_s_b(1,"e")&&(_.bra=_.cursor,b()&&(e=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-e,_.slice_del(),u=!0,g())))}function k(){var e;b()&&(e=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-e,_.eq_s_b(3,"gem")||(_.cursor=_.limit-e,_.slice_del(),g())))}this.setCurrent=function(e){_.setCurrent(e)},this.getCurrent=function(){return _.getCurrent()},this.stem=function(){var e=_.cursor;return function(){for(var e,r,i,n=_.cursor;;){if(_.bra=_.cursor,e=_.find_among(o,11))switch(_.ket=_.cursor,e){case 1:_.slice_from("a");continue;case 2:_.slice_from("e");continue;case 3:_.slice_from("i");continue;case 4:_.slice_from("o");continue;case 5:_.slice_from("u");continue;case 6:if(_.cursor>=_.limit)break;_.cursor++;continue}break}for(_.cursor=n,_.bra=n,_.eq_s(1,"y")?(_.ket=_.cursor,_.slice_from("Y")):_.cursor=n;;)if(r=_.cursor,_.in_grouping(m,97,232)){if(i=_.cursor,_.bra=i,_.eq_s(1,"i"))_.ket=_.cursor,_.in_grouping(m,97,232)&&(_.slice_from("I"),_.cursor=r);else if(_.cursor=i,_.eq_s(1,"y"))_.ket=_.cursor,_.slice_from("Y"),_.cursor=r;else if(s(r))break}else if(s(r))break}(),_.cursor=e,i=_.limit,r=i,w()||((i=_.cursor)<3&&(i=3),w()||(r=_.cursor)),_.limit_backward=e,_.cursor=_.limit,function(){var e,r,i,n,o,t,s=_.limit-_.cursor;if(_.ket=_.cursor,e=_.find_among_b(c,5))switch(_.bra=_.cursor,e){case 1:b()&&_.slice_from("heid");break;case 2:k();break;case 3:b()&&_.out_grouping_b(f,97,232)&&_.slice_del()}if(_.cursor=_.limit-s,h(),_.cursor=_.limit-s,_.ket=_.cursor,_.eq_s_b(4,"heid")&&(_.bra=_.cursor,p()&&(r=_.limit-_.cursor,_.eq_s_b(1,"c")||(_.cursor=_.limit-r,_.slice_del(),_.ket=_.cursor,_.eq_s_b(2,"en")&&(_.bra=_.cursor,k())))),_.cursor=_.limit-s,_.ket=_.cursor,e=_.find_among_b(a,6))switch(_.bra=_.cursor,e){case 1:if(p()){if(_.slice_del(),i=_.limit-_.cursor,_.ket=_.cursor,_.eq_s_b(2,"ig")&&(_.bra=_.cursor,p()&&(n=_.limit-_.cursor,!_.eq_s_b(1,"e")))){_.cursor=_.limit-n,_.slice_del();break}_.cursor=_.limit-i,g()}break;case 2:p()&&(o=_.limit-_.cursor,_.eq_s_b(1,"e")||(_.cursor=_.limit-o,_.slice_del()));break;case 3:p()&&(_.slice_del(),h());break;case 4:p()&&_.slice_del();break;case 5:p()&&u&&_.slice_del()}_.cursor=_.limit-s,_.out_grouping_b(d,73,232)&&(t=_.limit-_.cursor,_.find_among_b(l,4)&&_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-t,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del())))}(),_.cursor=_.limit_backward,function(){for(var e;;)if(_.bra=_.cursor,e=_.find_among(n,3))switch(_.ket=_.cursor,e){case 1:_.slice_from("y");break;case 2:_.slice_from("i");break;case 3:if(_.cursor>=_.limit)return;_.cursor++}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.du.stemmer,"stemmer-du"),e.du.stopWordFilter=e.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),e.Pipeline.registerFunction(e.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.es.js b/latest/_static/javascripts/lunr/lunr.es.js new file mode 100644 index 000000000..9de6c09cb --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.es.js @@ -0,0 +1 @@ +!function(e,s){"function"==typeof define&&define.amd?define(s):"object"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var C,P,s;e.es=function(){this.pipeline.reset(),this.pipeline.add(e.es.trimmer,e.es.stopWordFilter,e.es.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.es.stemmer))},e.es.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.es.trimmer=e.trimmerSupport.generateTrimmer(e.es.wordCharacters),e.Pipeline.registerFunction(e.es.trimmer,"trimmer-es"),e.es.stemmer=(C=e.stemmerSupport.Among,P=e.stemmerSupport.SnowballProgram,s=new function(){var r,n,i,a=[new C("",-1,6),new C("á",0,1),new C("é",0,2),new C("í",0,3),new C("ó",0,4),new C("ú",0,5)],t=[new C("la",-1,-1),new C("sela",0,-1),new C("le",-1,-1),new C("me",-1,-1),new C("se",-1,-1),new C("lo",-1,-1),new C("selo",5,-1),new C("las",-1,-1),new C("selas",7,-1),new C("les",-1,-1),new C("los",-1,-1),new C("selos",10,-1),new C("nos",-1,-1)],o=[new C("ando",-1,6),new C("iendo",-1,6),new C("yendo",-1,7),new C("ándo",-1,2),new C("iéndo",-1,1),new C("ar",-1,6),new C("er",-1,6),new C("ir",-1,6),new C("ár",-1,3),new C("ér",-1,4),new C("ír",-1,5)],s=[new C("ic",-1,-1),new C("ad",-1,-1),new C("os",-1,-1),new C("iv",-1,1)],u=[new C("able",-1,1),new C("ible",-1,1),new C("ante",-1,1)],w=[new C("ic",-1,1),new C("abil",-1,1),new C("iv",-1,1)],c=[new C("ica",-1,1),new C("ancia",-1,2),new C("encia",-1,5),new C("adora",-1,2),new C("osa",-1,1),new C("ista",-1,1),new C("iva",-1,9),new C("anza",-1,1),new C("logía",-1,3),new C("idad",-1,8),new C("able",-1,1),new C("ible",-1,1),new C("ante",-1,2),new C("mente",-1,7),new C("amente",13,6),new C("ación",-1,2),new C("ución",-1,4),new C("ico",-1,1),new C("ismo",-1,1),new C("oso",-1,1),new C("amiento",-1,1),new C("imiento",-1,1),new C("ivo",-1,9),new C("ador",-1,2),new C("icas",-1,1),new C("ancias",-1,2),new C("encias",-1,5),new C("adoras",-1,2),new C("osas",-1,1),new C("istas",-1,1),new C("ivas",-1,9),new C("anzas",-1,1),new C("logías",-1,3),new C("idades",-1,8),new C("ables",-1,1),new C("ibles",-1,1),new C("aciones",-1,2),new C("uciones",-1,4),new C("adores",-1,2),new C("antes",-1,2),new C("icos",-1,1),new C("ismos",-1,1),new C("osos",-1,1),new C("amientos",-1,1),new C("imientos",-1,1),new C("ivos",-1,9)],m=[new C("ya",-1,1),new C("ye",-1,1),new C("yan",-1,1),new C("yen",-1,1),new C("yeron",-1,1),new C("yendo",-1,1),new C("yo",-1,1),new C("yas",-1,1),new C("yes",-1,1),new C("yais",-1,1),new C("yamos",-1,1),new C("yó",-1,1)],l=[new C("aba",-1,2),new C("ada",-1,2),new C("ida",-1,2),new C("ara",-1,2),new C("iera",-1,2),new C("ía",-1,2),new C("aría",5,2),new C("ería",5,2),new C("iría",5,2),new C("ad",-1,2),new C("ed",-1,2),new C("id",-1,2),new C("ase",-1,2),new C("iese",-1,2),new C("aste",-1,2),new C("iste",-1,2),new C("an",-1,2),new C("aban",16,2),new C("aran",16,2),new C("ieran",16,2),new C("ían",16,2),new C("arían",20,2),new C("erían",20,2),new C("irían",20,2),new C("en",-1,1),new C("asen",24,2),new C("iesen",24,2),new C("aron",-1,2),new C("ieron",-1,2),new C("arán",-1,2),new C("erán",-1,2),new C("irán",-1,2),new C("ado",-1,2),new C("ido",-1,2),new C("ando",-1,2),new C("iendo",-1,2),new C("ar",-1,2),new C("er",-1,2),new C("ir",-1,2),new C("as",-1,2),new C("abas",39,2),new C("adas",39,2),new C("idas",39,2),new C("aras",39,2),new C("ieras",39,2),new C("ías",39,2),new C("arías",45,2),new C("erías",45,2),new C("irías",45,2),new C("es",-1,1),new C("ases",49,2),new C("ieses",49,2),new C("abais",-1,2),new C("arais",-1,2),new C("ierais",-1,2),new C("íais",-1,2),new C("aríais",55,2),new C("eríais",55,2),new C("iríais",55,2),new C("aseis",-1,2),new C("ieseis",-1,2),new C("asteis",-1,2),new C("isteis",-1,2),new C("áis",-1,2),new C("éis",-1,1),new C("aréis",64,2),new C("eréis",64,2),new C("iréis",64,2),new C("ados",-1,2),new C("idos",-1,2),new C("amos",-1,2),new C("ábamos",70,2),new C("áramos",70,2),new C("iéramos",70,2),new C("íamos",70,2),new C("aríamos",74,2),new C("eríamos",74,2),new C("iríamos",74,2),new C("emos",-1,1),new C("aremos",78,2),new C("eremos",78,2),new C("iremos",78,2),new C("ásemos",78,2),new C("iésemos",78,2),new C("imos",-1,2),new C("arás",-1,2),new C("erás",-1,2),new C("irás",-1,2),new C("ís",-1,2),new C("ará",-1,2),new C("erá",-1,2),new C("irá",-1,2),new C("aré",-1,2),new C("eré",-1,2),new C("iré",-1,2),new C("ió",-1,2)],d=[new C("a",-1,1),new C("e",-1,2),new C("o",-1,1),new C("os",-1,1),new C("á",-1,1),new C("é",-1,2),new C("í",-1,1),new C("ó",-1,1)],b=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],f=new P;function _(){if(f.out_grouping(b,97,252)){for(;!f.in_grouping(b,97,252);){if(f.cursor>=f.limit)return!0;f.cursor++}return!1}return!0}function h(){var e,s=f.cursor;if(function(){if(f.in_grouping(b,97,252)){var e=f.cursor;if(_()){if(f.cursor=e,!f.in_grouping(b,97,252))return!0;for(;!f.out_grouping(b,97,252);){if(f.cursor>=f.limit)return!0;f.cursor++}}return!1}return!0}()){if(f.cursor=s,!f.out_grouping(b,97,252))return;if(e=f.cursor,_()){if(f.cursor=e,!f.in_grouping(b,97,252)||f.cursor>=f.limit)return;f.cursor++}}i=f.cursor}function v(){for(;!f.in_grouping(b,97,252);){if(f.cursor>=f.limit)return!1;f.cursor++}for(;!f.out_grouping(b,97,252);){if(f.cursor>=f.limit)return!1;f.cursor++}return!0}function p(){return i<=f.cursor}function g(){return r<=f.cursor}function k(e,s){if(!g())return!0;f.slice_del(),f.ket=f.cursor;var r=f.find_among_b(e,s);return r&&(f.bra=f.cursor,1==r&&g()&&f.slice_del()),!1}function y(e){return!g()||(f.slice_del(),f.ket=f.cursor,f.eq_s_b(2,e)&&(f.bra=f.cursor,g()&&f.slice_del()),!1)}function q(){var e;if(f.ket=f.cursor,e=f.find_among_b(c,46)){switch(f.bra=f.cursor,e){case 1:if(!g())return!1;f.slice_del();break;case 2:if(y("ic"))return!1;break;case 3:if(!g())return!1;f.slice_from("log");break;case 4:if(!g())return!1;f.slice_from("u");break;case 5:if(!g())return!1;f.slice_from("ente");break;case 6:if(!(n<=f.cursor))return!1;f.slice_del(),f.ket=f.cursor,(e=f.find_among_b(s,4))&&(f.bra=f.cursor,g()&&(f.slice_del(),1==e&&(f.ket=f.cursor,f.eq_s_b(2,"at")&&(f.bra=f.cursor,g()&&f.slice_del()))));break;case 7:if(k(u,3))return!1;break;case 8:if(k(w,3))return!1;break;case 9:if(y("at"))return!1}return!0}return!1}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e,s=f.cursor;return e=f.cursor,i=f.limit,r=n=i,h(),f.cursor=e,v()&&(n=f.cursor,v()&&(r=f.cursor)),f.limit_backward=s,f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,f.find_among_b(t,13)&&(f.bra=f.cursor,(e=f.find_among_b(o,11))&&p()))switch(e){case 1:f.bra=f.cursor,f.slice_from("iendo");break;case 2:f.bra=f.cursor,f.slice_from("ando");break;case 3:f.bra=f.cursor,f.slice_from("ar");break;case 4:f.bra=f.cursor,f.slice_from("er");break;case 5:f.bra=f.cursor,f.slice_from("ir");break;case 6:f.slice_del();break;case 7:f.eq_s_b(1,"u")&&f.slice_del()}}(),f.cursor=f.limit,q()||(f.cursor=f.limit,function(){var e,s;if(f.cursor>=i&&(s=f.limit_backward,f.limit_backward=i,f.ket=f.cursor,e=f.find_among_b(m,12),f.limit_backward=s,e)){if(f.bra=f.cursor,1==e){if(!f.eq_s_b(1,"u"))return!1;f.slice_del()}return!0}return!1}()||(f.cursor=f.limit,function(){var e,s,r,n;if(f.cursor>=i&&(s=f.limit_backward,f.limit_backward=i,f.ket=f.cursor,e=f.find_among_b(l,96),f.limit_backward=s,e))switch(f.bra=f.cursor,e){case 1:r=f.limit-f.cursor,f.eq_s_b(1,"u")?(n=f.limit-f.cursor,f.eq_s_b(1,"g")?f.cursor=f.limit-n:f.cursor=f.limit-r):f.cursor=f.limit-r,f.bra=f.cursor;case 2:f.slice_del()}}())),f.cursor=f.limit,function(){var e,s;if(f.ket=f.cursor,e=f.find_among_b(d,8))switch(f.bra=f.cursor,e){case 1:p()&&f.slice_del();break;case 2:p()&&(f.slice_del(),f.ket=f.cursor,f.eq_s_b(1,"u")&&(f.bra=f.cursor,s=f.limit-f.cursor,f.eq_s_b(1,"g")&&(f.cursor=f.limit-s,p()&&f.slice_del())))}}(),f.cursor=f.limit_backward,function(){for(var e;;){if(f.bra=f.cursor,e=f.find_among(a,6))switch(f.ket=f.cursor,e){case 1:f.slice_from("a");continue;case 2:f.slice_from("e");continue;case 3:f.slice_from("i");continue;case 4:f.slice_from("o");continue;case 5:f.slice_from("u");continue;case 6:if(f.cursor>=f.limit)break;f.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}):(s.setCurrent(e),s.stem(),s.getCurrent())}),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.fi.js b/latest/_static/javascripts/lunr/lunr.fi.js new file mode 100644 index 000000000..2f9bf5aeb --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.fi.js @@ -0,0 +1 @@ +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var v,C,e;i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=(v=i.stemmerSupport.Among,C=i.stemmerSupport.SnowballProgram,e=new function(){var n,t,l,o,r=[new v("pa",-1,1),new v("sti",-1,2),new v("kaan",-1,1),new v("han",-1,1),new v("kin",-1,1),new v("hän",-1,1),new v("kään",-1,1),new v("ko",-1,1),new v("pä",-1,1),new v("kö",-1,1)],s=[new v("lla",-1,-1),new v("na",-1,-1),new v("ssa",-1,-1),new v("ta",-1,-1),new v("lta",3,-1),new v("sta",3,-1)],a=[new v("llä",-1,-1),new v("nä",-1,-1),new v("ssä",-1,-1),new v("tä",-1,-1),new v("ltä",3,-1),new v("stä",3,-1)],u=[new v("lle",-1,-1),new v("ine",-1,-1)],c=[new v("nsa",-1,3),new v("mme",-1,3),new v("nne",-1,3),new v("ni",-1,2),new v("si",-1,1),new v("an",-1,4),new v("en",-1,6),new v("än",-1,5),new v("nsä",-1,3)],i=[new v("aa",-1,-1),new v("ee",-1,-1),new v("ii",-1,-1),new v("oo",-1,-1),new v("uu",-1,-1),new v("ää",-1,-1),new v("öö",-1,-1)],m=[new v("a",-1,8),new v("lla",0,-1),new v("na",0,-1),new v("ssa",0,-1),new v("ta",0,-1),new v("lta",4,-1),new v("sta",4,-1),new v("tta",4,9),new v("lle",-1,-1),new v("ine",-1,-1),new v("ksi",-1,-1),new v("n",-1,7),new v("han",11,1),new v("den",11,-1,q),new v("seen",11,-1,j),new v("hen",11,2),new v("tten",11,-1,q),new v("hin",11,3),new v("siin",11,-1,q),new v("hon",11,4),new v("hän",11,5),new v("hön",11,6),new v("ä",-1,8),new v("llä",22,-1),new v("nä",22,-1),new v("ssä",22,-1),new v("tä",22,-1),new v("ltä",26,-1),new v("stä",26,-1),new v("ttä",26,9)],w=[new v("eja",-1,-1),new v("mma",-1,1),new v("imma",1,-1),new v("mpa",-1,1),new v("impa",3,-1),new v("mmi",-1,1),new v("immi",5,-1),new v("mpi",-1,1),new v("impi",7,-1),new v("ejä",-1,-1),new v("mmä",-1,1),new v("immä",10,-1),new v("mpä",-1,1),new v("impä",12,-1)],_=[new v("i",-1,-1),new v("j",-1,-1)],k=[new v("mma",-1,1),new v("imma",0,-1)],b=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],e=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],f=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],h=new C;function p(){for(var i;i=h.cursor,!h.in_grouping(d,97,246);){if((h.cursor=i)>=h.limit)return!0;h.cursor++}for(h.cursor=i;!h.out_grouping(d,97,246);){if(h.cursor>=h.limit)return!0;h.cursor++}return!1}function g(){var i,e;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(r,10)){switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:if(!h.in_grouping_b(f,97,246))return;break;case 2:if(!(l<=h.cursor))return}h.slice_del()}else h.limit_backward=e}function j(){return h.find_among_b(i,7)}function q(){return h.eq_s_b(1,"i")&&h.in_grouping_b(e,97,246)}this.setCurrent=function(i){h.setCurrent(i)},this.getCurrent=function(){return h.getCurrent()},this.stem=function(){var i,e=h.cursor;return o=h.limit,l=o,p()||(o=h.cursor,p()||(l=h.cursor)),n=!1,h.limit_backward=e,h.cursor=h.limit,g(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(c,9))switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:r=h.limit-h.cursor,h.eq_s_b(1,"k")||(h.cursor=h.limit-r,h.slice_del());break;case 2:h.slice_del(),h.ket=h.cursor,h.eq_s_b(3,"kse")&&(h.bra=h.cursor,h.slice_from("ksi"));break;case 3:h.slice_del();break;case 4:h.find_among_b(s,6)&&h.slice_del();break;case 5:h.find_among_b(a,6)&&h.slice_del();break;case 6:h.find_among_b(u,2)&&h.slice_del()}else h.limit_backward=e}(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(m,30)){switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:if(!h.eq_s_b(1,"a"))return;break;case 2:case 9:if(!h.eq_s_b(1,"e"))return;break;case 3:if(!h.eq_s_b(1,"i"))return;break;case 4:if(!h.eq_s_b(1,"o"))return;break;case 5:if(!h.eq_s_b(1,"ä"))return;break;case 6:if(!h.eq_s_b(1,"ö"))return;break;case 7:if(r=h.limit-h.cursor,!j()&&(h.cursor=h.limit-r,!h.eq_s_b(2,"ie"))){h.cursor=h.limit-r;break}if(h.cursor=h.limit-r,h.cursor<=h.limit_backward){h.cursor=h.limit-r;break}h.cursor--,h.bra=h.cursor;break;case 8:if(!h.in_grouping_b(d,97,246)||!h.out_grouping_b(d,97,246))return}h.slice_del(),n=!0}else h.limit_backward=e}(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=l)if(e=h.limit_backward,h.limit_backward=l,h.ket=h.cursor,i=h.find_among_b(w,14)){if(h.bra=h.cursor,h.limit_backward=e,1==i){if(r=h.limit-h.cursor,h.eq_s_b(2,"po"))return;h.cursor=h.limit-r}h.slice_del()}else h.limit_backward=e}(),h.cursor=h.limit,h.cursor=(n?h.cursor>=o&&(i=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,h.find_among_b(_,2)?(h.bra=h.cursor,h.limit_backward=i,h.slice_del()):h.limit_backward=i):(h.cursor=h.limit,function(){var i,e,r,n,t,s;if(h.cursor>=o){if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,h.eq_s_b(1,"t")&&(h.bra=h.cursor,r=h.limit-h.cursor,h.in_grouping_b(d,97,246)&&(h.cursor=h.limit-r,h.slice_del(),h.limit_backward=e,n=h.limit-h.cursor,h.cursor>=l&&(h.cursor=l,t=h.limit_backward,h.limit_backward=h.cursor,h.cursor=h.limit-n,h.ket=h.cursor,i=h.find_among_b(k,2))))){if(h.bra=h.cursor,h.limit_backward=t,1==i){if(s=h.limit-h.cursor,h.eq_s_b(2,"po"))return;h.cursor=h.limit-s}return h.slice_del()}h.limit_backward=e}}()),h.limit),function(){var i,e,r,n;if(h.cursor>=o){for(i=h.limit_backward,h.limit_backward=o,e=h.limit-h.cursor,j()&&(h.cursor=h.limit-e,h.ket=h.cursor,h.cursor>h.limit_backward&&(h.cursor--,h.bra=h.cursor,h.slice_del())),h.cursor=h.limit-e,h.ket=h.cursor,h.in_grouping_b(b,97,228)&&(h.bra=h.cursor,h.out_grouping_b(d,97,246)&&h.slice_del()),h.cursor=h.limit-e,h.ket=h.cursor,h.eq_s_b(1,"j")&&(h.bra=h.cursor,r=h.limit-h.cursor,h.eq_s_b(1,"o")?h.slice_del():(h.cursor=h.limit-r,h.eq_s_b(1,"u")&&h.slice_del())),h.cursor=h.limit-e,h.ket=h.cursor,h.eq_s_b(1,"o")&&(h.bra=h.cursor,h.eq_s_b(1,"j")&&h.slice_del()),h.cursor=h.limit-e,h.limit_backward=i;;){if(n=h.limit-h.cursor,h.out_grouping_b(d,97,246)){h.cursor=h.limit-n;break}if(h.cursor=h.limit-n,h.cursor<=h.limit_backward)return;h.cursor--}h.ket=h.cursor,h.cursor>h.limit_backward&&(h.cursor--,h.bra=h.cursor,t=h.slice_to(),h.eq_v_b(t)&&h.slice_del())}}(),!0}},function(i){return"function"==typeof i.update?i.update(function(i){return e.setCurrent(i),e.stem(),e.getCurrent()}):(e.setCurrent(i),e.stem(),e.getCurrent())}),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.fr.js b/latest/_static/javascripts/lunr/lunr.fr.js new file mode 100644 index 000000000..078d0cab7 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.fr.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,y,s;e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=(r=e.stemmerSupport.Among,y=e.stemmerSupport.SnowballProgram,s=new function(){var s,i,t,n=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],u=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],o=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],c=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],a=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],l=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],w=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],f=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],m=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],_=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],b=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],d=new y;function k(e,r,s){return!(!d.eq_s(1,e)||(d.ket=d.cursor,!d.in_grouping(_,97,251)))&&(d.slice_from(r),d.cursor=s,!0)}function p(e,r,s){return!!d.eq_s(1,e)&&(d.ket=d.cursor,d.slice_from(r),d.cursor=s,!0)}function g(){for(;!d.in_grouping(_,97,251);){if(d.cursor>=d.limit)return!0;d.cursor++}for(;!d.out_grouping(_,97,251);){if(d.cursor>=d.limit)return!0;d.cursor++}return!1}function q(){return t<=d.cursor}function v(){return i<=d.cursor}function h(){return s<=d.cursor}function z(){if(!function(){var e,r;if(d.ket=d.cursor,e=d.find_among_b(a,43)){switch(d.bra=d.cursor,e){case 1:if(!h())return!1;d.slice_del();break;case 2:if(!h())return!1;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"ic")&&(d.bra=d.cursor,h()?d.slice_del():d.slice_from("iqU"));break;case 3:if(!h())return!1;d.slice_from("log");break;case 4:if(!h())return!1;d.slice_from("u");break;case 5:if(!h())return!1;d.slice_from("ent");break;case 6:if(!q())return!1;if(d.slice_del(),d.ket=d.cursor,e=d.find_among_b(o,6))switch(d.bra=d.cursor,e){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,h()&&d.slice_del()));break;case 2:h()?d.slice_del():v()&&d.slice_from("eux");break;case 3:h()&&d.slice_del();break;case 4:q()&&d.slice_from("i")}break;case 7:if(!h())return!1;if(d.slice_del(),d.ket=d.cursor,e=d.find_among_b(c,3))switch(d.bra=d.cursor,e){case 1:h()?d.slice_del():d.slice_from("abl");break;case 2:h()?d.slice_del():d.slice_from("iqU");break;case 3:h()&&d.slice_del()}break;case 8:if(!h())return!1;if(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,h()&&(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"ic")))){d.bra=d.cursor,h()?d.slice_del():d.slice_from("iqU");break}break;case 9:d.slice_from("eau");break;case 10:if(!v())return!1;d.slice_from("al");break;case 11:if(h())d.slice_del();else{if(!v())return!1;d.slice_from("eux")}break;case 12:if(!v()||!d.out_grouping_b(_,97,251))return!1;d.slice_del();break;case 13:return q()&&d.slice_from("ant"),!1;case 14:return q()&&d.slice_from("ent"),!1;case 15:return r=d.limit-d.cursor,d.in_grouping_b(_,97,251)&&q()&&(d.cursor=d.limit-r,d.slice_del()),!1}return!0}return!1}()&&(d.cursor=d.limit,!function(){var e,r;if(d.cursor=t){if(s=d.limit_backward,d.limit_backward=t,d.ket=d.cursor,e=d.find_among_b(f,7))switch(d.bra=d.cursor,e){case 1:if(h()){if(i=d.limit-d.cursor,!d.eq_s_b(1,"s")&&(d.cursor=d.limit-i,!d.eq_s_b(1,"t")))break;d.slice_del()}break;case 2:d.slice_from("i");break;case 3:d.slice_del();break;case 4:d.eq_s_b(2,"gu")&&d.slice_del()}d.limit_backward=s}}();d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,"Y")?(d.bra=d.cursor,d.slice_from("i")):(d.cursor=d.limit,d.eq_s_b(1,"ç")&&(d.bra=d.cursor,d.slice_from("c")))}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){var e,r=d.cursor;return function(){for(var e,r;;){if(e=d.cursor,d.in_grouping(_,97,251)){if(d.bra=d.cursor,r=d.cursor,k("u","U",e))continue;if(d.cursor=r,k("i","I",e))continue;if(d.cursor=r,p("y","Y",e))continue}if(d.cursor=e,!k("y","Y",d.bra=e)){if(d.cursor=e,d.eq_s(1,"q")&&(d.bra=d.cursor,p("u","U",e)))continue;if((d.cursor=e)>=d.limit)return;d.cursor++}}}(),d.cursor=r,function(){var e=d.cursor;if(t=d.limit,s=i=t,d.in_grouping(_,97,251)&&d.in_grouping(_,97,251)&&d.cursor=d.limit){d.cursor=t;break}d.cursor++}while(!d.in_grouping(_,97,251))}t=d.cursor,d.cursor=e,g()||(i=d.cursor,g()||(s=d.cursor))}(),d.limit_backward=r,d.cursor=d.limit,z(),d.cursor=d.limit,e=d.limit-d.cursor,d.find_among_b(m,5)&&(d.cursor=d.limit-e,d.ket=d.cursor,d.cursor>d.limit_backward&&(d.cursor--,d.bra=d.cursor,d.slice_del())),d.cursor=d.limit,function(){for(var e,r=1;d.out_grouping_b(_,97,251);)r--;if(r<=0){if(d.ket=d.cursor,e=d.limit-d.cursor,!d.eq_s_b(1,"é")&&(d.cursor=d.limit-e,!d.eq_s_b(1,"è")))return;d.bra=d.cursor,d.slice_from("e")}}(),d.cursor=d.limit_backward,function(){for(var e,r;r=d.cursor,d.bra=r,e=d.find_among(u,4);)switch(d.ket=d.cursor,e){case 1:d.slice_from("i");break;case 2:d.slice_from("u");break;case 3:d.slice_from("y");break;case 4:if(d.cursor>=d.limit)return;d.cursor++}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}):(s.setCurrent(e),s.stem(),s.getCurrent())}),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.hu.js b/latest/_static/javascripts/lunr/lunr.hu.js new file mode 100644 index 000000000..56a4b0dc1 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.hu.js @@ -0,0 +1 @@ +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var p,_,n;e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=(p=e.stemmerSupport.Among,_=e.stemmerSupport.SnowballProgram,n=new function(){var r,i=[new p("cs",-1,-1),new p("dzs",-1,-1),new p("gy",-1,-1),new p("ly",-1,-1),new p("ny",-1,-1),new p("sz",-1,-1),new p("ty",-1,-1),new p("zs",-1,-1)],n=[new p("á",-1,1),new p("é",-1,2)],a=[new p("bb",-1,-1),new p("cc",-1,-1),new p("dd",-1,-1),new p("ff",-1,-1),new p("gg",-1,-1),new p("jj",-1,-1),new p("kk",-1,-1),new p("ll",-1,-1),new p("mm",-1,-1),new p("nn",-1,-1),new p("pp",-1,-1),new p("rr",-1,-1),new p("ccs",-1,-1),new p("ss",-1,-1),new p("zzs",-1,-1),new p("tt",-1,-1),new p("vv",-1,-1),new p("ggy",-1,-1),new p("lly",-1,-1),new p("nny",-1,-1),new p("tty",-1,-1),new p("ssz",-1,-1),new p("zz",-1,-1)],t=[new p("al",-1,1),new p("el",-1,2)],e=[new p("ba",-1,-1),new p("ra",-1,-1),new p("be",-1,-1),new p("re",-1,-1),new p("ig",-1,-1),new p("nak",-1,-1),new p("nek",-1,-1),new p("val",-1,-1),new p("vel",-1,-1),new p("ul",-1,-1),new p("nál",-1,-1),new p("nél",-1,-1),new p("ból",-1,-1),new p("ról",-1,-1),new p("tól",-1,-1),new p("bõl",-1,-1),new p("rõl",-1,-1),new p("tõl",-1,-1),new p("ül",-1,-1),new p("n",-1,-1),new p("an",19,-1),new p("ban",20,-1),new p("en",19,-1),new p("ben",22,-1),new p("képpen",22,-1),new p("on",19,-1),new p("ön",19,-1),new p("képp",-1,-1),new p("kor",-1,-1),new p("t",-1,-1),new p("at",29,-1),new p("et",29,-1),new p("ként",29,-1),new p("anként",32,-1),new p("enként",32,-1),new p("onként",32,-1),new p("ot",29,-1),new p("ért",29,-1),new p("öt",29,-1),new p("hez",-1,-1),new p("hoz",-1,-1),new p("höz",-1,-1),new p("vá",-1,-1),new p("vé",-1,-1)],s=[new p("án",-1,2),new p("én",-1,1),new p("ánként",-1,3)],c=[new p("stul",-1,2),new p("astul",0,1),new p("ástul",0,3),new p("stül",-1,2),new p("estül",3,1),new p("éstül",3,4)],w=[new p("á",-1,1),new p("é",-1,2)],o=[new p("k",-1,7),new p("ak",0,4),new p("ek",0,6),new p("ok",0,5),new p("ák",0,1),new p("ék",0,2),new p("ök",0,3)],l=[new p("éi",-1,7),new p("áéi",0,6),new p("ééi",0,5),new p("é",-1,9),new p("ké",3,4),new p("aké",4,1),new p("eké",4,1),new p("oké",4,1),new p("áké",4,3),new p("éké",4,2),new p("öké",4,1),new p("éé",3,8)],u=[new p("a",-1,18),new p("ja",0,17),new p("d",-1,16),new p("ad",2,13),new p("ed",2,13),new p("od",2,13),new p("ád",2,14),new p("éd",2,15),new p("öd",2,13),new p("e",-1,18),new p("je",9,17),new p("nk",-1,4),new p("unk",11,1),new p("ánk",11,2),new p("énk",11,3),new p("ünk",11,1),new p("uk",-1,8),new p("juk",16,7),new p("ájuk",17,5),new p("ük",-1,8),new p("jük",19,7),new p("éjük",20,6),new p("m",-1,12),new p("am",22,9),new p("em",22,9),new p("om",22,9),new p("ám",22,10),new p("ém",22,11),new p("o",-1,18),new p("á",-1,19),new p("é",-1,20)],m=[new p("id",-1,10),new p("aid",0,9),new p("jaid",1,6),new p("eid",0,9),new p("jeid",3,6),new p("áid",0,7),new p("éid",0,8),new p("i",-1,15),new p("ai",7,14),new p("jai",8,11),new p("ei",7,14),new p("jei",10,11),new p("ái",7,12),new p("éi",7,13),new p("itek",-1,24),new p("eitek",14,21),new p("jeitek",15,20),new p("éitek",14,23),new p("ik",-1,29),new p("aik",18,26),new p("jaik",19,25),new p("eik",18,26),new p("jeik",21,25),new p("áik",18,27),new p("éik",18,28),new p("ink",-1,20),new p("aink",25,17),new p("jaink",26,16),new p("eink",25,17),new p("jeink",28,16),new p("áink",25,18),new p("éink",25,19),new p("aitok",-1,21),new p("jaitok",32,20),new p("áitok",-1,22),new p("im",-1,5),new p("aim",35,4),new p("jaim",36,1),new p("eim",35,4),new p("jeim",38,1),new p("áim",35,2),new p("éim",35,3)],k=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],f=new _;function b(){return r<=f.cursor}function d(){var e=f.limit-f.cursor;return!!f.find_among_b(a,23)&&(f.cursor=f.limit-e,!0)}function g(){if(f.cursor>f.limit_backward){f.cursor--,f.ket=f.cursor;var e=f.cursor-1;f.limit_backward<=e&&e<=f.limit&&(f.cursor=e,f.bra=e,f.slice_del())}}function h(){f.ket=f.cursor,f.find_among_b(e,44)&&(f.bra=f.cursor,b()&&(f.slice_del(),function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(n,2))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("a");break;case 2:f.slice_from("e")}}()))}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e=f.cursor;return function(){var e,n=f.cursor;if(r=f.limit,f.in_grouping(k,97,252))for(;;){if(e=f.cursor,f.out_grouping(k,97,252))return f.cursor=e,f.find_among(i,8)||(f.cursor=e)=f.limit)return r=e;f.cursor++}if(f.cursor=n,f.out_grouping(k,97,252)){for(;!f.in_grouping(k,97,252);){if(f.cursor>=f.limit)return;f.cursor++}r=f.cursor}}(),f.limit_backward=e,f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(t,2))&&(f.bra=f.cursor,b())){if((1==e||2==e)&&!d())return;f.slice_del(),g()}}(),f.cursor=f.limit,h(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(s,3))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("e");break;case 2:case 3:f.slice_from("a")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(c,6))&&(f.bra=f.cursor,b()))switch(e){case 1:case 2:f.slice_del();break;case 3:f.slice_from("a");break;case 4:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(w,2))&&(f.bra=f.cursor,b())){if((1==e||2==e)&&!d())return;f.slice_del(),g()}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(l,12))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 7:case 9:f.slice_del();break;case 2:case 5:case 8:f.slice_from("e");break;case 3:case 6:f.slice_from("a")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(u,31))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:f.slice_del();break;case 2:case 5:case 10:case 14:case 19:f.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(m,42))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:f.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:f.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(o,7))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("a");break;case 2:f.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:f.slice_del()}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.it.js b/latest/_static/javascripts/lunr/lunr.it.js new file mode 100644 index 000000000..50dddaa04 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.it.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var z,P,r;e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=(z=e.stemmerSupport.Among,P=e.stemmerSupport.SnowballProgram,r=new function(){var o,t,s,a=[new z("",-1,7),new z("qu",0,6),new z("á",0,1),new z("é",0,2),new z("í",0,3),new z("ó",0,4),new z("ú",0,5)],u=[new z("",-1,3),new z("I",0,1),new z("U",0,2)],c=[new z("la",-1,-1),new z("cela",0,-1),new z("gliela",0,-1),new z("mela",0,-1),new z("tela",0,-1),new z("vela",0,-1),new z("le",-1,-1),new z("cele",6,-1),new z("gliele",6,-1),new z("mele",6,-1),new z("tele",6,-1),new z("vele",6,-1),new z("ne",-1,-1),new z("cene",12,-1),new z("gliene",12,-1),new z("mene",12,-1),new z("sene",12,-1),new z("tene",12,-1),new z("vene",12,-1),new z("ci",-1,-1),new z("li",-1,-1),new z("celi",20,-1),new z("glieli",20,-1),new z("meli",20,-1),new z("teli",20,-1),new z("veli",20,-1),new z("gli",20,-1),new z("mi",-1,-1),new z("si",-1,-1),new z("ti",-1,-1),new z("vi",-1,-1),new z("lo",-1,-1),new z("celo",31,-1),new z("glielo",31,-1),new z("melo",31,-1),new z("telo",31,-1),new z("velo",31,-1)],w=[new z("ando",-1,1),new z("endo",-1,1),new z("ar",-1,2),new z("er",-1,2),new z("ir",-1,2)],r=[new z("ic",-1,-1),new z("abil",-1,-1),new z("os",-1,-1),new z("iv",-1,1)],n=[new z("ic",-1,1),new z("abil",-1,1),new z("iv",-1,1)],i=[new z("ica",-1,1),new z("logia",-1,3),new z("osa",-1,1),new z("ista",-1,1),new z("iva",-1,9),new z("anza",-1,1),new z("enza",-1,5),new z("ice",-1,1),new z("atrice",7,1),new z("iche",-1,1),new z("logie",-1,3),new z("abile",-1,1),new z("ibile",-1,1),new z("usione",-1,4),new z("azione",-1,2),new z("uzione",-1,4),new z("atore",-1,2),new z("ose",-1,1),new z("ante",-1,1),new z("mente",-1,1),new z("amente",19,7),new z("iste",-1,1),new z("ive",-1,9),new z("anze",-1,1),new z("enze",-1,5),new z("ici",-1,1),new z("atrici",25,1),new z("ichi",-1,1),new z("abili",-1,1),new z("ibili",-1,1),new z("ismi",-1,1),new z("usioni",-1,4),new z("azioni",-1,2),new z("uzioni",-1,4),new z("atori",-1,2),new z("osi",-1,1),new z("anti",-1,1),new z("amenti",-1,6),new z("imenti",-1,6),new z("isti",-1,1),new z("ivi",-1,9),new z("ico",-1,1),new z("ismo",-1,1),new z("oso",-1,1),new z("amento",-1,6),new z("imento",-1,6),new z("ivo",-1,9),new z("ità",-1,8),new z("istà",-1,1),new z("istè",-1,1),new z("istì",-1,1)],l=[new z("isca",-1,1),new z("enda",-1,1),new z("ata",-1,1),new z("ita",-1,1),new z("uta",-1,1),new z("ava",-1,1),new z("eva",-1,1),new z("iva",-1,1),new z("erebbe",-1,1),new z("irebbe",-1,1),new z("isce",-1,1),new z("ende",-1,1),new z("are",-1,1),new z("ere",-1,1),new z("ire",-1,1),new z("asse",-1,1),new z("ate",-1,1),new z("avate",16,1),new z("evate",16,1),new z("ivate",16,1),new z("ete",-1,1),new z("erete",20,1),new z("irete",20,1),new z("ite",-1,1),new z("ereste",-1,1),new z("ireste",-1,1),new z("ute",-1,1),new z("erai",-1,1),new z("irai",-1,1),new z("isci",-1,1),new z("endi",-1,1),new z("erei",-1,1),new z("irei",-1,1),new z("assi",-1,1),new z("ati",-1,1),new z("iti",-1,1),new z("eresti",-1,1),new z("iresti",-1,1),new z("uti",-1,1),new z("avi",-1,1),new z("evi",-1,1),new z("ivi",-1,1),new z("isco",-1,1),new z("ando",-1,1),new z("endo",-1,1),new z("Yamo",-1,1),new z("iamo",-1,1),new z("avamo",-1,1),new z("evamo",-1,1),new z("ivamo",-1,1),new z("eremo",-1,1),new z("iremo",-1,1),new z("assimo",-1,1),new z("ammo",-1,1),new z("emmo",-1,1),new z("eremmo",54,1),new z("iremmo",54,1),new z("immo",-1,1),new z("ano",-1,1),new z("iscano",58,1),new z("avano",58,1),new z("evano",58,1),new z("ivano",58,1),new z("eranno",-1,1),new z("iranno",-1,1),new z("ono",-1,1),new z("iscono",65,1),new z("arono",65,1),new z("erono",65,1),new z("irono",65,1),new z("erebbero",-1,1),new z("irebbero",-1,1),new z("assero",-1,1),new z("essero",-1,1),new z("issero",-1,1),new z("ato",-1,1),new z("ito",-1,1),new z("uto",-1,1),new z("avo",-1,1),new z("evo",-1,1),new z("ivo",-1,1),new z("ar",-1,1),new z("ir",-1,1),new z("erà",-1,1),new z("irà",-1,1),new z("erò",-1,1),new z("irò",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],f=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],v=[17],b=new P;function d(e,r,n){return!(!b.eq_s(1,e)||(b.ket=b.cursor,!b.in_grouping(m,97,249)))&&(b.slice_from(r),b.cursor=n,!0)}function _(e){if(b.cursor=e,!b.in_grouping(m,97,249))return!1;for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function g(){var e,r=b.cursor;if(!function(){if(b.in_grouping(m,97,249)){var e=b.cursor;if(b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return _(e);b.cursor++}return!0}return _(e)}return!1}()){if(b.cursor=r,!b.out_grouping(m,97,249))return;if(e=b.cursor,b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return b.cursor=e,void(b.in_grouping(m,97,249)&&b.cursor=b.limit)return;b.cursor++}s=b.cursor}function p(){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function k(){return s<=b.cursor}function h(){return o<=b.cursor}function q(){var e;if(b.ket=b.cursor,!(e=b.find_among_b(i,51)))return!1;switch(b.bra=b.cursor,e){case 1:if(!h())return!1;b.slice_del();break;case 2:if(!h())return!1;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"ic")&&(b.bra=b.cursor,h()&&b.slice_del());break;case 3:if(!h())return!1;b.slice_from("log");break;case 4:if(!h())return!1;b.slice_from("u");break;case 5:if(!h())return!1;b.slice_from("ente");break;case 6:if(!k())return!1;b.slice_del();break;case 7:if(!(t<=b.cursor))return!1;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(r,4))&&(b.bra=b.cursor,h()&&(b.slice_del(),1==e&&(b.ket=b.cursor,b.eq_s_b(2,"at")&&(b.bra=b.cursor,h()&&b.slice_del()))));break;case 8:if(!h())return!1;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(n,3))&&(b.bra=b.cursor,1==e&&h()&&b.slice_del());break;case 9:if(!h())return!1;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"at")&&(b.bra=b.cursor,h()&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"ic")&&(b.bra=b.cursor,h()&&b.slice_del())))}return!0}function C(){var e;e=b.limit-b.cursor,b.ket=b.cursor,b.in_grouping_b(f,97,242)&&(b.bra=b.cursor,k()&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(1,"i")&&(b.bra=b.cursor,k())))?b.slice_del():b.cursor=b.limit-e,b.ket=b.cursor,b.eq_s_b(1,"h")&&(b.bra=b.cursor,b.in_grouping_b(v,99,103)&&k()&&b.slice_del())}this.setCurrent=function(e){b.setCurrent(e)},this.getCurrent=function(){return b.getCurrent()},this.stem=function(){var e,r,n,i=b.cursor;return function(){for(var e,r,n,i,o=b.cursor;;){if(b.bra=b.cursor,e=b.find_among(a,7))switch(b.ket=b.cursor,e){case 1:b.slice_from("à");continue;case 2:b.slice_from("è");continue;case 3:b.slice_from("ì");continue;case 4:b.slice_from("ò");continue;case 5:b.slice_from("ù");continue;case 6:b.slice_from("qU");continue;case 7:if(b.cursor>=b.limit)break;b.cursor++;continue}break}for(b.cursor=o;;)for(r=b.cursor;;){if(n=b.cursor,b.in_grouping(m,97,249)){if(b.bra=b.cursor,i=b.cursor,d("u","U",n))break;if(b.cursor=i,d("i","I",n))break}if(b.cursor=n,b.cursor>=b.limit)return b.cursor=r;b.cursor++}}(),b.cursor=i,e=b.cursor,s=b.limit,o=t=s,g(),b.cursor=e,p()&&(t=b.cursor,p()&&(o=b.cursor)),b.limit_backward=i,b.cursor=b.limit,function(){var e;if(b.ket=b.cursor,b.find_among_b(c,37)&&(b.bra=b.cursor,(e=b.find_among_b(w,5))&&k()))switch(e){case 1:b.slice_del();break;case 2:b.slice_from("e")}}(),b.cursor=b.limit,q()||(b.cursor=b.limit,b.cursor>=s&&(n=b.limit_backward,b.limit_backward=s,b.ket=b.cursor,(r=b.find_among_b(l,87))&&(b.bra=b.cursor,1==r&&b.slice_del()),b.limit_backward=n)),b.cursor=b.limit,C(),b.cursor=b.limit_backward,function(){for(var e;b.bra=b.cursor,e=b.find_among(u,3);)switch(b.ket=b.cursor,e){case 1:b.slice_from("i");break;case 2:b.slice_from("u");break;case 3:if(b.cursor>=b.limit)return;b.cursor++}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.ja.js b/latest/_static/javascripts/lunr/lunr.ja.js new file mode 100644 index 000000000..69f620250 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.ja.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(m){if(void 0===m)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===m.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var l="2"==m.version[0];m.ja=function(){this.pipeline.reset(),this.pipeline.add(m.ja.trimmer,m.ja.stopWordFilter,m.ja.stemmer),l?this.tokenizer=m.ja.tokenizer:(m.tokenizer&&(m.tokenizer=m.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=m.ja.tokenizer))};var j=new m.TinySegmenter;m.ja.tokenizer=function(e){var r,t,i,n,o,s,p,a,u;if(!arguments.length||null==e||null==e)return[];if(Array.isArray(e))return e.map(function(e){return l?new m.Token(e.toLowerCase()):e.toLowerCase()});for(r=(t=e.toString().toLowerCase().replace(/^\s+/,"")).length-1;0<=r;r--)if(/\S/.test(t.charAt(r))){t=t.substring(0,r+1);break}for(o=[],i=t.length,p=a=0;a<=i;a++)if(s=a-p,t.charAt(a).match(/\s/)||a==i){if(0=_.limit||(_.cursor++,!1)}function w(){for(;!_.in_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}for(;!_.out_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}return!1}function b(){return i<=_.cursor}function p(){return e<=_.cursor}function g(){var r=_.limit-_.cursor;_.find_among_b(t,3)&&(_.cursor=_.limit-r,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del()))}function h(){var r;u=!1,_.ket=_.cursor,_.eq_s_b(1,"e")&&(_.bra=_.cursor,b()&&(r=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-r,_.slice_del(),u=!0,g())))}function k(){var r;b()&&(r=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-r,_.eq_s_b(3,"gem")||(_.cursor=_.limit-r,_.slice_del(),g())))}this.setCurrent=function(r){_.setCurrent(r)},this.getCurrent=function(){return _.getCurrent()},this.stem=function(){var r=_.cursor;return function(){for(var r,e,i,n=_.cursor;;){if(_.bra=_.cursor,r=_.find_among(o,11))switch(_.ket=_.cursor,r){case 1:_.slice_from("a");continue;case 2:_.slice_from("e");continue;case 3:_.slice_from("i");continue;case 4:_.slice_from("o");continue;case 5:_.slice_from("u");continue;case 6:if(_.cursor>=_.limit)break;_.cursor++;continue}break}for(_.cursor=n,_.bra=n,_.eq_s(1,"y")?(_.ket=_.cursor,_.slice_from("Y")):_.cursor=n;;)if(e=_.cursor,_.in_grouping(m,97,232)){if(i=_.cursor,_.bra=i,_.eq_s(1,"i"))_.ket=_.cursor,_.in_grouping(m,97,232)&&(_.slice_from("I"),_.cursor=e);else if(_.cursor=i,_.eq_s(1,"y"))_.ket=_.cursor,_.slice_from("Y"),_.cursor=e;else if(s(e))break}else if(s(e))break}(),_.cursor=r,i=_.limit,e=i,w()||((i=_.cursor)<3&&(i=3),w()||(e=_.cursor)),_.limit_backward=r,_.cursor=_.limit,function(){var r,e,i,n,o,t,s=_.limit-_.cursor;if(_.ket=_.cursor,r=_.find_among_b(c,5))switch(_.bra=_.cursor,r){case 1:b()&&_.slice_from("heid");break;case 2:k();break;case 3:b()&&_.out_grouping_b(f,97,232)&&_.slice_del()}if(_.cursor=_.limit-s,h(),_.cursor=_.limit-s,_.ket=_.cursor,_.eq_s_b(4,"heid")&&(_.bra=_.cursor,p()&&(e=_.limit-_.cursor,_.eq_s_b(1,"c")||(_.cursor=_.limit-e,_.slice_del(),_.ket=_.cursor,_.eq_s_b(2,"en")&&(_.bra=_.cursor,k())))),_.cursor=_.limit-s,_.ket=_.cursor,r=_.find_among_b(a,6))switch(_.bra=_.cursor,r){case 1:if(p()){if(_.slice_del(),i=_.limit-_.cursor,_.ket=_.cursor,_.eq_s_b(2,"ig")&&(_.bra=_.cursor,p()&&(n=_.limit-_.cursor,!_.eq_s_b(1,"e")))){_.cursor=_.limit-n,_.slice_del();break}_.cursor=_.limit-i,g()}break;case 2:p()&&(o=_.limit-_.cursor,_.eq_s_b(1,"e")||(_.cursor=_.limit-o,_.slice_del()));break;case 3:p()&&(_.slice_del(),h());break;case 4:p()&&_.slice_del();break;case 5:p()&&u&&_.slice_del()}_.cursor=_.limit-s,_.out_grouping_b(d,73,232)&&(t=_.limit-_.cursor,_.find_among_b(l,4)&&_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-t,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del())))}(),_.cursor=_.limit_backward,function(){for(var r;;)if(_.bra=_.cursor,r=_.find_among(n,3))switch(_.ket=_.cursor,r){case 1:_.slice_from("y");break;case 2:_.slice_from("i");break;case 3:if(_.cursor>=_.limit)return;_.cursor++}}(),!0}},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}),r.Pipeline.registerFunction(r.nl.stemmer,"stemmer-nl"),r.nl.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.nl.stopWordFilter,"stopWordFilter-nl")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.no.js b/latest/_static/javascripts/lunr/lunr.no.js new file mode 100644 index 000000000..3d156b9c1 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.no.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,n,i;e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=(r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){var o,s,a=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],m=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],u=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],d=[119,125,149,1],c=new n;this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var e,r,n,i,t=c.cursor;return function(){var e,r=c.cursor+3;if(s=c.limit,0<=r||r<=c.limit){for(o=r;;){if(e=c.cursor,c.in_grouping(u,97,248)){c.cursor=e;break}if(e>=c.limit)return;c.cursor=e+1}for(;!c.out_grouping(u,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(s=c.cursor)=s&&(r=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,e=c.find_among_b(a,29),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:n=c.limit-c.cursor,c.in_grouping_b(d,98,122)?c.slice_del():(c.cursor=c.limit-n,c.eq_s_b(1,"k")&&c.out_grouping_b(u,97,248)&&c.slice_del());break;case 3:c.slice_from("er")}}(),c.cursor=c.limit,r=c.limit-c.cursor,c.cursor>=s&&(e=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,c.find_among_b(m,2)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e),c.cursor=c.limit,c.cursor>=s&&(i=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,(n=c.find_among_b(l,11))?(c.bra=c.cursor,c.limit_backward=i,1==n&&c.slice_del()):c.limit_backward=i),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.pt.js b/latest/_static/javascripts/lunr/lunr.pt.js new file mode 100644 index 000000000..f50fc9fa6 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.pt.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var j,C,r;e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=(j=e.stemmerSupport.Among,C=e.stemmerSupport.SnowballProgram,r=new function(){var s,n,i,o=[new j("",-1,3),new j("ã",0,1),new j("õ",0,2)],a=[new j("",-1,3),new j("a~",0,1),new j("o~",0,2)],r=[new j("ic",-1,-1),new j("ad",-1,-1),new j("os",-1,-1),new j("iv",-1,1)],t=[new j("ante",-1,1),new j("avel",-1,1),new j("ível",-1,1)],u=[new j("ic",-1,1),new j("abil",-1,1),new j("iv",-1,1)],w=[new j("ica",-1,1),new j("ância",-1,1),new j("ência",-1,4),new j("ira",-1,9),new j("adora",-1,1),new j("osa",-1,1),new j("ista",-1,1),new j("iva",-1,8),new j("eza",-1,1),new j("logía",-1,2),new j("idade",-1,7),new j("ante",-1,1),new j("mente",-1,6),new j("amente",12,5),new j("ável",-1,1),new j("ível",-1,1),new j("ución",-1,3),new j("ico",-1,1),new j("ismo",-1,1),new j("oso",-1,1),new j("amento",-1,1),new j("imento",-1,1),new j("ivo",-1,8),new j("aça~o",-1,1),new j("ador",-1,1),new j("icas",-1,1),new j("ências",-1,4),new j("iras",-1,9),new j("adoras",-1,1),new j("osas",-1,1),new j("istas",-1,1),new j("ivas",-1,8),new j("ezas",-1,1),new j("logías",-1,2),new j("idades",-1,7),new j("uciones",-1,3),new j("adores",-1,1),new j("antes",-1,1),new j("aço~es",-1,1),new j("icos",-1,1),new j("ismos",-1,1),new j("osos",-1,1),new j("amentos",-1,1),new j("imentos",-1,1),new j("ivos",-1,8)],m=[new j("ada",-1,1),new j("ida",-1,1),new j("ia",-1,1),new j("aria",2,1),new j("eria",2,1),new j("iria",2,1),new j("ara",-1,1),new j("era",-1,1),new j("ira",-1,1),new j("ava",-1,1),new j("asse",-1,1),new j("esse",-1,1),new j("isse",-1,1),new j("aste",-1,1),new j("este",-1,1),new j("iste",-1,1),new j("ei",-1,1),new j("arei",16,1),new j("erei",16,1),new j("irei",16,1),new j("am",-1,1),new j("iam",20,1),new j("ariam",21,1),new j("eriam",21,1),new j("iriam",21,1),new j("aram",20,1),new j("eram",20,1),new j("iram",20,1),new j("avam",20,1),new j("em",-1,1),new j("arem",29,1),new j("erem",29,1),new j("irem",29,1),new j("assem",29,1),new j("essem",29,1),new j("issem",29,1),new j("ado",-1,1),new j("ido",-1,1),new j("ando",-1,1),new j("endo",-1,1),new j("indo",-1,1),new j("ara~o",-1,1),new j("era~o",-1,1),new j("ira~o",-1,1),new j("ar",-1,1),new j("er",-1,1),new j("ir",-1,1),new j("as",-1,1),new j("adas",47,1),new j("idas",47,1),new j("ias",47,1),new j("arias",50,1),new j("erias",50,1),new j("irias",50,1),new j("aras",47,1),new j("eras",47,1),new j("iras",47,1),new j("avas",47,1),new j("es",-1,1),new j("ardes",58,1),new j("erdes",58,1),new j("irdes",58,1),new j("ares",58,1),new j("eres",58,1),new j("ires",58,1),new j("asses",58,1),new j("esses",58,1),new j("isses",58,1),new j("astes",58,1),new j("estes",58,1),new j("istes",58,1),new j("is",-1,1),new j("ais",71,1),new j("eis",71,1),new j("areis",73,1),new j("ereis",73,1),new j("ireis",73,1),new j("áreis",73,1),new j("éreis",73,1),new j("íreis",73,1),new j("ásseis",73,1),new j("ésseis",73,1),new j("ísseis",73,1),new j("áveis",73,1),new j("íeis",73,1),new j("aríeis",84,1),new j("eríeis",84,1),new j("iríeis",84,1),new j("ados",-1,1),new j("idos",-1,1),new j("amos",-1,1),new j("áramos",90,1),new j("éramos",90,1),new j("íramos",90,1),new j("ávamos",90,1),new j("íamos",90,1),new j("aríamos",95,1),new j("eríamos",95,1),new j("iríamos",95,1),new j("emos",-1,1),new j("aremos",99,1),new j("eremos",99,1),new j("iremos",99,1),new j("ássemos",99,1),new j("êssemos",99,1),new j("íssemos",99,1),new j("imos",-1,1),new j("armos",-1,1),new j("ermos",-1,1),new j("irmos",-1,1),new j("ámos",-1,1),new j("arás",-1,1),new j("erás",-1,1),new j("irás",-1,1),new j("eu",-1,1),new j("iu",-1,1),new j("ou",-1,1),new j("ará",-1,1),new j("erá",-1,1),new j("irá",-1,1)],c=[new j("a",-1,1),new j("i",-1,1),new j("o",-1,1),new j("os",-1,1),new j("á",-1,1),new j("í",-1,1),new j("ó",-1,1)],l=[new j("e",-1,1),new j("ç",-1,2),new j("é",-1,1),new j("ê",-1,1)],f=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],d=new C;function v(){if(d.out_grouping(f,97,250)){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return!0;d.cursor++}return!1}return!0}function p(){var e,r,s=d.cursor;if(d.in_grouping(f,97,250))if(e=d.cursor,v()){if(d.cursor=e,function(){if(d.in_grouping(f,97,250))for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}return i=d.cursor,!0}())return}else i=d.cursor;if(d.cursor=s,d.out_grouping(f,97,250)){if(r=d.cursor,v()){if(d.cursor=r,!d.in_grouping(f,97,250)||d.cursor>=d.limit)return;d.cursor++}i=d.cursor}}function _(){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}return!0}function h(){return i<=d.cursor}function b(){return s<=d.cursor}function g(){var e;if(d.ket=d.cursor,!(e=d.find_among_b(w,45)))return!1;switch(d.bra=d.cursor,e){case 1:if(!b())return!1;d.slice_del();break;case 2:if(!b())return!1;d.slice_from("log");break;case 3:if(!b())return!1;d.slice_from("u");break;case 4:if(!b())return!1;d.slice_from("ente");break;case 5:if(!(n<=d.cursor))return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(r,4))&&(d.bra=d.cursor,b()&&(d.slice_del(),1==e&&(d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,b()&&d.slice_del()))));break;case 6:if(!b())return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(t,3))&&(d.bra=d.cursor,1==e&&b()&&d.slice_del());break;case 7:if(!b())return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(u,3))&&(d.bra=d.cursor,1==e&&b()&&d.slice_del());break;case 8:if(!b())return!1;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,b()&&d.slice_del());break;case 9:if(!h()||!d.eq_s_b(1,"e"))return!1;d.slice_from("ir")}return!0}function k(e,r){if(d.eq_s_b(1,e)){d.bra=d.cursor;var s=d.limit-d.cursor;if(d.eq_s_b(1,r))return d.cursor=d.limit-s,h()&&d.slice_del(),!1}return!0}function q(){if(!g()&&(d.cursor=d.limit,!function(){var e,r;if(d.cursor>=i){if(r=d.limit_backward,d.limit_backward=i,d.ket=d.cursor,e=d.find_among_b(m,120))return d.bra=d.cursor,1==e&&d.slice_del(),d.limit_backward=r,!0;d.limit_backward=r}return!1}()))return d.cursor=d.limit,d.ket=d.cursor,void((e=d.find_among_b(c,7))&&(d.bra=d.cursor,1==e&&h()&&d.slice_del()));var e;d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,"i")&&(d.bra=d.cursor,d.eq_s_b(1,"c")&&(d.cursor=d.limit,h()&&d.slice_del()))}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){var e,r=d.cursor;return function(){for(var e;;){if(d.bra=d.cursor,e=d.find_among(o,3))switch(d.ket=d.cursor,e){case 1:d.slice_from("a~");continue;case 2:d.slice_from("o~");continue;case 3:if(d.cursor>=d.limit)break;d.cursor++;continue}break}}(),d.cursor=r,e=d.cursor,i=d.limit,s=n=i,p(),d.cursor=e,_()&&(n=d.cursor,_()&&(s=d.cursor)),d.limit_backward=r,d.cursor=d.limit,q(),d.cursor=d.limit,function(){var e;if(d.ket=d.cursor,e=d.find_among_b(l,4))switch(d.bra=d.cursor,e){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.limit,d.cursor,k("u","g")&&k("i","c"));break;case 2:d.slice_from("c")}}(),d.cursor=d.limit_backward,function(){for(var e;;){if(d.bra=d.cursor,e=d.find_among(a,3))switch(d.ket=d.cursor,e){case 1:d.slice_from("ã");continue;case 2:d.slice_from("õ");continue;case 3:if(d.cursor>=d.limit)break;d.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.ro.js b/latest/_static/javascripts/lunr/lunr.ro.js new file mode 100644 index 000000000..b19627e1b --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.ro.js @@ -0,0 +1 @@ +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var h,z,i;e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=(h=e.stemmerSupport.Among,z=e.stemmerSupport.SnowballProgram,i=new function(){var r,n,t,a,o=[new h("",-1,3),new h("I",0,1),new h("U",0,2)],s=[new h("ea",-1,3),new h("aţia",-1,7),new h("aua",-1,2),new h("iua",-1,4),new h("aţie",-1,7),new h("ele",-1,3),new h("ile",-1,5),new h("iile",6,4),new h("iei",-1,4),new h("atei",-1,6),new h("ii",-1,4),new h("ului",-1,1),new h("ul",-1,1),new h("elor",-1,3),new h("ilor",-1,4),new h("iilor",14,4)],c=[new h("icala",-1,4),new h("iciva",-1,4),new h("ativa",-1,5),new h("itiva",-1,6),new h("icale",-1,4),new h("aţiune",-1,5),new h("iţiune",-1,6),new h("atoare",-1,5),new h("itoare",-1,6),new h("ătoare",-1,5),new h("icitate",-1,4),new h("abilitate",-1,1),new h("ibilitate",-1,2),new h("ivitate",-1,3),new h("icive",-1,4),new h("ative",-1,5),new h("itive",-1,6),new h("icali",-1,4),new h("atori",-1,5),new h("icatori",18,4),new h("itori",-1,6),new h("ători",-1,5),new h("icitati",-1,4),new h("abilitati",-1,1),new h("ivitati",-1,3),new h("icivi",-1,4),new h("ativi",-1,5),new h("itivi",-1,6),new h("icităi",-1,4),new h("abilităi",-1,1),new h("ivităi",-1,3),new h("icităţi",-1,4),new h("abilităţi",-1,1),new h("ivităţi",-1,3),new h("ical",-1,4),new h("ator",-1,5),new h("icator",35,4),new h("itor",-1,6),new h("ător",-1,5),new h("iciv",-1,4),new h("ativ",-1,5),new h("itiv",-1,6),new h("icală",-1,4),new h("icivă",-1,4),new h("ativă",-1,5),new h("itivă",-1,6)],u=[new h("ica",-1,1),new h("abila",-1,1),new h("ibila",-1,1),new h("oasa",-1,1),new h("ata",-1,1),new h("ita",-1,1),new h("anta",-1,1),new h("ista",-1,3),new h("uta",-1,1),new h("iva",-1,1),new h("ic",-1,1),new h("ice",-1,1),new h("abile",-1,1),new h("ibile",-1,1),new h("isme",-1,3),new h("iune",-1,2),new h("oase",-1,1),new h("ate",-1,1),new h("itate",17,1),new h("ite",-1,1),new h("ante",-1,1),new h("iste",-1,3),new h("ute",-1,1),new h("ive",-1,1),new h("ici",-1,1),new h("abili",-1,1),new h("ibili",-1,1),new h("iuni",-1,2),new h("atori",-1,1),new h("osi",-1,1),new h("ati",-1,1),new h("itati",30,1),new h("iti",-1,1),new h("anti",-1,1),new h("isti",-1,3),new h("uti",-1,1),new h("işti",-1,3),new h("ivi",-1,1),new h("ităi",-1,1),new h("oşi",-1,1),new h("ităţi",-1,1),new h("abil",-1,1),new h("ibil",-1,1),new h("ism",-1,3),new h("ator",-1,1),new h("os",-1,1),new h("at",-1,1),new h("it",-1,1),new h("ant",-1,1),new h("ist",-1,3),new h("ut",-1,1),new h("iv",-1,1),new h("ică",-1,1),new h("abilă",-1,1),new h("ibilă",-1,1),new h("oasă",-1,1),new h("ată",-1,1),new h("ită",-1,1),new h("antă",-1,1),new h("istă",-1,3),new h("ută",-1,1),new h("ivă",-1,1)],w=[new h("ea",-1,1),new h("ia",-1,1),new h("esc",-1,1),new h("ăsc",-1,1),new h("ind",-1,1),new h("ând",-1,1),new h("are",-1,1),new h("ere",-1,1),new h("ire",-1,1),new h("âre",-1,1),new h("se",-1,2),new h("ase",10,1),new h("sese",10,2),new h("ise",10,1),new h("use",10,1),new h("âse",10,1),new h("eşte",-1,1),new h("ăşte",-1,1),new h("eze",-1,1),new h("ai",-1,1),new h("eai",19,1),new h("iai",19,1),new h("sei",-1,2),new h("eşti",-1,1),new h("ăşti",-1,1),new h("ui",-1,1),new h("ezi",-1,1),new h("âi",-1,1),new h("aşi",-1,1),new h("seşi",-1,2),new h("aseşi",29,1),new h("seseşi",29,2),new h("iseşi",29,1),new h("useşi",29,1),new h("âseşi",29,1),new h("işi",-1,1),new h("uşi",-1,1),new h("âşi",-1,1),new h("aţi",-1,2),new h("eaţi",38,1),new h("iaţi",38,1),new h("eţi",-1,2),new h("iţi",-1,2),new h("âţi",-1,2),new h("arăţi",-1,1),new h("serăţi",-1,2),new h("aserăţi",45,1),new h("seserăţi",45,2),new h("iserăţi",45,1),new h("userăţi",45,1),new h("âserăţi",45,1),new h("irăţi",-1,1),new h("urăţi",-1,1),new h("ârăţi",-1,1),new h("am",-1,1),new h("eam",54,1),new h("iam",54,1),new h("em",-1,2),new h("asem",57,1),new h("sesem",57,2),new h("isem",57,1),new h("usem",57,1),new h("âsem",57,1),new h("im",-1,2),new h("âm",-1,2),new h("ăm",-1,2),new h("arăm",65,1),new h("serăm",65,2),new h("aserăm",67,1),new h("seserăm",67,2),new h("iserăm",67,1),new h("userăm",67,1),new h("âserăm",67,1),new h("irăm",65,1),new h("urăm",65,1),new h("ârăm",65,1),new h("au",-1,1),new h("eau",76,1),new h("iau",76,1),new h("indu",-1,1),new h("ându",-1,1),new h("ez",-1,1),new h("ească",-1,1),new h("ară",-1,1),new h("seră",-1,2),new h("aseră",84,1),new h("seseră",84,2),new h("iseră",84,1),new h("useră",84,1),new h("âseră",84,1),new h("iră",-1,1),new h("ură",-1,1),new h("âră",-1,1),new h("ează",-1,1)],i=[new h("a",-1,1),new h("e",-1,1),new h("ie",1,1),new h("i",-1,1),new h("ă",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],l=new z;function f(e,i){l.eq_s(1,e)&&(l.ket=l.cursor,l.in_grouping(m,97,259)&&l.slice_from(i))}function p(){if(l.out_grouping(m,97,259)){for(;!l.in_grouping(m,97,259);){if(l.cursor>=l.limit)return!0;l.cursor++}return!1}return!0}function d(){var e,i,r=l.cursor;if(l.in_grouping(m,97,259)){if(e=l.cursor,!p())return void(a=l.cursor);if(l.cursor=e,!function(){if(l.in_grouping(m,97,259))for(;!l.out_grouping(m,97,259);){if(l.cursor>=l.limit)return!0;l.cursor++}return!1}())return void(a=l.cursor)}l.cursor=r,l.out_grouping(m,97,259)&&(i=l.cursor,p()&&(l.cursor=i,l.in_grouping(m,97,259)&&l.cursor=l.limit)return!1;l.cursor++}for(;!l.out_grouping(m,97,259);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function v(){return t<=l.cursor}function _(){var e,i=l.limit-l.cursor;if(l.ket=l.cursor,(e=l.find_among_b(c,46))&&(l.bra=l.cursor,v())){switch(e){case 1:l.slice_from("abil");break;case 2:l.slice_from("ibil");break;case 3:l.slice_from("iv");break;case 4:l.slice_from("ic");break;case 5:l.slice_from("at");break;case 6:l.slice_from("it")}return r=!0,l.cursor=l.limit-i,!0}return!1}function g(){var e,i;for(r=!1;;)if(i=l.limit-l.cursor,!_()){l.cursor=l.limit-i;break}if(l.ket=l.cursor,(e=l.find_among_b(u,62))&&(l.bra=l.cursor,n<=l.cursor)){switch(e){case 1:l.slice_del();break;case 2:l.eq_s_b(1,"ţ")&&(l.bra=l.cursor,l.slice_from("t"));break;case 3:l.slice_from("ist")}r=!0}}function k(){var e;l.ket=l.cursor,(e=l.find_among_b(i,5))&&(l.bra=l.cursor,a<=l.cursor&&1==e&&l.slice_del())}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){var e,i=l.cursor;return function(){for(var e,i;e=l.cursor,l.in_grouping(m,97,259)&&(i=l.cursor,l.bra=i,f("u","U"),l.cursor=i,f("i","I")),l.cursor=e,!(l.cursor>=l.limit);)l.cursor++}(),l.cursor=i,e=l.cursor,a=l.limit,n=t=a,d(),l.cursor=e,b()&&(t=l.cursor,b()&&(n=l.cursor)),l.limit_backward=i,l.cursor=l.limit,function(){var e,i;if(l.ket=l.cursor,(e=l.find_among_b(s,16))&&(l.bra=l.cursor,v()))switch(e){case 1:l.slice_del();break;case 2:l.slice_from("a");break;case 3:l.slice_from("e");break;case 4:l.slice_from("i");break;case 5:i=l.limit-l.cursor,l.eq_s_b(2,"ab")||(l.cursor=l.limit-i,l.slice_from("i"));break;case 6:l.slice_from("at");break;case 7:l.slice_from("aţi")}}(),l.cursor=l.limit,g(),l.cursor=l.limit,r||(l.cursor=l.limit,function(){var e,i,r;if(l.cursor>=a){if(i=l.limit_backward,l.limit_backward=a,l.ket=l.cursor,e=l.find_among_b(w,94))switch(l.bra=l.cursor,e){case 1:if(r=l.limit-l.cursor,!l.out_grouping_b(m,97,259)&&(l.cursor=l.limit-r,!l.eq_s_b(1,"u")))break;case 2:l.slice_del()}l.limit_backward=i}}(),l.cursor=l.limit),k(),l.cursor=l.limit_backward,function(){for(var e;;){if(l.bra=l.cursor,e=l.find_among(o,3))switch(l.ket=l.cursor,e){case 1:l.slice_from("i");continue;case 2:l.slice_from("u");continue;case 3:if(l.cursor>=l.limit)break;l.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.ru.js b/latest/_static/javascripts/lunr/lunr.ru.js new file mode 100644 index 000000000..ac9924804 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.ru.js @@ -0,0 +1 @@ +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var h,g,n;e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=(h=e.stemmerSupport.Among,g=e.stemmerSupport.SnowballProgram,n=new function(){var n,e,r=[new h("в",-1,1),new h("ив",0,2),new h("ыв",0,2),new h("вши",-1,1),new h("ивши",3,2),new h("ывши",3,2),new h("вшись",-1,1),new h("ившись",6,2),new h("ывшись",6,2)],t=[new h("ее",-1,1),new h("ие",-1,1),new h("ое",-1,1),new h("ые",-1,1),new h("ими",-1,1),new h("ыми",-1,1),new h("ей",-1,1),new h("ий",-1,1),new h("ой",-1,1),new h("ый",-1,1),new h("ем",-1,1),new h("им",-1,1),new h("ом",-1,1),new h("ым",-1,1),new h("его",-1,1),new h("ого",-1,1),new h("ему",-1,1),new h("ому",-1,1),new h("их",-1,1),new h("ых",-1,1),new h("ею",-1,1),new h("ою",-1,1),new h("ую",-1,1),new h("юю",-1,1),new h("ая",-1,1),new h("яя",-1,1)],w=[new h("ем",-1,1),new h("нн",-1,1),new h("вш",-1,1),new h("ивш",2,2),new h("ывш",2,2),new h("щ",-1,1),new h("ющ",5,1),new h("ующ",6,2)],i=[new h("сь",-1,1),new h("ся",-1,1)],u=[new h("ла",-1,1),new h("ила",0,2),new h("ыла",0,2),new h("на",-1,1),new h("ена",3,2),new h("ете",-1,1),new h("ите",-1,2),new h("йте",-1,1),new h("ейте",7,2),new h("уйте",7,2),new h("ли",-1,1),new h("или",10,2),new h("ыли",10,2),new h("й",-1,1),new h("ей",13,2),new h("уй",13,2),new h("л",-1,1),new h("ил",16,2),new h("ыл",16,2),new h("ем",-1,1),new h("им",-1,2),new h("ым",-1,2),new h("н",-1,1),new h("ен",22,2),new h("ло",-1,1),new h("ило",24,2),new h("ыло",24,2),new h("но",-1,1),new h("ено",27,2),new h("нно",27,1),new h("ет",-1,1),new h("ует",30,2),new h("ит",-1,2),new h("ыт",-1,2),new h("ют",-1,1),new h("уют",34,2),new h("ят",-1,2),new h("ны",-1,1),new h("ены",37,2),new h("ть",-1,1),new h("ить",39,2),new h("ыть",39,2),new h("ешь",-1,1),new h("ишь",-1,2),new h("ю",-1,2),new h("ую",44,2)],s=[new h("а",-1,1),new h("ев",-1,1),new h("ов",-1,1),new h("е",-1,1),new h("ие",3,1),new h("ье",3,1),new h("и",-1,1),new h("еи",6,1),new h("ии",6,1),new h("ами",6,1),new h("ями",6,1),new h("иями",10,1),new h("й",-1,1),new h("ей",12,1),new h("ией",13,1),new h("ий",12,1),new h("ой",12,1),new h("ам",-1,1),new h("ем",-1,1),new h("ием",18,1),new h("ом",-1,1),new h("ям",-1,1),new h("иям",21,1),new h("о",-1,1),new h("у",-1,1),new h("ах",-1,1),new h("ях",-1,1),new h("иях",26,1),new h("ы",-1,1),new h("ь",-1,1),new h("ю",-1,1),new h("ию",30,1),new h("ью",30,1),new h("я",-1,1),new h("ия",33,1),new h("ья",33,1)],o=[new h("ост",-1,1),new h("ость",-1,1)],c=[new h("ейше",-1,1),new h("н",-1,2),new h("ейш",-1,1),new h("ь",-1,3)],m=[33,65,8,232],l=new g;function f(){for(;!l.in_grouping(m,1072,1103);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function a(){for(;!l.out_grouping(m,1072,1103);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function p(e,n){var r,t;if(l.ket=l.cursor,r=l.find_among_b(e,n)){switch(l.bra=l.cursor,r){case 1:if(t=l.limit-l.cursor,!l.eq_s_b(1,"а")&&(l.cursor=l.limit-t,!l.eq_s_b(1,"я")))return!1;case 2:l.slice_del()}return!0}return!1}function d(e,n){var r;return l.ket=l.cursor,!!(r=l.find_among_b(e,n))&&(l.bra=l.cursor,1==r&&l.slice_del(),!0)}function _(){return!!d(t,26)&&(p(w,8),!0)}function b(){var e;l.ket=l.cursor,(e=l.find_among_b(o,2))&&(l.bra=l.cursor,n<=l.cursor&&1==e&&l.slice_del())}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){return e=l.limit,n=e,f()&&(e=l.cursor,a()&&f()&&a()&&(n=l.cursor)),l.cursor=l.limit,!(l.cursor>3]&1<<(7&s))return this.cursor++,!0}return!1},in_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(s<=i&&t<=s&&r[(s-=t)>>3]&1<<(7&s))return this.cursor--,!0}return!1},out_grouping:function(r,t,i){if(this.cursor>3]&1<<(7&s)))return this.cursor++,!0}return!1},out_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(i>3]&1<<(7&s)))return this.cursor--,!0}return!1},eq_s:function(r,t){if(this.limit-this.cursor>1),a=0,f=u=(l=r[i]).s_size){if(this.cursor=e+l.s_size,!l.method)return l.result;var m=l.method();if(this.cursor=e+l.s_size,m)return l.result}if((i=l.substring_i)<0)return 0}},find_among_b:function(r,t){for(var i=0,s=t,e=this.cursor,n=this.limit_backward,u=0,o=0,h=!1;;){for(var c=i+(s-i>>1),a=0,f=u=(_=r[i]).s_size){if(this.cursor=e-_.s_size,!_.method)return _.result;var m=_.method();if(this.cursor=e-_.s_size,m)return _.result}if((i=_.substring_i)<0)return 0}},replace_s:function(r,t,i){var s=i.length-(t-r);return b=b.substring(0,r)+i+b.substring(t),this.limit+=s,this.cursor>=t?this.cursor+=s:this.cursor>r&&(this.cursor=r),s},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>b.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),b.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.sv.js b/latest/_static/javascripts/lunr/lunr.sv.js new file mode 100644 index 000000000..6daf5f9d8 --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.sv.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,l,n;e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=(r=e.stemmerSupport.Among,l=e.stemmerSupport.SnowballProgram,n=new function(){var n,t,i=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],s=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],o=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],u=[119,127,149],m=new l;this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var e,r=m.cursor;return function(){var e,r=m.cursor+3;if(t=m.limit,0<=r||r<=m.limit){for(n=r;;){if(e=m.cursor,m.in_grouping(o,97,246)){m.cursor=e;break}if(m.cursor=e,m.cursor>=m.limit)return;m.cursor++}for(;!m.out_grouping(o,97,246);){if(m.cursor>=m.limit)return;m.cursor++}(t=m.cursor)=t&&(m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(i,37),m.limit_backward=r,e))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.in_grouping_b(u,98,121)&&m.slice_del()}}(),m.cursor=m.limit,e=m.limit_backward,m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.find_among_b(s,7)&&(m.cursor=m.limit,m.ket=m.cursor,m.cursor>m.limit_backward&&(m.bra=--m.cursor,m.slice_del())),m.limit_backward=e),m.cursor=m.limit,function(){var e,r;if(m.cursor>=t){if(r=m.limit_backward,m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(a,5))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.slice_from("lös");break;case 3:m.slice_from("full")}m.limit_backward=r}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.th.js b/latest/_static/javascripts/lunr/lunr.th.js new file mode 100644 index 000000000..ee8ef373a --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.th.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(t){if(void 0===t)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===t.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==t.version[0];t.th=function(){this.pipeline.reset(),this.pipeline.add(t.th.trimmer),i?this.tokenizer=t.th.tokenizer:(t.tokenizer&&(t.tokenizer=t.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=t.th.tokenizer))},t.th.wordCharacters="[฀-๿]",t.th.trimmer=t.trimmerSupport.generateTrimmer(t.th.wordCharacters),t.Pipeline.registerFunction(t.th.trimmer,"trimmer-th");var n=t.wordcut;n.init(),t.th.tokenizer=function(e){if(!arguments.length||null==e||null==e)return[];if(Array.isArray(e))return e.map(function(e){return i?new t.Token(e):e});var r=e.toString().replace(/^\s+/,"");return n.cut(r).split("|")}}}); \ No newline at end of file diff --git a/latest/_static/javascripts/lunr/lunr.tr.js b/latest/_static/javascripts/lunr/lunr.tr.js new file mode 100644 index 000000000..e8fb5a7df --- /dev/null +++ b/latest/_static/javascripts/lunr/lunr.tr.js @@ -0,0 +1 @@ +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var mr,dr,i;r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=(mr=r.stemmerSupport.Among,dr=r.stemmerSupport.SnowballProgram,i=new function(){var t,r=[new mr("m",-1,-1),new mr("n",-1,-1),new mr("miz",-1,-1),new mr("niz",-1,-1),new mr("muz",-1,-1),new mr("nuz",-1,-1),new mr("müz",-1,-1),new mr("nüz",-1,-1),new mr("mız",-1,-1),new mr("nız",-1,-1)],i=[new mr("leri",-1,-1),new mr("ları",-1,-1)],e=[new mr("ni",-1,-1),new mr("nu",-1,-1),new mr("nü",-1,-1),new mr("nı",-1,-1)],n=[new mr("in",-1,-1),new mr("un",-1,-1),new mr("ün",-1,-1),new mr("ın",-1,-1)],u=[new mr("a",-1,-1),new mr("e",-1,-1)],o=[new mr("na",-1,-1),new mr("ne",-1,-1)],s=[new mr("da",-1,-1),new mr("ta",-1,-1),new mr("de",-1,-1),new mr("te",-1,-1)],c=[new mr("nda",-1,-1),new mr("nde",-1,-1)],l=[new mr("dan",-1,-1),new mr("tan",-1,-1),new mr("den",-1,-1),new mr("ten",-1,-1)],a=[new mr("ndan",-1,-1),new mr("nden",-1,-1)],m=[new mr("la",-1,-1),new mr("le",-1,-1)],d=[new mr("ca",-1,-1),new mr("ce",-1,-1)],f=[new mr("im",-1,-1),new mr("um",-1,-1),new mr("üm",-1,-1),new mr("ım",-1,-1)],b=[new mr("sin",-1,-1),new mr("sun",-1,-1),new mr("sün",-1,-1),new mr("sın",-1,-1)],w=[new mr("iz",-1,-1),new mr("uz",-1,-1),new mr("üz",-1,-1),new mr("ız",-1,-1)],_=[new mr("siniz",-1,-1),new mr("sunuz",-1,-1),new mr("sünüz",-1,-1),new mr("sınız",-1,-1)],k=[new mr("lar",-1,-1),new mr("ler",-1,-1)],p=[new mr("niz",-1,-1),new mr("nuz",-1,-1),new mr("nüz",-1,-1),new mr("nız",-1,-1)],g=[new mr("dir",-1,-1),new mr("tir",-1,-1),new mr("dur",-1,-1),new mr("tur",-1,-1),new mr("dür",-1,-1),new mr("tür",-1,-1),new mr("dır",-1,-1),new mr("tır",-1,-1)],y=[new mr("casına",-1,-1),new mr("cesine",-1,-1)],z=[new mr("di",-1,-1),new mr("ti",-1,-1),new mr("dik",-1,-1),new mr("tik",-1,-1),new mr("duk",-1,-1),new mr("tuk",-1,-1),new mr("dük",-1,-1),new mr("tük",-1,-1),new mr("dık",-1,-1),new mr("tık",-1,-1),new mr("dim",-1,-1),new mr("tim",-1,-1),new mr("dum",-1,-1),new mr("tum",-1,-1),new mr("düm",-1,-1),new mr("tüm",-1,-1),new mr("dım",-1,-1),new mr("tım",-1,-1),new mr("din",-1,-1),new mr("tin",-1,-1),new mr("dun",-1,-1),new mr("tun",-1,-1),new mr("dün",-1,-1),new mr("tün",-1,-1),new mr("dın",-1,-1),new mr("tın",-1,-1),new mr("du",-1,-1),new mr("tu",-1,-1),new mr("dü",-1,-1),new mr("tü",-1,-1),new mr("dı",-1,-1),new mr("tı",-1,-1)],h=[new mr("sa",-1,-1),new mr("se",-1,-1),new mr("sak",-1,-1),new mr("sek",-1,-1),new mr("sam",-1,-1),new mr("sem",-1,-1),new mr("san",-1,-1),new mr("sen",-1,-1)],v=[new mr("miş",-1,-1),new mr("muş",-1,-1),new mr("müş",-1,-1),new mr("mış",-1,-1)],q=[new mr("b",-1,1),new mr("c",-1,2),new mr("d",-1,3),new mr("ğ",-1,4)],C=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],P=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],F=[65],S=[65],W=[["a",[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],["e",[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],101,252],["ı",[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],["i",[17],101,105],["o",F,111,117],["ö",S,246,252],["u",F,111,117]],L=new dr;function x(r,i,e){for(;;){var n=L.limit-L.cursor;if(L.in_grouping_b(r,i,e)){L.cursor=L.limit-n;break}if(L.cursor=L.limit-n,L.cursor<=L.limit_backward)return!1;L.cursor--}return!0}function A(){var r,i;r=L.limit-L.cursor,x(C,97,305);for(var e=0;eL.limit_backward&&(L.cursor--,e=L.limit-L.cursor,i()))?(L.cursor=L.limit-e,!0):(L.cursor=L.limit-n,r()?(L.cursor=L.limit-n,!1):(L.cursor=L.limit-n,!(L.cursor<=L.limit_backward)&&(L.cursor--,!!i()&&(L.cursor=L.limit-n,!0))))}function j(r){return E(r,function(){return L.in_grouping_b(C,97,305)})}function T(){return j(function(){return L.eq_s_b(1,"n")})}function Z(){return j(function(){return L.eq_s_b(1,"y")})}function B(){return L.find_among_b(r,10)&&E(function(){return L.in_grouping_b(P,105,305)},function(){return L.out_grouping_b(C,97,305)})}function D(){return A()&&L.in_grouping_b(P,105,305)&&j(function(){return L.eq_s_b(1,"s")})}function G(){return L.find_among_b(i,2)}function H(){return A()&&L.find_among_b(n,4)&&T()}function I(){return A()&&L.find_among_b(s,4)}function J(){return A()&&L.find_among_b(c,2)}function K(){return A()&&L.find_among_b(f,4)&&Z()}function M(){return A()&&L.find_among_b(b,4)}function N(){return A()&&L.find_among_b(w,4)&&Z()}function O(){return L.find_among_b(_,4)}function Q(){return A()&&L.find_among_b(k,2)}function R(){return A()&&L.find_among_b(g,8)}function U(){return A()&&L.find_among_b(z,32)&&Z()}function V(){return L.find_among_b(h,8)&&Z()}function X(){return A()&&L.find_among_b(v,4)&&Z()}function Y(){var r=L.limit-L.cursor;return!(X()||(L.cursor=L.limit-r,U()||(L.cursor=L.limit-r,V()||(L.cursor=L.limit-r,L.eq_s_b(3,"ken")&&Z()))))}function $(){if(L.find_among_b(y,2)){var r=L.limit-L.cursor;if(O()||(L.cursor=L.limit-r,Q()||(L.cursor=L.limit-r,K()||(L.cursor=L.limit-r,M()||(L.cursor=L.limit-r,N()||(L.cursor=L.limit-r))))),X())return!1}return!0}function rr(){if(!A()||!L.find_among_b(p,4))return!0;var r=L.limit-L.cursor;return!U()&&(L.cursor=L.limit-r,!V())}function ir(){var r,i,e,n=L.limit-L.cursor;if(L.ket=L.cursor,t=!0,Y()&&(L.cursor=L.limit-n,$()&&(L.cursor=L.limit-n,function(){if(Q()){L.bra=L.cursor,L.slice_del();var r=L.limit-L.cursor;return L.ket=L.cursor,R()||(L.cursor=L.limit-r,U()||(L.cursor=L.limit-r,V()||(L.cursor=L.limit-r,X()||(L.cursor=L.limit-r)))),t=!1}return!0}()&&(L.cursor=L.limit-n,rr()&&(L.cursor=L.limit-n,e=L.limit-L.cursor,!(O()||(L.cursor=L.limit-e,N()||(L.cursor=L.limit-e,M()||(L.cursor=L.limit-e,K()))))||(L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,X()||(L.cursor=L.limit-i),0)))))){if(L.cursor=L.limit-n,!R())return;L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,r=L.limit-L.cursor,O()||(L.cursor=L.limit-r,Q()||(L.cursor=L.limit-r,K()||(L.cursor=L.limit-r,M()||(L.cursor=L.limit-r,N()||(L.cursor=L.limit-r))))),X()||(L.cursor=L.limit-r)}L.bra=L.cursor,L.slice_del()}function er(){var r,i,e,n;if(L.ket=L.cursor,L.eq_s_b(2,"ki")){if(r=L.limit-L.cursor,I())return L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,Q()?(L.bra=L.cursor,L.slice_del(),er()):(L.cursor=L.limit-i,B()&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()))),!0;if(L.cursor=L.limit-r,H()){if(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,e=L.limit-L.cursor,G())L.bra=L.cursor,L.slice_del();else{if(L.cursor=L.limit-e,L.ket=L.cursor,!B()&&(L.cursor=L.limit-e,!D()&&(L.cursor=L.limit-e,!er())))return!0;L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())}return!0}if(L.cursor=L.limit-r,J()){if(n=L.limit-L.cursor,G())L.bra=L.cursor,L.slice_del();else if(L.cursor=L.limit-n,D())L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er());else if(L.cursor=L.limit-n,!er())return!1;return!0}}return!1}function nr(r){if(L.ket=L.cursor,!J()&&(L.cursor=L.limit-r,!A()||!L.find_among_b(o,2)))return!1;var i=L.limit-L.cursor;if(G())L.bra=L.cursor,L.slice_del();else if(L.cursor=L.limit-i,D())L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er());else if(L.cursor=L.limit-i,!er())return!1;return!0}function tr(r){if(L.ket=L.cursor,!(A()&&L.find_among_b(a,2)||(L.cursor=L.limit-r,A()&&L.find_among_b(e,4))))return!1;var i=L.limit-L.cursor;return!(!D()&&(L.cursor=L.limit-i,!G()))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()),!0)}function ur(){var r,i=L.limit-L.cursor;return L.ket=L.cursor,!!(H()||(L.cursor=L.limit-i,A()&&L.find_among_b(m,2)&&Z()))&&(L.bra=L.cursor,L.slice_del(),r=L.limit-L.cursor,L.ket=L.cursor,!(!Q()||(L.bra=L.cursor,L.slice_del(),!er()))||(L.cursor=L.limit-r,L.ket=L.cursor,(B()||(L.cursor=L.limit-r,D()||(L.cursor=L.limit-r,er())))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())),!0))}function or(){var r,i,e=L.limit-L.cursor;if(L.ket=L.cursor,!(I()||(L.cursor=L.limit-e,A()&&L.in_grouping_b(P,105,305)&&Z()||(L.cursor=L.limit-e,A()&&L.find_among_b(u,2)&&Z()))))return!1;if(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,r=L.limit-L.cursor,B())L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,Q()||(L.cursor=L.limit-i);else if(L.cursor=L.limit-r,!Q())return!0;return L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,er(),!0}function sr(){var r,i,e=L.limit-L.cursor;if(L.ket=L.cursor,Q())return L.bra=L.cursor,L.slice_del(),void er();if(L.cursor=L.limit-e,L.ket=L.cursor,A()&&L.find_among_b(d,2)&&T())if(L.bra=L.cursor,L.slice_del(),r=L.limit-L.cursor,L.ket=L.cursor,G())L.bra=L.cursor,L.slice_del();else{if(L.cursor=L.limit-r,L.ket=L.cursor,!B()&&(L.cursor=L.limit-r,!D())){if(L.cursor=L.limit-r,L.ket=L.cursor,!Q())return;if(L.bra=L.cursor,L.slice_del(),!er())return}L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())}else if(L.cursor=L.limit-e,!nr(e)&&(L.cursor=L.limit-e,!tr(e))){if(L.cursor=L.limit-e,L.ket=L.cursor,A()&&L.find_among_b(l,4))return L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,i=L.limit-L.cursor,void(B()?(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())):(L.cursor=L.limit-i,Q()?(L.bra=L.cursor,L.slice_del()):L.cursor=L.limit-i,er()));if(L.cursor=L.limit-e,!ur()){if(L.cursor=L.limit-e,G())return L.bra=L.cursor,void L.slice_del();L.cursor=L.limit-e,er()||(L.cursor=L.limit-e,or()||(L.cursor=L.limit-e,L.ket=L.cursor,(B()||(L.cursor=L.limit-e,D()))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()))))}}}function cr(r,i,e){if(L.cursor=L.limit-r,function(){for(;;){var r=L.limit-L.cursor;if(L.in_grouping_b(C,97,305)){L.cursor=L.limit-r;break}if(L.cursor=L.limit-r,L.cursor<=L.limit_backward)return!1;L.cursor--}return!0}()){var n=L.limit-L.cursor;if(!L.eq_s_b(1,i)&&(L.cursor=L.limit-n,!L.eq_s_b(1,e)))return!0;L.cursor=L.limit-r;var t=L.cursor;return L.insert(L.cursor,L.cursor,e),L.cursor=t,!1}return!0}function lr(r,i,e){for(;!L.eq_s(i,e);){if(L.cursor>=L.limit)return!0;L.cursor++}return i!=L.limit||(L.cursor=r,!1)}function ar(){var r,i,e=L.cursor;return!(!lr(r=L.cursor,2,"ad")||!lr(L.cursor=r,5,"soyad"))&&(L.limit_backward=e,L.cursor=L.limit,i=L.limit-L.cursor,(L.eq_s_b(1,"d")||(L.cursor=L.limit-i,L.eq_s_b(1,"g")))&&cr(i,"a","ı")&&cr(i,"e","i")&&cr(i,"o","u")&&cr(i,"ö","ü"),L.cursor=L.limit,function(){var r;if(L.ket=L.cursor,r=L.find_among_b(q,4))switch(L.bra=L.cursor,r){case 1:L.slice_from("p");break;case 2:L.slice_from("ç");break;case 3:L.slice_from("t");break;case 4:L.slice_from("k")}}(),!0)}this.setCurrent=function(r){L.setCurrent(r)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){return!!(function(){for(var r,i=L.cursor,e=2;;){for(r=L.cursor;!L.in_grouping(C,97,305);){if(L.cursor>=L.limit)return L.cursor=r,!(0e&&(this._events[n].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[n].length),"function"==typeof console.trace&&console.trace()));return this},r.prototype.once=function(n,t){if(!a(t))throw TypeError("listener must be a function");var e=!1;function r(){this.removeListener(n,r),e||(e=!0,t.apply(this,arguments))}return r.listener=t,this.on(n,r),this},r.prototype.removeListener=function(n,t){var e,r,i,o;if(!a(t))throw TypeError("listener must be a function");if(!this._events||!this._events[n])return this;if(i=(e=this._events[n]).length,r=-1,e===t||a(e.listener)&&e.listener===t)delete this._events[n],this._events.removeListener&&this.emit("removeListener",n,t);else if(c(e)){for(o=i;0this.maxLength)return i();if(!this.stat&&p(this.cache,o)){var t=this.cache[o];if(Array.isArray(t)&&(t="DIR"),!n||"DIR"===t)return i(null,t);if(n&&"FILE"===t)return i()}var e=this.statCache[o];if(void 0!==e){if(!1===e)return i(null,e);var s=e.isDirectory()?"DIR":"FILE";return n&&"FILE"===s?i():i(null,s,e)}var a=this,c=d("stat\0"+o,function(n,e){{if(e&&e.isSymbolicLink())return u.stat(o,function(n,t){n?a._stat2(r,o,null,e,i):a._stat2(r,o,n,t,i)});a._stat2(r,o,n,e,i)}});c&&u.lstat(o,c)},b.prototype._stat2=function(n,t,e,r,i){if(e)return this.statCache[t]=!1,i();var o="/"===n.slice(-1);if(this.statCache[t]=r,"/"===t.slice(-1)&&!r.isDirectory())return i(null,!1,r);var s=r.isDirectory()?"DIR":"FILE";return this.cache[t]=this.cache[t]||s,o&&"DIR"!==s?i():i(null,s,r)}}).call(this,_("_process"))},{"./common.js":15,"./sync.js":17,_process:24,assert:9,events:14,fs:12,inflight:18,inherits:19,minimatch:20,once:21,path:22,"path-is-absolute":23,util:28}],17:[function(e,r,n){(function(i){(r.exports=n).GlobSync=h;var s=e("fs"),c=e("minimatch"),g=(c.Minimatch,e("./glob.js").Glob,e("util"),e("path")),u=e("assert"),l=e("path-is-absolute"),t=e("./common.js"),o=(t.alphasort,t.alphasorti,t.setopts),a=t.ownProp,f=t.childrenIgnored;function n(n,t){if("function"==typeof t||3===arguments.length)throw new TypeError("callback provided to sync glob\nSee: https://github.com/isaacs/node-glob/issues/167");return new h(n,t).found}function h(n,t){if(!n)throw new Error("must provide pattern");if("function"==typeof t||3===arguments.length)throw new TypeError("callback provided to sync glob\nSee: https://github.com/isaacs/node-glob/issues/167");if(!(this instanceof h))return new h(n,t);if(o(this,n,t),this.noprocess)return this;var e=this.minimatch.set.length;this.matches=new Array(e);for(var r=0;rthis.maxLength)return!1;if(!this.stat&&a(this.cache,t)){var r=this.cache[t];if(Array.isArray(r)&&(r="DIR"),!e||"DIR"===r)return r;if(e&&"FILE"===r)return!1}var i=this.statCache[t];if(!i){var o;try{o=s.lstatSync(t)}catch(n){return!1}if(o.isSymbolicLink())try{i=s.statSync(t)}catch(n){i=o}else i=o}r=(this.statCache[t]=i).isDirectory()?"DIR":"FILE";return this.cache[t]=this.cache[t]||r,(!e||"DIR"===r)&&r},h.prototype._mark=function(n){return t.mark(this,n)},h.prototype._makeAbs=function(n){return t.makeAbs(this,n)}}).call(this,e("_process"))},{"./common.js":15,"./glob.js":16,_process:24,assert:9,fs:12,minimatch:20,path:22,"path-is-absolute":23,util:28}],18:[function(t,r,n){(function(s){var n=t("wrappy"),a=Object.create(null),e=t("once");r.exports=n(function(n,t){return a[n]?(a[n].push(t),null):(a[n]=[t],o=n,e(function n(){var t=a[o],e=t.length,r=function(n){for(var t=n.length,e=[],r=0;re?(t.splice(0,e),s.nextTick(function(){n.apply(null,r)})):delete a[o]}}));var o})}).call(this,t("_process"))},{_process:24,once:21,wrappy:29}],19:[function(n,t,e){"function"==typeof Object.create?t.exports=function(n,t){n.super_=t,n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(n,t){n.super_=t;var e=function(){};e.prototype=t.prototype,n.prototype=new e,n.prototype.constructor=n}},{}],20:[function(n,t,e){(t.exports=s).Minimatch=i;var u={sep:"/"};try{u=n("path")}catch(n){}var M=s.GLOBSTAR=i.GLOBSTAR={},r=n("brace-expansion"),C={"!":{open:"(?:(?!(?:",close:"))[^/]*?)"},"?":{open:"(?:",close:")?"},"+":{open:"(?:",close:")+"},"*":{open:"(?:",close:")*"},"@":{open:"(?:",close:")"}},P="[^/]",z=P+"*?",B="().*{}+?[]^$\\!".split("").reduce(function(n,t){return n[t]=!0,n},{});var l=/\/+/;function o(t,e){t=t||{},e=e||{};var r={};return Object.keys(e).forEach(function(n){r[n]=e[n]}),Object.keys(t).forEach(function(n){r[n]=t[n]}),r}function s(n,t,e){if("string"!=typeof t)throw new TypeError("glob pattern string required");return e||(e={}),!(!e.nocomment&&"#"===t.charAt(0))&&(""===t.trim()?""===n:new i(t,e).match(n))}function i(n,t){if(!(this instanceof i))return new i(n,t);if("string"!=typeof n)throw new TypeError("glob pattern string required");t||(t={}),n=n.trim(),"/"!==u.sep&&(n=n.split(u.sep).join("/")),this.options=t,this.set=[],this.pattern=n,this.regexp=null,this.negate=!1,this.comment=!1,this.empty=!1,this.make()}function a(n,t){if(t||(t=this instanceof i?this.options:{}),void 0===(n=void 0===n?this.pattern:n))throw new TypeError("undefined pattern");return t.nobrace||!n.match(/\{.*\}/)?[n]:r(n)}s.filter=function(r,i){return i=i||{},function(n,t,e){return s(n,r,i)}},s.defaults=function(r){if(!r||!Object.keys(r).length)return s;var i=s,n=function(n,t,e){return i.minimatch(n,t,o(r,e))};return n.Minimatch=function(n,t){return new i.Minimatch(n,o(r,t))},n},i.defaults=function(n){return n&&Object.keys(n).length?s.defaults(n).Minimatch:i},i.prototype.debug=function(){},i.prototype.make=function(){if(this._made)return;var n=this.pattern,t=this.options;if(!t.nocomment&&"#"===n.charAt(0))return void(this.comment=!0);if(!n)return void(this.empty=!0);this.parseNegate();var e=this.globSet=this.braceExpand();t.debug&&(this.debug=console.error);this.debug(this.pattern,e),e=this.globParts=e.map(function(n){return n.split(l)}),this.debug(this.pattern,e),e=e.map(function(n,t,e){return n.map(this.parse,this)},this),this.debug(this.pattern,e),e=e.filter(function(n){return-1===n.indexOf(!1)}),this.debug(this.pattern,e),this.set=e},i.prototype.parseNegate=function(){var n=this.pattern,t=!1,e=this.options,r=0;if(e.nonegate)return;for(var i=0,o=n.length;i>> no match, partial?",n,f,t,h),f!==s))}if("string"==typeof u?(c=r.nocase?l.toLowerCase()===u.toLowerCase():l===u,this.debug("string match",u,l,c)):(c=l.match(u),this.debug("pattern match",u,l,c)),!c)return!1}if(i===s&&o===a)return!0;if(i===s)return e;if(o===a)return i===s-1&&""===n[i];throw new Error("wtf?")}},{"brace-expansion":11,path:22}],21:[function(n,t,e){var r=n("wrappy");function i(n){var t=function(){return t.called?t.value:(t.called=!0,t.value=n.apply(this,arguments))};return t.called=!1,t}function o(n){var t=function(){if(t.called)throw new Error(t.onceError);return t.called=!0,t.value=n.apply(this,arguments)},e=n.name||"Function wrapped with `once`";return t.onceError=e+" shouldn't be called more than once",t.called=!1,t}t.exports=r(i),t.exports.strict=r(o),i.proto=i(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return i(this)},configurable:!0}),Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return o(this)},configurable:!0})})},{wrappy:29}],22:[function(n,t,u){(function(i){function o(n,t){for(var e=0,r=n.length-1;0<=r;r--){var i=n[r];"."===i?n.splice(r,1):".."===i?(n.splice(r,1),e++):e&&(n.splice(r,1),e--)}if(t)for(;e--;e)n.unshift("..");return n}var t=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,s=function(n){return t.exec(n).slice(1)};function a(n,t){if(n.filter)return n.filter(t);for(var e=[],r=0;r":">",'"':""","'":"'","`":"`"},D=d.invert(N),F=function(t){var e=function(n){return t[n]},n="(?:"+d.keys(t).join("|")+")",r=RegExp(n),i=RegExp(n,"g");return function(n){return n=null==n?"":""+n,r.test(n)?n.replace(i,e):n}};d.escape=F(N),d.unescape=F(D),d.result=function(n,t,e){var r=null==n?void 0:n[t];return void 0===r&&(r=e),d.isFunction(r)?r.call(n):r};var M=0;d.uniqueId=function(n){var t=++M+"";return n?n+t:t},d.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var C=/(.)^/,P={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},z=/\\|'|\r|\n|\u2028|\u2029/g,B=function(n){return"\\"+P[n]};d.template=function(o,n,t){!n&&t&&(n=t),n=d.defaults({},n,d.templateSettings);var e=RegExp([(n.escape||C).source,(n.interpolate||C).source,(n.evaluate||C).source].join("|")+"|$","g"),s=0,a="__p+='";o.replace(e,function(n,t,e,r,i){return a+=o.slice(s,i).replace(z,B),s=i+n.length,t?a+="'+\n((__t=("+t+"))==null?'':_.escape(__t))+\n'":e?a+="'+\n((__t=("+e+"))==null?'':__t)+\n'":r&&(a+="';\n"+r+"\n__p+='"),n}),a+="';\n",n.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{var r=new Function(n.variable||"obj","_",a)}catch(n){throw n.source=a,n}var i=function(n){return r.call(this,n,d)},c=n.variable||"obj";return i.source="function("+c+"){\n"+a+"}",i},d.chain=function(n){var t=d(n);return t._chain=!0,t};var U=function(n,t){return n._chain?d(t).chain():t};d.mixin=function(e){d.each(d.functions(e),function(n){var t=d[n]=e[n];d.prototype[n]=function(){var n=[this._wrapped];return i.apply(n,arguments),U(this,t.apply(d,n))}})},d.mixin(d),d.each(["pop","push","reverse","shift","sort","splice","unshift"],function(t){var e=r[t];d.prototype[t]=function(){var n=this._wrapped;return e.apply(n,arguments),"shift"!==t&&"splice"!==t||0!==n.length||delete n[0],U(this,n)}}),d.each(["concat","join","slice"],function(n){var t=r[n];d.prototype[n]=function(){return U(this,t.apply(this._wrapped,arguments))}}),d.prototype.value=function(){return this._wrapped},d.prototype.valueOf=d.prototype.toJSON=d.prototype.value,d.prototype.toString=function(){return""+this._wrapped}}).call(this)},{}],26:[function(n,t,e){arguments[4][19][0].apply(e,arguments)},{dup:19}],27:[function(n,t,e){t.exports=function(n){return n&&"object"==typeof n&&"function"==typeof n.copy&&"function"==typeof n.fill&&"function"==typeof n.readUInt8}},{}],28:[function(h,n,k){(function(r,i){var a=/%[sdj%]/g;k.format=function(n){if(!_(n)){for(var t=[],e=0;e 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 document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + 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.5.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 ); + }; + +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 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + 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 ) { + 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 ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // 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 ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + 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; + }, + + // 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 flat( 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.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( 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(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = 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]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // 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 + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + 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" ) + }, + + rhtml = /HTML$/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-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + 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(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { 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 + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.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 ) { + 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 && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // 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 ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } 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 && + inDisabledFieldset( 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 ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * 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 + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + 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 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + 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 ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* 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 ) { + + var input; + + // 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( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // 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( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + 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" ); + } + + // Support: Opera 10 - 11 only + // 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 + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + 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 + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + 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 ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + 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 + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ 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 ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + 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 += ""; + + /* eslint-disable max-len */ + + 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; + /* eslint-enable max-len */ + + }; + }, + + "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 || 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 ) { + // eslint-disable-next-line no-unused-expressions + 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 > length ? + 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 ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + 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; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + 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 ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + 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 documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +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. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +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 = elem.nodeType && + ( 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 ); + + + +( 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; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // 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, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +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, attached, 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; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +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 ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + 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 = Object.create( null ); + } + 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 ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ 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() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + 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 + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( 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; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +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, + code: 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 ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// 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 + + // 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 = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + 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.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + Assumptions — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Assumptions + + ¶ + +

+
+

+ Hardware and software environments + + ¶ + +

+

+ No assumptions on a specific hardware environment are made. It must be possible +to create an array library adhering to this standard that runs (efficiently) on +a variety of different hardware: CPUs with different architectures, GPUs, +distributed systems and TPUs and other emerging accelerators. +

+

+ The same applies to software environments: it must be possible to create an +array library adhering to this standard that runs efficiently independent of +what compilers, build-time or run-time execution environment, or distribution +and install method is employed. Parallel execution, JIT compilation, and +delayed (lazy) evaluation must all be possible. +

+

+ The variety of hardware and software environments puts + + constraints + + on choices +made in the API standard. For example, JIT compilers may require output dtypes +of functions to be predictable from input dtypes only rather than input values. +

+
+
+ + +

+ Dependencies + + ¶ + +

+

+ The only dependency that’s assumed in this standard is that on Python itself. +Python >= 3.8 is assumed, motivated by the use of positional-only parameters +(see + + + function and method signatures + + + ). +

+

+ Importantly, array libraries are not assumed to be aware of each other, or of +a common array-specific layer. The + + + use cases + + + do not require +such a dependency, and building and evolving an array library is easier without +such a coupling. Facilitation support of multiple array types in downstream +libraries is an important use case however, the assumed dependency structure +for that is: +

+

+ dependency assumptions diagram +

+

+ Array libraries may know how to interoperate with each other, for example by +constructing their own array type from that of another library or by shared +memory use of an array (see + + + Data interchange mechanisms + + + ). +This can be done without a dependency though - only adherence to a protocol is +enough. +

+

+ Array-consuming libraries will have to depend on one or more array libraries. +That could be a “soft dependency” though, meaning retrieving an array library +namespace from array instances that are passed in, but not explicitly doing + + + import + + + arraylib_name + + + . +

+
+
+

+ Backwards compatibility + + ¶ + +

+

+ The assumption made during creation of this standard is that libraries are +constrained by backwards compatibility guarantees to their users, and are +likely unwilling to make significant backwards-incompatible changes for the +purpose of conforming to this standard. Therefore it is assumed that the +standard will be made available in a new namespace within each library, or the +library will provide a way to retrieve a module or module-like object that +adheres to this standard. See + + + How to adopt this API + + + for more details. +

+
+
+

+ Production code & interactive use + + ¶ + +

+

+ It is assumed that the primary use case is writing production code, for example +in array-consuming libraries. As a consequence, making it easy to ensure that +code is written as intended and has unambiguous semantics is preferred - and +clear exceptions must be raised otherwise. +

+

+ It is also assumed that this does not significantly detract from the +interactive user experience. However, in case existing libraries differ in +behavior, the more strict version of that behavior is typically preferred. A +good example is array inputs to functions - while NumPy accepts lists, tuples, +generators, and anything else that could be turned into an array, most other +libraries only accept their own array types. This standard follows the latter choice. +It is likely always possible to put a thin “interactive use convenience layer” +on top of a more strict behavior. +

+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/benchmark_suite.html b/latest/benchmark_suite.html new file mode 100644 index 000000000..e647e257c --- /dev/null +++ b/latest/benchmark_suite.html @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Benchmark suite — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+

+ Benchmark suite + + ¶ + +

+

+ Adding a benchmark suite is planned in the future. +

+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/design_topics/C_API.html b/latest/design_topics/C_API.html new file mode 100644 index 000000000..bef3f18ff --- /dev/null +++ b/latest/design_topics/C_API.html @@ -0,0 +1,748 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C API — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ C API + + ¶ + +

+

+ Use of a C API is out of scope for this array API, as mentioned in + + + Scope (includes out-of-scope / non-goals) + + + . +There are a lot of libraries that do use such an API - in particular via Cython code +or via direct usage of the NumPy C API. When the maintainers of such libraries +want to use this array API standard to support multiple types of arrays, they +need a way to deal with that issue. This section aims to provide some guidance. +

+

+ The assumption in the rest of this section is that performance matters for the library, +and hence the goal is to make other array types work without converting to a + + + numpy.ndarray + + + or another particular array type. If that’s not the case (e.g. for a +visualization package), then other array types can simply be handled by converting +to the supported array type. +

+
+

+ Note +

+

+ Often a zero-copy conversion to + + + numpy.ndarray + + + is possible, at least for CPU arrays. +If that’s the case, this may be a good way to support other array types. +The main difficulty in that case will be getting the return array type right - however, +this standard does provide a Python-level API for array construction that should allow +doing this. A relevant question is if it’s possible to know with +certainty that a conversion will be zero-copy. This may indeed be +possible, see + + + Data interchange mechanisms + + + . +

+
+
+

+ Example situations for C/Cython usage + + ¶ + +

+
+

+ Situation 1: a Python package that is mostly pure Python, with a limited number of Cython extensions + + ¶ + +

+
+

+ Note +

+

+ Projects in this situation include Statsmodels, scikit-bio and QuTiP +

+
+

+ Main strategy: documentation. The functionality using Cython code will not support other array types (or only with conversion to/from + + + numpy.ndarray + + + ), which can be documented per function. +

+
+
+

+ Situation 2: a Python package that contains a lot of Cython code + + ¶ + +

+
+

+ Note +

+

+ Projects in this situation include scikit-learn and scikit-image +

+
+

+ Main strategy: add support for other array types + + per submodule + + . This keeps it manageable to explain to the user which functionality does and doesn’t have support. +

+

+ Longer term: specific support for particular array types (e.g. + + + cupy.ndarray + + + can be supported with Python-only code via + + + cupy.ElementwiseKernel + + + ). +

+
+
+

+ Situation 3: a Python package that uses the NumPy or Python C API directly + + ¶ + +

+
+

+ Note +

+

+ Projects in this situation include SciPy and Astropy +

+
+

+ Strategy: similar to + + situation 2 + + , but the number of submodules that can support all array types may be limited. +

+
+
+
+

+ Device support + + ¶ + +

+

+ Supporting non-CPU array types in code using the C API or Cython seems problematic, +this almost inevitably will require custom device-specific code (e.g., CUDA, ROCm) or +something like JIT compilation with Numba. +

+
+
+

+ Other longer-term approaches + + ¶ + +

+
+

+ Further Python API standardization + + ¶ + +

+

+ There may be cases where it makes sense to standardize additional sets of +functions, because they’re important enough that array libraries tend to +reimplement them. An example of this may be + + special functions + + , as provided +by + + + scipy.special + + + . Bessel and gamma functions for example are commonly +reimplemented by array libraries. This may avoid having to drop into a +particular implementation that does use a C API (e.g., one can then rely on + + + arraylib.special.gamma + + + rather than having to use + + + scipy.special.gamma + + + ). +

+
+
+

+ HPy + + ¶ + +

+

+ + HPy + + is a new project that will provide a higher-level +C API and ABI than CPython offers. A Cython backend targeting HPy will be provided as well. +

+
    +
  • +

    + Better PyPy support +

    +
  • +
  • +

    + Universal ABI - single binary for all supported Python versions +

    +
  • +
  • +

    + Cython backend generating HPy rather than CPython code +

    +
  • +
+

+ HPy isn’t quite ready for mainstream usage today, but once it does it may +help make supporting multiple array libraries or adding non-CPU device +support to Cython more feasible. +

+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/design_topics/accuracy.html b/latest/design_topics/accuracy.html new file mode 100644 index 000000000..26b321d5c --- /dev/null +++ b/latest/design_topics/accuracy.html @@ -0,0 +1,726 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Accuracy — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Accuracy + + ¶ + +

+
+
+

+ Array API specification for minimum accuracy requirements. +

+
+
+
+

+ Arithmetic Operations + + ¶ + +

+

+ The results of element-wise arithmetic operations +

+
    +
  • +

    + + + + + + +

    +
  • +
  • +

    + + + - + + +

    +
  • +
  • +

    + + + * + + +

    +
  • +
  • +

    + + + / + + +

    +
  • +
  • +

    + + + % + + +

    +
  • +
+

+ including the corresponding element-wise array APIs defined in this standard +

+
    +
  • +

    + add +

    +
  • +
  • +

    + subtract +

    +
  • +
  • +

    + multiply +

    +
  • +
  • +

    + divide +

    +
  • +
+

+ for floating-point operands must return the nearest representable value according to IEEE 754-2019 and a supported rounding mode. By default, the rounding mode should be + + + roundTiesToEven + + + (i.e., ties rounded toward the nearest value with an even least significant bit). +

+
+
+

+ Mathematical Functions + + ¶ + +

+

+ This specification does + + not + + precisely define the behavior of the following functions +

+
    +
  • +

    + acos +

    +
  • +
  • +

    + acosh +

    +
  • +
  • +

    + asin +

    +
  • +
  • +

    + asinh +

    +
  • +
  • +

    + atan +

    +
  • +
  • +

    + atan2 +

    +
  • +
  • +

    + atanh +

    +
  • +
  • +

    + cos +

    +
  • +
  • +

    + cosh +

    +
  • +
  • +

    + exp +

    +
  • +
  • +

    + expm1 +

    +
  • +
  • +

    + log +

    +
  • +
  • +

    + log1p +

    +
  • +
  • +

    + log2 +

    +
  • +
  • +

    + log10 +

    +
  • +
  • +

    + pow +

    +
  • +
  • +

    + sin +

    +
  • +
  • +

    + sinh +

    +
  • +
  • +

    + tan +

    +
  • +
  • +

    + tanh +

    +
  • +
+

+ except to require specific results for certain argument values that represent boundary cases of interest. +

+
+

+ Note +

+

+ To help readers identify functions lacking precisely defined accuracy behavior, this specification uses the phrase “implementation-dependent approximation” in function descriptions. +

+
+

+ For other argument values, these functions should compute approximations to the results of respective mathematical functions; however, this specification recognizes that array libraries may be constrained by underlying hardware and/or seek to optimize performance over absolute accuracy and, thus, allows some latitude in the choice of approximation algorithms. +

+

+ Although the specification leaves the choice of algorithms to the implementation, this specification recommends (but does not specify) that implementations use the approximation algorithms for IEEE 754-2019 arithmetic contained in + + FDLIBM + + , the freely distributable mathematical library from Sun Microsystems, or some other comparable IEEE 754-2019 compliant mathematical library. +

+
+

+ Note +

+

+ With exception of a few mathematical functions, returning results which are indistinguishable from correctly rounded infinitely precise results is difficult, if not impossible, to achieve due to the algorithms involved, the limits of finite-precision, and error propagation. However, this specification recognizes that numerical accuracy alignment among array libraries is desirable in order to ensure portability and reproducibility. Accordingly, for each mathematical function, the specification test suite includes test values which span a function’s domain and reports the average and maximum deviation from either a designated standard implementation (e.g., an arbitrary precision arithmetic implementation) or an average computed across a subset of known array library implementations. Such reporting aids users who need to know how accuracy varies among libraries and developers who need to check the validity of their implementations. +

+
+
+
+

+ Statistical Functions + + ¶ + +

+

+ This specification does not specify accuracy requirements for statistical functions; however, this specification does expect that a conforming implementation of the array API standard will make a best-effort attempt to ensure that its implementations are theoretically sound and numerically robust. +

+
+

+ Note +

+

+ In order for an array library to pass the specification test suite, an array library’s statistical function implementations must satisfy certain bare-minimum accuracy requirements (e.g., accurate summation of a small set of positive integers). Unfortunately, imposing more rigorous accuracy requirements is not possible without severely curtailing possible implementation algorithms and unduly increasing implementation complexity. +

+
+
+
+

+ Linear Algebra + + ¶ + +

+

+ This specification does not specify accuracy requirements for linear algebra functions; however, this specification does expect that a conforming implementation of the array API standard will make a best-effort attempt to ensure that its implementations are theoretically sound and numerically robust. +

+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/design_topics/copies_views_and_mutation.html b/latest/design_topics/copies_views_and_mutation.html new file mode 100644 index 000000000..f898ff7dd --- /dev/null +++ b/latest/design_topics/copies_views_and_mutation.html @@ -0,0 +1,621 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Copy-view behaviour and mutability — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +

+ Copy-view behaviour and mutability + + ¶ + +

+

+ Strided array implementations (e.g. NumPy, PyTorch, CuPy, MXNet) typically +have the concept of a “view”, meaning an array containing data in memory that +belongs to another array (i.e. a different “view” on the original data). +Views are useful for performance reasons - not copying data to a new location +saves memory and is faster than copying - but can also affect the semantics +of code. This happens when views are combined with + + mutating + + operations. +This simple example illustrates that: +

+
+
+
x = ones(1)
+y = x[:]  # `y` *may* be a view on the data of `x`
+y -= 1  # if `y` is a view, this modifies `x`
+
+
+
+

+ Code as simple as the above example will not be portable between array +libraries - for NumPy/PyTorch/CuPy/MXNet + + + x + + + will contain the value + + + 0 + + + , +while for TensorFlow/JAX/Dask it will contain the value + + + 1 + + + . The combination +of views and mutability is fundamentally problematic here if the goal is to +be able to write code with unambiguous semantics. +

+

+ Views are necessary for getting good performance out of the current strided +array libraries. It is not always clear however when a library will return a +view, and when it will return a copy. This API standard does not attempt to +specify this - libraries can do either. +

+

+ There are several types of operations that do in-place mutation of data +contained in arrays. These include: +

+
    +
  1. +

    + Inplace operators (e.g. + + + *= + + + ) +

    +
  2. +
  3. +

    + Item assignment (e.g. + + + x[0] + + + = + + + 1 + + + ) +

    +
  4. +
  5. +

    + Slice assignment (e.g., + + + x[:2, + + + :] + + + = + + + 3 + + + ) +

    +
  6. +
  7. +

    + The + + + out= + + + keyword present in some strided array libraries (e.g. + + + sin(x, + + + out=y + + + )) +

    +
  8. +
+

+ Libraries like TensorFlow and JAX tend to support inplace operators, provide +alternative syntax for item and slice assignment (e.g. an + + + update_index + + + function or + + + x.at[idx].set(y) + + + ), and have no need for + + + out= + + + . +

+

+ A potential solution could be to make views read-only, or use copy-on-write +semantics. Both are hard to implement and would present significant issues +for backwards compatibility for current strided array libraries. Read-only +views would also not be a full solution, given that mutating the original +(base) array will also result in ambiguous semantics. Hence this API standard +does not attempt to go down this route. +

+

+ Both inplace operators and item/slice assignment can be mapped onto +equivalent functional expressions (e.g. + + + x[idx] + + + = + + + val + + + maps to + + + x.at[idx].set(val) + + + ), and given that both inplace operators and item/slice +assignment are very widely used in both library and end user code, this +standard chooses to include them. +

+

+ The situation with + + + out= + + + is slightly different - it’s less heavily used, and +easier to avoid. It’s also not an optimal API, because it mixes an +“efficiency of implementation” consideration (“you’re allowed to do this +inplace”) with the semantics of a function (“the output + + must + + be placed into +this array). There are libraries that do some form of tracing or abstract +interpretation over a language that does not support mutation (to make +analysis easier); in those cases implementing + + + out= + + + with correct handling of +views may even be impossible to do. There’s alternatives, for example the +donated arguments in JAX or working buffers in LAPACK, that allow the user to +express “you + + may + + overwrite this data, do whatever is fastest”. Given that +those alternatives aren’t widely used in array libraries today, this API +standard chooses to (a) leave out + + + out= + + + , and (b) not specify another method +of reusing arrays that are no longer needed as buffers. +

+

+ This leaves the problem of the initial example - with this API standard it +remains possible to write code that will not work the same for all array +libraries. This is something that the user must be careful about. +

+
+

+ Note +

+

+ It is recommended that users avoid any mutating operations when a view may be involved. +

+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/design_topics/data_interchange.html b/latest/design_topics/data_interchange.html new file mode 100644 index 000000000..8b3c3dce0 --- /dev/null +++ b/latest/design_topics/data_interchange.html @@ -0,0 +1,964 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Data interchange mechanisms — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Data interchange mechanisms + + ¶ + +

+

+ This section discusses the mechanism to convert one type of array into another. +As discussed in the + + + assumptions-dependencies + + + section, + + functions + + provided by an array library are not expected to operate on + + array types + + implemented by another library. Instead, the array can be +converted to a “native” array type. +

+

+ The interchange mechanism must offer the following: +

+
    +
  1. +

    + Data access via a protocol that describes the memory layout of the array +in an implementation-independent manner. + + Rationale: any number of libraries must be able to exchange data, and no +particular package must be needed to do so. + +

    +
  2. +
  3. +

    + Support for all dtypes in this API standard (see + + + Data Types + + + ). +

    +
  4. +
  5. +

    + Device support. It must be possible to determine on what device the array +that is to be converted lives. + + Rationale: there are CPU-only, GPU-only, and multi-device array types; +it’s best to support these with a single protocol (with separate +per-device protocols it’s hard to figure out unambiguous rules for which +protocol gets used, and the situation will get more complex over time +as TPU’s and other accelerators become more widely available). + +

    +
  6. +
  7. +

    + Zero-copy semantics where possible, making a copy only if needed (e.g. +when data is not contiguous in memory). + + Rationale: performance. + +

    +
  8. +
  9. +

    + A Python-side and a C-side interface, the latter with a stable C ABI. + + Rationale: all prominent existing array libraries are implemented in +C/C++, and are released independently from each other. Hence a stable C +ABI is required for packages to work well together. + +

    +
  10. +
+

+ The best candidate for this protocol is DLPack. See the + + RFC to adopt DLPack + + for details. +

+
+

+ Note +

+

+ The main alternatives to DLPack are device-specific methods: +

+
    +
  • +

    + The + + buffer protocol + + on CPU +

    +
  • +
  • +

    + + + __cuda_array_interface__ + + + for CUDA, specified in the Numba documentation + + here + + (Python-side only at the moment) +

    +
  • +
+

+ An issue with device-specific protocols are: if two libraries both +support multiple device types, in which order should the protocols be +tried? A growth in the number of protocols to support each time a new +device gets supported by array libraries (e.g. TPUs, AMD GPUs, emerging +hardware accelerators) also seems undesirable. +

+

+ In addition to the above argument, it is also clear from adoption +patterns that DLPack has the widest support. The buffer protocol, despite +being a lot older and standardized as part of Python itself via PEP 3118, +hardly has any support from array libraries. CPU interoperability is +mostly dealt with via the NumPy-specific + + + __array__ + + + (which, when called, +means the object it is attached to must return a + + + numpy.ndarray + + + containing the data the object holds). +

+
+
+

+ Syntax for data interchange with DLPack + + ¶ + +

+

+ The array API will offer the following syntax for data interchange: +

+
    +
  1. +

    + A + + + from_dlpack(x) + + + function, which accepts (array) objects with a + + + __dlpack__ + + + method and uses that method to construct a new array +containing the data from + + + x + + + . +

    +
  2. +
  3. +

    + + + __dlpack__(self, + + + stream=None) + + + and + + + __dlpack_device__ + + + methods on the +array object, which will be called from within + + + from_dlpack + + + , to query +what device the array is on (may be needed to pass in the correct +stream, e.g. in the case of multiple GPUs) and to access the data. +

    +
  4. +
+
+
+

+ Semantics + + ¶ + +

+

+ DLPack describe the memory layout of strided, n-dimensional arrays. +When a user calls + + + y + + + = + + + from_dlpack(x) + + + , the library implementing + + + x + + + (the +“producer”) will provide access to the data from + + + x + + + to the library +containing + + + from_dlpack + + + (the “consumer”). If possible, this must be +zero-copy (i.e. + + + y + + + will be a + + view + + on + + + x + + + ). If not possible, that library +may make a copy of the data. In both cases: +

+
    +
  • +

    + the producer keeps owning the memory +

    +
  • +
  • +

    + + + y + + + may or may not be a view, therefore the user must keep the +recommendation to avoid mutating + + + y + + + in mind - see + + + Copy-view behaviour and mutability + + + . +

    +
  • +
  • +

    + Both + + + x + + + and + + + y + + + may continue to be used just like arrays created in other ways. +

    +
  • +
+

+ If an array that is accessed via the interchange protocol lives on a +device that the requesting library does not support, it is recommended to +raise a + + + TypeError + + + . +

+

+ Stream handling through the + + + stream + + + keyword applies to CUDA and ROCm (perhaps +to other devices that have a stream concept as well, however those haven’t been +considered in detail). The consumer must pass the stream it will use to the +producer; the producer must synchronize or wait on the stream when necessary. +In the common case of the default stream being used, synchronization will be +unnecessary so asynchronous execution is enabled. +

+
+
+

+ Implementation + + ¶ + +

+

+ + Note that while this API standard largely tries to avoid discussing implementation details, some discussion and requirements are needed here because data interchange requires coordination between implementers on, e.g., memory management. + +

+

+ Diagram of DLPack structs +

+

+ + DLPack diagram. Dark blue are the structs it defines, light blue struct members, gray text enum values of supported devices and data types. + +

+

+ The + + + __dlpack__ + + + method will produce a + + + PyCapsule + + + containing a + + + DLPackManagedTensor + + + , which will be consumed immediately within + + + from_dlpack + + + - therefore it is consumed exactly once, and it will not be +visible to users of the Python API. +

+

+ The consumer must set the PyCapsule name to + + + "used_dltensor" + + + , and call the + + + deleter + + + of the + + + DLPackManagedTensor + + + when it no longer needs the data. +

+

+ When the + + + strides + + + field in the + + + DLTensor + + + struct is + + + NULL + + + , it indicates a +row-major compact array. If the array is of size zero, the data pointer in + + + DLTensor + + + should be set to either + + + NULL + + + or + + + 0 + + + . +

+

+ DLPack version used must be + + + 0.2 + + + <= + + + DLPACK_VERSION + + + < + + + 1.0 + + + . For further +details on DLPack design and how to implement support for it, +refer to + + github.com/dmlc/dlpack + + . +

+
+

+ Warning +

+

+ DLPack contains a + + + device_id + + + , which will be the device ID (an integer, + + + 0, + + + 1, + + + ... + + + ) which the producer library uses. In practice this will likely be the same numbering as that of the consumer, however that is not guaranteed. Depending on the hardware type, it may be possible for the consumer library implementation to look up the actual device from the pointer to the data - this is possible for example for CUDA device pointers. +

+

+ It is recommended that implementers of this array API consider and document +whether the + + + .device + + + attribute of the array returned from + + + from_dlpack + + + is +guaranteed to be in a certain order or not. +

+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/design_topics/device_support.html b/latest/design_topics/device_support.html new file mode 100644 index 000000000..57a17891d --- /dev/null +++ b/latest/design_topics/device_support.html @@ -0,0 +1,822 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Device support — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Device support + + ¶ + +

+

+ For libraries that support execution on more than a single hardware device - e.g. CPU and GPU, or multiple GPUs - it is important to be able to control on which device newly created arrays get placed and where execution happens. Attempting to be fully implicit doesn’t always scale well to situations with multiple GPUs. +

+

+ Existing libraries employ one or more of these three methods to exert such control: +

+
    +
  1. +

    + A global default device, which may be fixed or user-switchable. +

    +
  2. +
  3. +

    + A context manager to control device assignment within its scope. +

    +
  4. +
  5. +

    + Local control via explicit keywords and a method to transfer arrays to another device. +

    +
  6. +
+

+ This standard chooses to add support for method 3 (local control), because it’s the most explicit and granular, with its only downside being verbosity. A context manager may be added in the future - see + + + Out of scope for device support + + + for details. +

+
+

+ Intended usage + + ¶ + +

+

+ The intended usage for the device support in the current version of the +standard is + + device handling in library code + + . The assumed pattern is that +users create arrays (for which they can use all the relevant device syntax +that the library they use provides), and that they then pass those arrays +into library code which may have to do the following: +

+
    +
  • +

    + Create new arrays on the same device as an array that’s passed in. +

    +
  • +
  • +

    + Determine whether two input arrays are present on the same device or not. +

    +
  • +
  • +

    + Move an array from one device to another. +

    +
  • +
  • +

    + Create output arrays on the same device as the input arrays. +

    +
  • +
  • +

    + Pass on a specified device to other library code. +

    +
  • +
+
+

+ Note +

+

+ Given that there is not much that’s currently common in terms of +device-related syntax between different array libraries, the syntax included +in the standard is kept as minimal as possible while enabling the +above-listed use cases. +

+
+
+
+

+ Syntax for device assignment + + ¶ + +

+

+ The array API will offer the following syntax for device assignment and +cross-device data transfer: +

+
    +
  1. +

    + A + + + .device + + + property on the array object, which returns a + + + Device + + + object +representing the device the data in the array is stored on, and supports +comparing devices for equality with + + + == + + + and + + + != + + + within the same library +(e.g., by implementing + + + __eq__ + + + ); comparing device objects from different +libraries is out of scope). +

    +
  2. +
  3. +

    + A + + + device=None + + + keyword for array creation functions, which takes an +instance of a + + + Device + + + object. +

    +
  4. +
  5. +

    + A + + + .to_device(device) + + + method on the array object, with + + + device + + + again being +a + + + Device + + + object, to move an array to a different device. +

    +
  6. +
+
+

+ Note +

+

+ The only way to obtain a + + + Device + + + object is from the + + + .device + + + property on +the array object, hence there is no + + + Device + + + object in the array API itself +that can be instantiated to point to a specific physical or logical device. +

+
+
+
+

+ Semantics + + ¶ + +

+

+ Handling devices is complex, and some frameworks have elaborate policies for +handling device placement. Therefore this section only gives recommendations, +rather than hard requirements: +

+
    +
  • +

    + Respect explicit device assignment (i.e. if the input to the + + + device= + + + keyword +is not + + + None + + + , guarantee that the array is created on the given device, and +raise an exception otherwise). +

    +
  • +
  • +

    + Preserve device assignment as much as possible (e.g. output arrays from a +function are expected to be on the same device as input arrays to the +function). +

    +
  • +
  • +

    + Raise an exception if an operation involves arrays on different devices +(i.e. avoid implicit data transfer between devices). +

    +
  • +
  • +

    + Use a default for + + + device=None + + + which is consistent between functions +within the same library. +

    +
  • +
  • +

    + If a library has multiple ways of controlling device placement, the most +explicit method should have the highest priority. For example: +

    +
      +
    1. +

      + If + + + device= + + + keyword is specified, that always takes precedence +

      +
    2. +
    3. +

      + If + + + device=None + + + , then use the setting from a context manager, if set. +

      +
    4. +
    5. +

      + If no context manager was used, then use the global default device/strategy +

      +
    6. +
    +
  • +
+
+
+ + +

+ Out of scope for device support + + ¶ + +

+

+ Individual libraries may offers APIs for one or more of the following topics, +however those are out of scope for this standard: +

+
    +
  • +

    + Identifying a specific physical or logical device across libraries +

    +
  • +
  • +

    + Setting a default device globally +

    +
  • +
  • +

    + Stream/queue control +

    +
  • +
  • +

    + Distributed allocation +

    +
  • +
  • +

    + Memory pinning +

    +
  • +
  • +

    + A context manager for device control +

    +
  • +
+
+

+ Note +

+

+ A context manager for controlling the default device is present in most existing array +libraries (NumPy being the exception). There are concerns with using a +context manager however. A context manager can be tricky to use at a high +level, since it may affect library code below function calls (non-local +effects). See, e.g., + + this PyTorch issue + + for a discussion on a good context manager API. +

+

+ Adding a context manager may be considered in a future version of this API standard. +

+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/design_topics/index.html b/latest/design_topics/index.html new file mode 100644 index 000000000..e0a9d6769 --- /dev/null +++ b/latest/design_topics/index.html @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Design topics & constraints — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+ + + + + + \ No newline at end of file diff --git a/latest/design_topics/parallelism.html b/latest/design_topics/parallelism.html new file mode 100644 index 000000000..30ccc9c83 --- /dev/null +++ b/latest/design_topics/parallelism.html @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Parallelism — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+

+ Parallelism + + ¶ + +

+

+ Parallelism is mostly, but not completely, an execution or runtime concern +rather than an API concern. Execution semantics are out of scope for this API +standard, and hence won’t be discussed further here. The API related part +involves how libraries allow users to exercise control over the parallelism +they offer, such as: +

+
    +
  • +

    + Via environment variables. This is the method of choice for BLAS libraries and libraries using OpenMP. +

    +
  • +
  • +

    + Via a keyword to individual functions or methods. Examples include the + + + n_jobs + + + keyword used in scikit-learn and the + + + workers + + + keyword used in SciPy. +

    +
  • +
  • +

    + Build-time settings to enable a parallel or distributed backend. +

    +
  • +
  • +

    + Via letting the user set chunk sizes. Dask uses this approach. +

    +
  • +
+

+ When combining multiple libraries, one has to deal with auto-parallelization +semantics and nested parallelism. Two things that could help improve the +coordination of parallelization behavior in a stack of Python libraries are: +

+
    +
  1. +

    + A common API pattern for enabling parallelism +

    +
  2. +
  3. +

    + A common library providing a parallelization layer +

    +
  4. +
+

+ Option (1) may possibly fit in a future version of this array API standard. + + array-api issue 4 + + contains +more detailed discussion on the topic of parallelism. +

+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/design_topics/static_typing.html b/latest/design_topics/static_typing.html new file mode 100644 index 000000000..6c08ddf1b --- /dev/null +++ b/latest/design_topics/static_typing.html @@ -0,0 +1,477 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Static typing — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+

+ Static typing + + ¶ + +

+

+ Good support for static typing both in array libraries and array-consuming +code is desirable. Therefore the exact type or set of types for each +parameter, keyword and return value is specified for functions and methods - +see + + + Function and method signatures + + + . That section specifies arrays +simply as + + + array + + + ; what that means is dealt with in this section. +

+

+ Introducing type annotations in libraries became more relevant only when +Python 2.7 support was dropped at the start of 2020. As a consequence, using +type annotations with array libraries is largely still a work in progress. +This version of the API standard does not deal with trying to type + + array +properties + + like shape, dimensionality or dtype, because that’s not a solved +problem in individual array libraries yet. +

+

+ An + + + array + + + type annotation can mean either the type of one specific array +object, or some superclass or typing Protocol - as long as it is consistent +with the array object specified in + + + Array object + + + . To illustrate by +example: +

+
+
+
# `Array` is a particular class in the library
+def sin(x: Array, / ...) -> Array:
+    ...
+
+
+
+

+ and +

+
+
+
# There's some base class `_BaseArray`, and there may be multiple
+# array subclasses inside the library
+A = TypeVar('A', bound=_BaseArray)
+def sin(x: A, / ...) -> A:
+    ...
+
+
+
+

+ should both be fine. There may be other variations possible. Also note that +this standard does not require that input and output array types are the same +(they’re expected to be defined in the same library though). Given that +array libraries don’t have to be aware of other types of arrays defined in +other libraries (see + + + Dependencies + + + ), this should be enough +for a single array library. +

+

+ That said, an array-consuming library aiming to support multiple array types +may need more - for example a protocol to enable structural subtyping. This +API standard currently takes the position that it does not provide any +reference implementation or package that can or should be relied on at +runtime, hence no such protocol is defined here. This may be dealt with in a +future version of this standard. +

+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/future_API_evolution.html b/latest/future_API_evolution.html new file mode 100644 index 000000000..bcbc0b642 --- /dev/null +++ b/latest/future_API_evolution.html @@ -0,0 +1,616 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Future API standard evolution — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Future API standard evolution + + ¶ + +

+
+

+ Scope extensions + + ¶ + +

+

+ Proposals for scope extensions in a future version of the API standard will follow +the process documented at https://github.com/data-apis/governance/blob/master/process_document.md +

+

+ In summary, proposed new APIs go through several maturity stages, and will only be +accepted in a future version of this API standard once they have reached the “Final” +maturity stage, which means multiple array libraries have compliant implementations +and real-world experience from use of those implementations is available. +

+
+
+

+ Backwards compatibility + + ¶ + +

+

+ Functions, objects, keywords and specified behavior are added to this API standard +only if those are already present in multiple existing array libraries, and if there is +data that those APIs are used. Therefore it is highly unlikely that future versions +of this standard will make backwards-incompatible changes. +

+

+ The aim is for future versions to be 100% backwards compatible with older versions. +Any exceptions must have strong rationales and be clearly documented in the updated +API specification. +

+
+
+ + +

+ Versioning + + ¶ + +

+

+ This API standard uses the following versioning scheme: +

+
    +
  • +

    + The version is date-based, in the form + + + yyyy.mm + + + (e.g., + + + 2020.12 + + + ). +

    +
  • +
  • +

    + The version shall not include a standard way to do + + + alpha + + + / + + + beta + + + / + + + rc + + + or + + + .post + + + / + + + .dev + + + type versions. + + Rationale: that’s for Python packages, not for a standard. + +

    +
  • +
  • +

    + The version must be made available at runtime via an attribute + + + __array_api_version__ + + + by a compliant implementation, in + + + 'yyyy.mm' + + + format +as a string, in the namespace that implements the API standard. + + Rationale: dunder version strings are the standard way of doing this. + +

    +
  • +
+

+ No utilities for dealing with version comparisons need to be provided; given +the format simple string comparisons with Python operators ( + + + =- + + + , + + + < + + + , + + + >= + + + , +etc.) will be enough. +

+
+

+ Note +

+

+ Rationale for the + + + yyyy.mm + + + versioning scheme choice: +the API will be provided as part of a library, which already has a versioning +scheme (typically PEP 440 compliant and in the form + + + major.minor.bugfix + + + ), +and a way to access it via + + + module.__version__ + + + . The API standard version is +completely independent from the package version. Given the standardization +process, it resembles a C/C++ versioning scheme (e.g. + + + C99 + + + , + + + C++14 + + + ) more +than Python package versioning. +

+
+

+ The frequency of releasing a new version of an API standard will likely be at +regular intervals and on the order of one year, however no assumption on +frequency of new versions appearing must be made. +

+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/genindex.html b/latest/genindex.html new file mode 100644 index 000000000..da083e3aa --- /dev/null +++ b/latest/genindex.html @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+

+ Index +

+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/index.html b/latest/index.html new file mode 100644 index 000000000..43a03bc3b --- /dev/null +++ b/latest/index.html @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Python array API standard — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+
+
+

+ A common API for array and tensor Python libraries +

+
+
+ +
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/objects.inv b/latest/objects.inv new file mode 100644 index 000000000..9eabe03c9 Binary files /dev/null and b/latest/objects.inv differ diff --git a/latest/purpose_and_scope.html b/latest/purpose_and_scope.html new file mode 100644 index 000000000..240603cfc --- /dev/null +++ b/latest/purpose_and_scope.html @@ -0,0 +1,1770 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Purpose and scope — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+

+ Purpose and scope + + ¶ + +

+
+

+ Introduction + + ¶ + +

+

+ Python users have a wealth of choice for libraries and frameworks for +numerical computing, data science, machine learning, and deep learning. New +frameworks pushing forward the state of the art in these fields are appearing +every year. One unintended consequence of all this activity and creativity +has been fragmentation in multidimensional array (a.k.a. tensor) libraries - +which are the fundamental data structure for these fields. Choices include +NumPy, Tensorflow, PyTorch, Dask, JAX, CuPy, MXNet, Xarray, and others. +

+

+ The APIs of each of these libraries are largely similar, but with enough +differences that it’s quite difficult to write code that works with multiple +(or all) of these libraries. This array API standard aims to address that +issue, by specifying an API for the most common ways arrays are constructed +and used. +

+

+ Why not simply pick an existing API and bless that as the standard? In short, +because there are often good reasons for the current inconsistencies between +libraries. The most obvious candidate for that existing API is NumPy. However +NumPy was not designed with non-CPU devices, graph-based libraries, or JIT +compilers in mind. Other libraries often deviate from NumPy for good +(necessary) reasons. Choices made in this API standard are often the same +ones NumPy makes, or close to it, but are different where necessary to make +sure all existing array libraries can adopt this API. +

+
+

+ This API standard + + ¶ + +

+

+ This document aims to standardize functionality that exists in most/all array +libraries and either is commonly used or is needed for +consistency/completeness. Usage is determined via analysis of downstream +libraries, see + + + Usage Data + + + . An example of consistency is: there are +functional equivalents for all Python operators (including the rarely used +ones). +

+

+ Beyond usage and consistency, there’s a set of use cases that inform the API +design to ensure it’s fit for a wide range of users and situations - see + + + Use cases + + + . +

+

+ A question that may arise when reading this document is: + + “what about +functionality that’s not present in this document? + + This: +

+
    +
  • +

    + means that there is no guarantee the functionality is present in libraries +adhering to the standard +

    +
  • +
  • +

    + does + + not + + mean that that functionality is unimportant +

    +
  • +
  • +

    + may indicate that that functionality, if present in a particular array +library, is unlikely to be present in all other libraries +

    +
  • +
+
+

+ Note +

+

+ This document is ready for wider community review, but still contains a +number of TODOs, and is expected to change and evolve before a first +official release. See + + + Future API standard evolution + + + for proposed +versioning. +

+
+
+
+

+ History + + ¶ + +

+

+ The first library for numerical and scientific computing in Python was +Numeric, developed in the mid-1990s. In the early 2000s a second, similar +library, Numarray, was created. In 2005 NumPy was written, superceding both +Numeric and Numarray and resolving the fragmentation at that time. For +roughly a decade, NumPy was the only widely used array library. Over the past +~5 years, mainly due to the emergence of new hardware and the rise of deep +learning, many other libraries have appeared, leading to more severe +fragmentation. Concepts and APIs in newer libraries were often inspired by +(or copied from) those in older ones - and then changed or improved upon to +fit new needs and use cases. Individual library authors discussed ideas, +however there was never (before this array API standard) an serious attempt +to coordinate between all libraries to avoid fragmentation and arrive at a +common API standard. +

+

+ The idea for this array API standard grew gradually out of many conversations +between maintainers during 2019-2020. It quickly became clear that any +attempt to write a new “reference library” to fix the current fragmentation +was infeasible - unlike in 2005, there are now too many different use cases +and too many stakeholders, and the speed of innovation is too high. In May +2020 an initial group of maintainers was assembled in the + + Consortium for +Python Data API Standards + + to start drafting a +specification for an array API that could be adopted by each of the existing +array and tensor libraries. That resulted in this document, describing that +API. +

+
+
+
+ + +

+ Scope (includes out-of-scope / non-goals) + + ¶ + +

+

+ This section outlines what is in scope and out of scope for this API standard. +

+
+

+ In scope + + ¶ + +

+

+ The scope of the array API standard includes: +

+
    +
  • +

    + Functionality which needs to be included in an array library for it to adhere +to this standard. +

    +
  • +
  • +

    + Names of functions, methods, classes and other objects. +

    +
  • +
  • +

    + Function signatures, including type annotations. +

    +
  • +
  • +

    + Semantics of functions and methods. I.e. expected outputs including precision +for and dtypes of numerical results. +

    +
  • +
  • +

    + Semantics in the presence of + + + nan + + + ’s, + + + inf + + + ’s, empty arrays (i.e. arrays +including one or more dimensions of size + + + 0 + + + ). +

    +
  • +
  • +

    + Casting rules, broadcasting, indexing +

    +
  • +
  • +

    + Data interchange. I.e. protocols to convert one type of array into another +type, potentially sharing memory. +

    +
  • +
  • +

    + Device support. +

    +
  • +
+

+ Furthermore, meta-topics included in this standard include: +

+
    +
  • +

    + Use cases for the API standard and assumptions made in it +

    +
  • +
  • +

    + API standard adoption +

    +
  • +
  • +

    + API standard versioning +

    +
  • +
  • +

    + Future API standard evolution +

    +
  • +
  • +

    + Array library and API standard versioning +

    +
  • +
  • +

    + Verification of API standard conformance +

    +
  • +
+

+ The concrete set of functionality that is in scope for this version of the +standard is shown in this diagram ( + + TODO: update after deciding on how optional +extensions are dealt with + + ): +

+

+ Scope of array API +

+

+ + Goals + + for the API standard include: +

+
    +
  • +

    + Make it possible for array-consuming libraries to start using multiple types +of arrays as inputs. +

    +
  • +
  • +

    + Enable more sharing and reuse of code built on top of the core functionality +in the API standard. +

    +
  • +
  • +

    + For authors of new array libraries, provide a concrete API that can be +adopted as is, rather than each author having to decide what to borrow from +where and where to deviate. +

    +
  • +
  • +

    + Make the learning curve for users less steep when they switch from one array +library to another one. +

    +
  • +
+
+
+

+ Out of scope + + ¶ + +

+
    +
  1. +

    + Implementations of the standard are out of scope. +

    +

    + + Rationale: the standard will consist of a document and an accompanying test +suite with which the conformance of an implementation can be verified. Actual +implementations will live in array libraries; no reference implementation is +planned. + +

    +
  2. +
  3. +

    + Execution semantics are out of scope. This includes single-threaded vs. +parallel execution, task scheduling and synchronization, eager vs. delayed +evaluation, performance characteristics of a particular implementation of the +standard, and other such topics. +

    +

    + + Rationale: execution is the domain of implementations. Attempting to specify +execution behavior in a standard is likely to require much more fine-grained +coordination between developers of implementations, and hence is likely to +become an obstable to adoption. + +

    +
  4. +
  5. +

    + Non-Python API standardization (e.g., Cython or NumPy C APIs) +

    +

    + + Rationale: this is an important topic for some array-consuming libraries, +but there is no widely shared C/Cython API and hence it doesn’t make sense at +this point in time to standardize anything. See +the + + + C API section + + + for more details. + +

    +
  6. +
  7. +

    + Standardization of these dtypes is out of scope: bfloat16, complex, extended +precision floating point, datetime, string, object and void dtypes. +

    +

    + + Rationale: these dtypes aren’t uniformly supported, and their inclusion at +this point in time could put a significant implementation burden on +libraries. It is expected that some of these dtypes - in particular + + + bfloat16 + + + , + + + complex64 + + + , and + + + complex128 + + + - will be included in a future +version of the standard. + +

    +
  8. +
  9. +

    + The following topics are out of scope: I/O, polynomials, error handling, +testing routines, building and packaging related functionality, methods of +binding compiled code (e.g., + + + cffi + + + , + + + ctypes + + + ), subclassing of an array +class, masked arrays, and missing data. +

    +

    + + Rationale: these topics are not core functionality for an array library, +and/or are too tied to implementation details. + +

    +
  10. +
  11. +

    + NumPy (generalized) universal functions, i.e. ufuncs and gufuncs. +

    +

    + + Rationale: these are NumPy-specific concepts, and are mostly just a +particular way of building regular functions with a few extra +methods/properties. + +

    +
  12. +
  13. +

    + Behaviour for unexpected/invalid input to functions and methods. +

    +
  14. +
+

+ + Rationale: there are a huge amount of ways in which users can provide +invalid or unspecified input to functionality in the standard. Exception +types or other resulting behaviour cannot be completely covered and would +be hard to make consistent between libraries. + +

+

+ + Non-goals + + for the API standard include: +

+
    +
  • +

    + Making array libraries identical so they can be merged. +

    +

    + + Each library will keep having its own particular strength, whether it’s +offering functionality beyond what’s in the standard, performance advantages +for a given use case, specific hardware or software environment support, or +more. + +

    +
  • +
  • +

    + Implement a backend or runtime switching system to be able to switch from one +array library to another with a single setting or line of code. +

    +

    + + This may be feasible, however it’s assumed that when an array-consuming +library switches from one array type to another, some testing and possibly +code adjustment for performance or other reasons may be needed. + +

    +
  • +
  • +

    + Making it possible to mix multiple array libraries in function calls. +

    +

    + + Most array libraries do not know about other libraries, and the functions +they implement may try to convert “foreign” input, or raise an exception. +This behaviour is hard to specify; ensuring only a single array type is +used is best left to the end user. + +

    +
  • +
+
+
+

+ TBD whether or not in scope, or for a later version + + ¶ + +

+
    +
  • +

    + Random number generation, Fourier transforms, and miscellaneous functionality +like a padding function. +

    +

    + + This will be decided later, depending on whether “optional extensions” will +be added to the standard. + +

    +
  • +
+
+
+

+ Implications of in/out of scope + + ¶ + +

+

+ If something is out of scope and therefore will not be part of (the current +version of) the API standard, that means that there are no guarantees that that +functionality works the same way, or even exists at all, across the set of +array libraries that conform to the standard. It does + + not + + imply that this +functionality is less important or should not be used. +

+
+
+
+

+ Stakeholders + + ¶ + +

+

+ Arrays are fundamental to scientific computing, data science, and machine +learning and deep learning. Hence there are many stakeholders for an array API +standard. The + + direct + + stakeholders of this standard are + + authors/maintainers of +Python array libraries + + . There are many more types of + + indirect + + stakeholders +though, including: +

+
    +
  • +

    + maintainers of libraries and other programs which depend on array libraries +(called “array-consuming libraries” in the rest of this document) +

    +
  • +
  • +

    + authors of non-Python array libraries +

    +
  • +
  • +

    + developers of compilers and runtimes with array-specific functionality +

    +
  • +
  • +

    + end users +

    +
  • +
+

+ Libraries that are being actively considered - in terms of current behaviour and +API surface - during the creation of the first version of this standard +include: +

+ +

+ Other Python array libraries that are currently under active development and +could adopt this API standard include: +

+ +

+ There are a huge amount of array-consuming libraries; some of the most +prominent ones that are being taken into account - in terms of current array +API usage or impact of design decisions on them - include (this list is likely +to grow it over time): +

+ +

+ Array libraries in other languages, some of which may grow a Python API in the +future or have taken inspiration from NumPy or other array libraries, include: +

+ +

+ Compilers, runtimes, and dispatching layers for which this API standard may be +relevant: +

+ +
+
+

+ How to read this document + + ¶ + +

+

+ For guidance on how to read and understand the type annotations included in this specification, consult the Python + + documentation + + . +

+
+
+ + +

+ How to adopt this API + + ¶ + +

+

+ Most (all) existing array libraries will find something in this API standard +that is incompatible with a current implementation, and that they cannot +change due to backwards compatibility concerns. Therefore we expect that each +of those libraries will want to offer a standard-compliant API in a + + new +namespace + + . The question then becomes: how does a user access this namespace? +

+

+ The simplest method is: document the import to use to directly access the +namespace (e.g. + + + import + + + package_name.array_api + + + ). This has two issues though: +

+
    +
  1. +

    + Array-consuming libraries that want to support multiple array libraries +then have to explicitly import each library. +

    +
  2. +
  3. +

    + It is difficult to + + version + + the array API standard implementation (see + + + Versioning + + + ). +

    +
  4. +
+

+ To address both issues, a uniform way must be provided by a conforming +implementation to access the API namespace, namely a + + + method on the array +object + + + : +

+
+
+
xp = x.__array_namespace__()
+
+
+
+

+ The method must take one keyword, + + + api_version=None + + + , to make it possible to +request a specific API version: +

+
+
+
xp = x.__array_namespace__(api_version='2020.10')
+
+
+
+
+

+ Note +

+

+ This is inspired by + + NEP 37 + + , +however it avoids adding a dependency on NumPy or having to provide a +separate package just to do + + + get_array_module(x) + + +

+

+ NEP 37 is still in flux (it was just accepted by JAX and TensorFlow on an +experimental basis), and it’s possible that that should be accepted instead. +

+

+ TBD: a decision must be made on this topic before a first version of the +standard can become final. We prefer to delay this decision, to see how +NEP 37 adoption will work out. +

+
+

+ The + + + xp + + + namespace must contain all functionality specified in + + + API specification + + + . It may contain other functionality, however it is +recommended not to add other functions or objects, because that may make it +harder for users to write code that will work with multiple array libraries. +

+
+
+
+

+ Conformance + + ¶ + +

+

+ A conforming implementation of the array API standard must provide and support +all the functions, arguments, data types, syntax, and semantics described in +this specification. +

+

+ A conforming implementation of the array API standard may provide additional +values, objects, properties, data types, and functions beyond those described +in this specification. +

+

+ Libraries which aim to provide a conforming implementation but haven’t yet +completed such an implementation may, and are encouraged to, provide details on +the level of (non-)conformance. For details on how to do this, see + + + Verification - measuring conformance + + + . +

+
+
+
+

+ Terms and Definitions + + ¶ + +

+

+ For the purposes of this specification, the following terms and definitions apply. +

+ +

+ + array + + : +a (usually fixed-size) multidimensional container of items of the same type and size. +

+

+ + axis + + : +an array dimension. +

+

+ + broadcast + + : +automatic (implicit) expansion of array dimensions to be of equal sizes without copying array data for the purpose of making arrays with different shapes have compatible shapes for element-wise operations. +

+

+ + compatible + + : +two arrays whose dimensions are compatible (i.e., where the size of each dimension in one array is either equal to one or to the size of the corresponding dimension in a second array). +

+

+ + element-wise + + : +an operation performed element-by-element, in which individual array elements are considered in isolation and independently of other elements within the same array. +

+

+ + matrix + + : +a two-dimensional array. +

+

+ + rank + + : +number of array dimensions (not to be confused with the number of linearly independent columns of a matrix). +

+

+ + shape + + : +a tuple of + + + N + + + non-negative integers that specify the sizes of each dimension and where + + + N + + + corresponds to the number of dimensions. +

+

+ + singleton dimension + + : +a dimension whose size is one. +

+

+ + vector + + : +a one-dimensional array. +

+
+
+
+

+ Normative References + + ¶ + +

+

+ The following referenced documents are indispensable for the application of this specification. +

+
    +
  • +

    + + IEEE 754-2019: IEEE Standard for Floating-Point Arithmetic. + + Institute of Electrical and Electronic Engineers, New York (2019). +

    +
  • +
  • +

    + Scott Bradner. 1997. “Key words for use in RFCs to Indicate Requirement Levels”. RFC 2119. doi: + + 10.17487/rfc2119 + + . +

    +
  • +
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/search.html b/latest/search.html new file mode 100644 index 000000000..cf84213eb --- /dev/null +++ b/latest/search.html @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + Search — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+

+ Search +

+
+ +

+ Please activate JavaScript to enable the search + functionality. +

+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/searchindex.js b/latest/searchindex.js new file mode 100644 index 000000000..5aa889176 --- /dev/null +++ b/latest/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["API_specification/array_object","API_specification/broadcasting","API_specification/constants","API_specification/creation_functions","API_specification/data_type_functions","API_specification/data_types","API_specification/elementwise_functions","API_specification/function_and_method_signatures","API_specification/index","API_specification/indexing","API_specification/linear_algebra_functions","API_specification/manipulation_functions","API_specification/searching_functions","API_specification/set_functions","API_specification/sorting_functions","API_specification/statistical_functions","API_specification/type_promotion","API_specification/utility_functions","assumptions","benchmark_suite","design_topics/C_API","design_topics/accuracy","design_topics/copies_views_and_mutation","design_topics/data_interchange","design_topics/device_support","design_topics/index","design_topics/parallelism","design_topics/static_typing","future_API_evolution","index","purpose_and_scope","usage_data","use_cases","verification_test_suite"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,"sphinx.ext.todo":2,sphinx:56},filenames:["API_specification/array_object.md","API_specification/broadcasting.md","API_specification/constants.md","API_specification/creation_functions.md","API_specification/data_type_functions.md","API_specification/data_types.md","API_specification/elementwise_functions.md","API_specification/function_and_method_signatures.md","API_specification/index.rst","API_specification/indexing.md","API_specification/linear_algebra_functions.md","API_specification/manipulation_functions.md","API_specification/searching_functions.md","API_specification/set_functions.md","API_specification/sorting_functions.md","API_specification/statistical_functions.md","API_specification/type_promotion.md","API_specification/utility_functions.md","assumptions.md","benchmark_suite.md","design_topics/C_API.md","design_topics/accuracy.md","design_topics/copies_views_and_mutation.md","design_topics/data_interchange.md","design_topics/device_support.md","design_topics/index.rst","design_topics/parallelism.md","design_topics/static_typing.md","future_API_evolution.md","index.rst","purpose_and_scope.md","usage_data.md","use_cases.md","verification_test_suite.md"],objects:{},objnames:{},objtypes:{},terms:{"1990s":30,"2000s":30,"\u03c0":[2,6],"abstract":[22,31],"boolean":[0,3,6,8,16],"case":[3,18,20,21,22,23,24,29,30,33],"class":[4,27,30,31],"default":[0,3,5,9,10,11,12,13,14,15,17,21,23,24],"enum":[0,23],"export":[0,31],"final":[28,30],"float":[0,2,3,4,6,8,10,15,17,21,30,31],"function":[0,5,8,18,20,22,23,24,26,27,28,30,31,32],"import":[18,20,24,30,32,33],"int":[0,3,4,7,9,10,11,12,14,15,16,17,31],"long":27,"new":[3,11,18,20,22,23,24,28,30,31,32],"null":23,"public":[0,31,32],"return":[7,8,20,21,22,23,24,27,32],"short":[30,31],"static":25,"switch":[30,32],"throw":1,"true":[5,6,8,9,10,12,13,15,17],"try":[27,30],"var":8,"void":30,"while":[1,6,9,18,22,23,24,31,32,33],AND:[6,17],Adding:[19,24],For:[0,5,6,7,9,10,11,18,21,23,24,30,32,33],NOT:6,Not:2,One:[11,30,33],Such:21,That:[18,27,30],The:[0,1,2,3,5,6,9,10,11,12,13,14,15,16,17,18,20,21,22,23,24,26,28,30,31,32,33],Then:32,There:[20,22,24,27,30,32,33],These:[5,22,31],Use:[20,24,29,30],Using:[0,9,16],With:[21,31,32],__abs__:8,__add__:8,__and__:8,__array__:[23,32],__array_api_version__:28,__array_namespace__:[8,30],__bool__:8,__cuda_array_interface__:23,__dlpack__:[3,8,23],__dlpack_device__:[3,8,23],__eq__:[8,24],__float__:8,__floordiv__:8,__ge__:8,__getitem__:[8,9],__gt__:8,__iadd__:0,__iand__:0,__ifloordiv__:0,__ilshift__:0,__imatmul__:0,__imod__:0,__imul__:0,__int__:8,__inv__:0,__invert__:8,__ior__:0,__ipow__:0,__irshift__:0,__isub__:0,__itruediv__:0,__ixor__:0,__le__:8,__len__:8,__lshift__:8,__lt__:8,__matmul__:8,__mod__:8,__mul__:8,__ne__:8,__neg__:8,__or__:8,__pos__:8,__pow__:8,__radd__:0,__rand__:0,__rfloordiv__:0,__rlshift__:0,__rmatmul__:0,__rmod__:0,__rmul__:0,__ror__:0,__rpow__:0,__rrshift__:0,__rshift__:8,__rsub__:0,__rtruediv__:0,__rxor__:0,__setitem__:8,__sub__:8,__truediv__:8,__version__:28,__xor__:8,_arg:31,_array_modul:33,_backend:32,_basearrai:27,abi:[20,23],abl:[22,23,24,30,32],about:[0,4,7,22,30,32,33],abov:[0,6,9,10,22,23,24,32],abs:[0,8,10],absolut:[0,6,10,21],acceler:[18,23],accept:[0,3,6,7,10,11,12,13,14,15,17,18,23,28,30],access:[0,9,23,28,30],accommod:[0,31,32],accompani:30,accord:[0,4,5,6,9,15,21],accordingli:[6,9,10,12,15,16,17,21],account:30,accur:[6,21],accuraci:[6,25],achiev:[9,21],aco:[8,21],acosh:[8,21],acquir:31,across:[1,21,24,30],activ:30,actual:[23,30],add:[0,5,7,8,9,20,21,24,30],added:[5,7,24,28,30],addend:0,adding:[7,20,30],addit:[0,5,6,7,9,16,20,23,30,31,33],address:[30,31,32],adher:[0,3,6,7,9,10,11,12,13,14,15,17,18,30],adjac:3,adjust:[15,30],adopt:[18,23,32],advanc:32,advantag:30,affect:[3,22,24],after:[6,30],again:24,against:33,aid:[21,33],aim:[7,20,27,28,30,31,32,33],algebra:8,algorithm:[8,21,32],align:[21,31],all:[0,3,5,8,9,10,11,13,18,20,22,23,24,30,32,33],alloc:24,allow:[9,11,20,21,22,26,32],almost:[20,32],along:[9,10,11,12,14,15,17],alpha:28,alreadi:[0,6,28,32],also:[13,16,18,22,23,27,32],altern:[7,22,23,33],although:21,alwai:[0,3,6,9,18,22,24],ambigu:[0,22],amd:23,among:21,amount:[30,31,32],analysi:[22,30,31,32],analyz:31,angl:6,ani:[0,6,8,9,16,22,23,27,28,30,33],annot:[7,27,30],anoth:[3,18,20,22,23,24,30,32],anyth:[18,30],apach:30,api:[0,1,5,7,9,16,18,21,22,23,24,25,26,27,31,33],api_vers:[8,30],appear:[28,30,33],append:[1,6,10],appli:[0,4,9,11,16,18,23,30,32],applic:[1,16,30,31],approach:[26,31],appropri:[0,6],approxim:[0,6,21],arang:[8,31],arbitrari:21,architectur:18,area:6,aren:[22,30],argmax:8,argmin:8,argsort:8,argument:[0,3,4,6,7,10,11,12,13,14,15,16,17,21,22,23,30,31,32],aris:30,arithmet:[15,16,30],arkouda:30,around:31,arrai:[1,2,3,4,5,6,7,8,10,12,13,14,15,17,18,20,21,22,23,24,26,27,28,30,31,33],array_api:30,array_api_test:33,array_api_tests_modul:33,array_modul:33,arraylib:20,arraylib_nam:18,arrays_and_dtyp:8,arriv:30,arrow:30,art:30,articul:31,asarrai:[8,32],ascend:14,asid:33,asin:[8,21],asinh:[8,21],asnumpi:32,aspect:33,aspir:31,assembl:30,assert_array_almost_equ:32,assertequ:32,assign:22,associ:[0,6,16,31],assum:[0,6,9,18,24,30],assumpt:[20,23,28,29,30],astropi:[20,32],asynchron:23,atan2:[8,21],atan:[8,21],atanh:[8,21],attach:23,attain:32,attempt:[9,21,22,24,30,32],attribut:[4,5,8,23,28,31,32],augend:0,author:[30,31,32],auto:[26,32],automat:[1,30],avail:[7,18,23,28,31],averag:21,avoid:[1,6,20,22,23,24,30,32],await:0,awar:[18,27,32],axes:[0,8,9,11,12,15,17],axi:[8,30],axis1:8,axis2:8,back:32,backend:[20,26,30],backward:[9,11,17,22,30],bar:31,bare:21,base:[0,3,6,7,9,10,11,12,13,14,15,17,22,27,28,30,31,32],basi:30,basic:9,becam:[27,30],becaus:[16,20,22,23,24,27,30,32,33],becom:[23,30,32],been:[23,30],befor:[11,30],begin:[9,32],behavior:[0,6,9,16,18,21,26,28,30,31,32,33],behaviour:[0,16,23,25,30,32],being:[9,23,24,30,33],belong:22,below:[10,24],benchmark:29,bessel:[15,20],best:[21,23,30],beta:28,better:[20,32],between:[3,4,6,11,13,16,22,23,24,30,32],beyond:[5,11,16,30],bfloat16:30,binari:[5,6,20],bind:[30,32],bio:[20,32],bit:[4,5,6,16,21],bitwis:6,bitwise_and:[0,8],bitwise_invert:[0,8],bitwise_left_shift:8,bitwise_or:8,bitwise_right_shift:[0,8],bitwise_xor:[0,8],bla:26,bless:30,blob:28,blue:23,bohrium:30,bool:[0,3,6,8,10,12,13,14,15,16,17],borrow:30,both:[0,1,6,9,10,22,23,27,30,31],bound:[9,16,27],boundari:21,bradner:30,branch:6,broad:31,broadcast:[0,6,8,10,12,15,17,30],brought:32,buffer:[3,22,23],bug:[32,33],bugfix:28,build:[18,26,30],built:[9,16,30],burden:30,c99:28,cach:1,calcul:[0,6,15],call:[0,3,6,7,10,11,12,13,14,15,17,23,24,30,31,32],can:[0,1,3,5,7,9,16,18,20,22,23,24,27,30,31,32,33],candid:[23,30],cannot:[3,30],capsul:0,care:22,carefulli:0,cast:[5,16,30,32],categori:[6,8],ceil:[3,8],certain:[21,23],certainti:20,cffi:30,cfunc:32,chang:[1,3,11,18,28,30,32,33],channel:31,characterist:30,check:[9,21,32,33],choic:[15,18,21,26,28,30,32],choleski:8,choos:[6,9,22,24,32],chosen:[6,12],chunk:26,clear:[0,18,22,23,30,32],clearli:[5,28],clip:9,clone:33,close:[3,6,9,30,32],closest:6,code:[7,16,22,24,27,30,31,32],codifi:31,codomain:6,collect:31,colon:9,column:[3,10,30],com:[23,28,33],combin:[22,26],comma:9,command:33,common:[16,18,23,24,26,30,31,32],commonli:[15,20,30,31],commun:30,commut:[0,6],compact:23,compar:[14,21,24,31,33],comparison:[28,31],compat:[0,1,6,10,11,12,15,16,17,22,30,32],compet:31,compil:[18,20,30],complement:31,complet:[26,28,30,32],complex128:[5,30],complex64:[5,30],complex:[5,21,23,24,30,31],compliant:[6,7,21,28,30],comput:[0,6,10,15,21,30],concat:8,concaten:11,concept:[9,22,23,30],concern:[24,26,30],concret:30,conda:33,condit:8,conform:[0,2,3,4,5,6,9,10,11,12,13,14,15,16,17,18,21],confus:30,connect:16,consequ:[18,27,30],conserv:32,consid:[0,6,7,23,24,30,32,33],consider:[9,22],consist:[3,9,24,27,30],consortium:30,constant:8,constitut:15,constrain:[18,21],constraint:[18,29],construct:[18,20,23,30],consult:30,consum:[0,18,23,27,30,31],consumpt:[0,1,31],contain:[0,3,6,9,10,11,12,13,15,17,21,22,23,26,30,32],context:[24,29,31],contigu:23,continu:23,control:[24,26],conveni:18,convent:[0,3,6,7,9,10,11,12,13,14,15,17,31],convers:[20,30],convert:[0,3,16,20,23,30,32],coordin:[6,23,26,30],copi:[0,1,8,14,20,23,25,30],core:[30,32],corner:32,correct:[8,22,23],correctli:21,correspond:[0,1,6,9,10,11,12,15,21,30],cos:[8,21],cosh:[8,21],cosin:6,cost:0,could:[0,18,22,26,30,32],count:[9,11,13,17],coupl:18,cover:[30,33],cpu:[0,18,20,23,24,30,32],cpu_pin:0,cpyext:32,cpython:20,creat:[3,13,18,23,24,30],creation:[8,18,24,30],creativ:30,critic:32,cross:[8,24,30],csd:32,ctype:30,cuda:[20,23,32],cupi:[20,22,30,31,32],current:[22,24,27,30,31,32],curtail:21,curv:30,custom:[0,20],cython:[30,32],dark:23,dash:16,dask:[22,26,30,31,32],data:[0,1,3,6,8,9,10,11,12,13,14,15,16,17,18,20,22,24,25,28,29,30,33],date:28,datetim:30,deal:[20,26,27,28],dealt:[23,27,30],decad:30,decid:30,decis:30,decreas:9,deep:30,def:[27,31,32],defin:[0,5,6,10,11,12,13,14,15,17,21,23,27,31,32,33],definit:31,degre:15,delai:[18,30],delet:23,demonstr:1,denot:6,depend:[0,6,9,12,14,16,21,23,27,30,32,33],deriv:[3,9,31],descend:8,describ:[1,5,16,23,30],descript:[7,21],design:[21,23,29,30,32,33],desir:[21,27],despit:23,det:8,detail:[0,3,5,18,23,24,26,30,32],determin:[0,1,6,10,11,12,16,17,23,24,30],detract:18,dev:28,develop:[0,21,30,31,32,33],deviat:[15,21,30,32],devic:[8,9,23,25,30,32],device_id:[0,23],device_typ:0,diagon:[3,8],diagram:[16,23,30],differ:[0,1,4,6,11,16,18,22,24,30,31,32],difficult:[21,30],difficulti:20,dimens:[0,1,9,10,11,12,13,15,16,17,30],dimension:[0,3,9,10,12,15,16,17,23,27,30],direct:[20,30,31],directli:[30,32],disallow:0,disappear:32,discontinu:32,discuss:[0,23,24,26,30,31,32],dispatch:[30,32],distanc:3,distribut:[18,21,24,26],diverg:33,divid:[0,8,9,21],dividend:6,divis:6,divisor:[6,15],dlpack:[0,3],dlpack_vers:23,dlpackmanagedtensor:23,dltensor:23,dmlc:23,docstr:31,document:[5,7,20,23,28,31,32,33],doe:[1,3,9,16,18,20,21,22,23,27,30,32,33],doesn:[20,24,30],doi:30,doing:[18,20,28,32],domain:[6,21,30,32],don:[27,32],donat:22,done:18,dot:8,doubl:[5,16],down:22,downsid:24,downstream:[18,30,31],draft:30,drop:[20,27],dtype:[4,5,8,16,18,23,27,30,31,32],due:[0,6,21,30],dunder:28,dure:[15,16,18,30,31],dynam:0,each:[0,6,9,10,11,12,13,18,21,23,27,30,31,32],eager:30,eagerpi:32,earli:30,eas:31,easi:18,easier:[7,18,22],easili:[32,33],edit:33,effect:[15,24,33],effici:[1,18,22],effort:[21,31],eig:8,eigvalsh:8,einop:30,einsum:8,either:[0,3,5,6,9,21,22,23,27,30,31,33],elabor:24,electr:30,electron:30,element:[0,1,3,8,9,10,11,12,13,15,17,21,30],elementwisekernel:20,ellipsi:[0,9],els:[1,18,31],elsewher:[3,12],embed:13,emerg:[18,23,30],empir:31,emploi:[18,24],empti:[8,9,30],empty_lik:8,enabl:[1,23,24,26,27,30],encapsul:4,encourag:[1,30,31],end:[3,6,22,30,31,32],endpoint:8,engin:[30,32],enough:[18,20,27,28,30],ensur:[0,18,21,30,31,32],entir:[15,17],entri:9,environ:[26,30,33],eps:4,equal:[0,1,3,8,9,10,14,24,30],equival:[0,6,9,10,16,22,30],ergonom:1,error:[0,3,16,21,30],establish:31,etc:[9,28],euclidean:10,euler:2,evalu:[0,6,17,18,30],even:[0,6,21,22,30,32],evenli:3,everi:[0,3,30],evolut:[29,30],evolv:[7,18,30],exact:27,exactli:23,exampl:[0,8,9,10,11,18,22,23,24,26,27,30,32,33],except:[1,3,5,9,11,12,16,17,18,21,24,28,30,31,32],exchang:23,exclud:[3,9],exclus:[3,9],execut:[16,18,23,24,26,30,32],exercis:26,exert:24,exist:[3,5,7,11,18,23,24,28,30,31],exp1:9,exp2:9,exp:[8,21],expand:[11,32],expand_dim:8,expans:[1,30],expect:[5,16,21,23,24,27,30],experi:[18,28],experiment:[30,31],explain:20,explicit:[24,32],explicitli:[0,18,30,32],explor:31,expm1:[8,21],expn:9,expon:[0,6],exponenti:[0,6],express:[6,9,16,22],extend:[9,30],extens:[30,32],extern:[0,3,6,7,10,11,12,13,14,15,17,32],extra:30,extract:31,eye:8,facilit:[1,18],fals:[3,5,6,8,9],famili:11,familiar:32,faster:22,fastest:22,fdlibm:[6,21],feasibl:[20,30],few:[21,30,32],field:[23,30],figur:23,file:[31,32,33],fill:3,fill_valu:8,find:[30,31],fine:[27,30],finfo:8,finit:[0,6,21],first:[0,6,9,10,11,12,13,30,31,32,33],fit:[26,30,32],fix:[24,30,32],flatten:[10,11,12,13],flexibl:32,flip:[6,8],float32:[8,16],float64:[8,16],floatxx:[11,16],floor:8,floor_divid:[0,8],floordiv:0,flux:30,focu:31,follow:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18,21,23,24,28,30,31,32],foo:31,foreign:30,form:[0,10,22,28,31],format:[0,28],former:[9,31],fortran:32,forward:30,found:[32,33],foundat:31,fourier:30,fragment:30,framework:[24,30],freedom:15,freeli:21,freq:32,frequenc:[28,31],friction:31,fro:10,frobeniu:10,from:[3,4,6,9,10,11,12,15,16,17,18,20,21,23,24,28,30,31,32,33],from_dlpack:[0,8,23],full:[8,22,32],full_lik:8,fulli:24,funcnam:7,fundament:[22,30],further:[23,26],furthermor:[0,30,33],futur:[19,24,26,27,29,30,32],gamma:20,gener:[3,18,20,30,31],get:[4,20,22,23,24],get_array_modul:30,get_backend:32,github:[23,28,33],give:[16,24],given:[0,1,3,11,16,22,24,27,28,30,32],global:24,glue:32,goal:[20,22,32],good:[18,20,22,24,27,30],got:32,govern:[0,6,16,28],gpu:[18,23,24,32],gradual:30,grai:23,grain:30,granular:24,graph:[0,30],greater:[0,8,9,10,11],greater_equ:[0,8],greatest:6,grew:30,ground:[31,33],group:30,grow:30,growth:23,guarante:[3,18,23,24,30,32],gufunc:30,guidanc:[7,20,30],half:[3,9],hand:16,handl:[0,20,22,23,24,30],happen:[22,24],hard:[22,23,24,30],harder:30,hardli:23,hardwar:[0,13,21,23,24,30],has:[0,3,6,9,10,11,13,15,16,18,23,24,26,28,30,32,33],have:[0,1,3,4,6,7,9,10,11,12,13,14,15,17,18,20,22,23,24,27,28,30,31,32],haven:[23,30],heavili:[22,32],help:[20,21,26],henc:[20,22,23,24,26,27,30,32],here:[16,22,23,26,27,32],high:[16,24,30],higher:[1,20,31],highest:24,highli:28,hoc:32,hold:23,hoop:32,how:[18,21,23,26,31,32,33],howev:[5,7,13,18,20,21,22,23,24,28,30,32],http:[28,33],huge:30,human:31,hyperbol:6,hypothesi:33,idea:30,ident:30,identifi:[21,24,31],idx:22,ieee:[0,2,4,5,6,10,15,17,21,30],iinfo:8,illustr:[22,27],imag:[20,30,31,32],immedi:23,immut:0,impact:30,implement:[0,2,3,4,5,6,9,10,11,12,13,14,15,16,17,20,21,22,24,27,28,30,31,32],impli:[1,30],implicit:[1,24,30],importantli:18,impos:21,imposs:[21,22,33],improv:[26,30,32],includ:[0,3,5,9,10,12,15,17,20,21,22,24,26,28,31,32],inclus:[3,9,30],incompat:[7,18,28,30],inconsist:30,increas:[21,31],inde:20,independ:[9,10,18,23,28,30],index:[0,3,5,8,11,12,13,14,30,32],indexerror:[9,11],indic:[3,6,9,10,11,12,13,14,16,23,30],indirect:30,indispens:30,indistinguish:[6,9,21],individu:[7,24,26,27,30,31],induc:10,ineffici:32,inevit:20,inf:[8,10,30],infeas:30,infer:[3,11,31],infin:[0,2,6,10],infinit:[6,21],inform:[4,30,31,32,33],initi:[22,30],innermost:10,innov:[30,31],inplac:22,input:[3,4,6,10,11,12,13,14,15,17,18,24,27,30,32],insert:11,insid:27,inspir:[30,32],instal:[18,33],instanc:[0,16,18,24],instanti:24,instead:[23,30,31,32],institut:30,instruct:0,instrument:31,int16:[8,16],int32:[8,16],int64:[8,13,16],int8:[8,16],integ:[0,3,4,6,8,9,10,15,17,21,23,30],intend:18,intent:6,intenum:0,interchang:[0,3,18,20,25,30],interest:21,interfac:[23,32],intern:32,interoper:[18,23],interpret:[22,33],intersect:31,interv:[3,5,9,11,17,28],introduc:[11,27,31],intuit:0,intxx:[11,16],inv:[0,8],invalid:[0,11,17,30],invers:[6,10,13],invert:[0,6],invok:31,involv:[0,1,4,6,16,21,22,24,26],isfinit:8,isinf:8,isn:20,isnan:8,isol:30,issu:[5,20,22,23,24,26,30,32],istft:32,item:[9,22,30],iter:9,its:[0,11,21,24,30,31,32],itself:[5,18,23,24,32],javascript:30,jax:[22,30,31,32],jit:[18,20,30],join:[11,16],json:31,julia:32,jump:32,junk:9,just:[23,30,32],jvm:30,keep:[16,20,23,30],keepdim:8,kei:[8,30],kept:24,kera:32,key1:7,key2:7,keyword:[0,3,6,7,10,11,12,13,14,15,17,22,23,24,26,27,28,30,31,32],kind:[4,16],know:[18,20,21,30,32],known:21,lack:21,languag:[22,30,32],lapack:22,larg:[0,6,23,27,30],larger:[0,4,6,11,15],largest:[4,10],last:[9,10,11,14,17],latest:0,latitud:21,latter:[9,18,23,31],lattic:16,layer:[18,26,30,32],layout:23,lazi:[18,32],lead:[7,30],learn:[20,26,30,31,32],least:[10,20,21],leav:[9,11,21,22],left:[6,7,9,11,16,30],legaci:0,legat:30,len:1,length:[1,3,9,11],less:[0,8,9,10,22,30],less_equ:[0,8],let:[0,1,9,26],level:[0,16,20,24,30,31],leverag:31,librari:[5,6,7,18,20,21,22,23,24,26,27,28,30,31,32,33],light:23,like:[7,18,20,22,23,27,28,30,31,32],limit:[4,21],line:[16,30,31,32,33],linear:8,linearli:30,linspac:8,list:[1,9,18,24,30,32],liter:10,littl:32,live:[23,30],loc:32,local:[1,24],locat:22,log10:[8,21],log1p:[8,21],log2:[8,21],log:[8,21],logaddexp:8,logarithm:6,logic:[6,17,24],logical_and:8,logical_not:8,logical_or:8,logical_xor:8,lombscargl:32,longer:[22,23],look:[7,23,32],lot:23,lower:[1,3],lshift:0,lstsq:8,machin:[4,30],made:[18,28,30,32],magnitud:[0,6],mai:[0,3,5,6,7,9,13,14,16,18,20,21,22,23,24,26,27,30,31,32],main:[3,10,20,23,32],mainli:30,mainstream:20,maintain:[14,20,30,32],major:[9,12,23,28],make:[1,3,7,13,18,20,21,22,23,28,30],manag:[20,23,24],manhattan:10,mani:[30,32],manipul:8,manner:23,manual:32,map:[0,3,6,7,10,11,12,13,14,15,17,22],mask:30,master:28,match:[0,1,32],mathemat:[0,2,6,10],matmul:[0,8],matplotlib:[30,31],matric:10,matrix:[10,30],matrix_pow:8,matrix_rank:8,matter:[16,20],matur:28,max:[1,4,8,10],maximum:[1,10,12,15,21],mean:[0,8,18,22,23,27,28,30],meant:0,measur:30,mechan:[0,3,18,20,25],member:[0,23],memori:[1,3,18,22,23,24,30,32],memoryview:3,mention:[20,32],merg:30,meta:30,metal:0,method:[3,5,8,18,22,23,24,26,27,30,31,32],methodolog:29,microsystem:21,mid:30,min:[4,8,10],mind:[23,30],minim:24,minimum:[6,12,15,21],minor:28,minuend:0,miscellan:30,miss:30,mix:[4,8,22,30],mlir:30,mod:0,mode:[0,6,21],model:32,modifi:22,modul:[0,18,28,31,32,33],modulo:7,moment:23,more:[0,1,5,6,7,9,10,11,13,16,18,20,21,23,24,26,27,28,30,31,33],most:[13,18,24,30,32],mostli:[23,26,30],motiv:18,move:[24,32],much:[24,30,33],mul:0,multi:[8,10,23,32],multidimension:30,multipl:[0,6,7,9,10,12,15,17,18,20,23,24,26,27,28,30,32],multipli:[0,8,21],multiprocess:32,must:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18,21,22,23,28,30,31],mutabl:[0,23,25],mutat:[22,23],mxnet:[22,30,31,32],n_job:[26,32],name:[0,3,6,7,9,10,11,12,13,14,15,17,23,30,31],namespac:[0,7,18,28,30,33],nan:[0,6,8,30],nativ:23,natur:6,nd4j:30,ndarrai:[20,23,30,32],ndim:8,nearest:[0,6,21],necessari:[0,3,9,22,23,30],necessarili:[0,33],need:[0,5,9,20,21,22,23,27,28,30,31,32,33],neg:[0,3,8,9,10,11,17,30],neither:[0,6,31],nep:30,nest:[3,26],nestedsequ:3,networkx:30,never:[3,30],newer:30,newli:24,next:[4,5],non:[0,1,3,6,10,12,15,16,17,20,24,32],none:[7,8,23,24,30,31,33],nonneg:9,nonzero:[0,6,8,9],nor:[0,6,31],norm:8,normal:[7,11],not_equ:[0,8],notabl:32,notat:6,note:[0,6,8,23,27,31,32,33],noth:9,novel:31,now:[30,32],nsf:32,nuc:10,nuclear:10,num:8,numarrai:30,numba:[20,23,30,32],number:[0,1,2,3,4,5,6,9,10,11,12,13,15,16,17,23,30,31],numer:[6,8,10,16,21,30,32],numpi:[0,18,22,23,24,30,31,32,33],numsharp:30,obj:8,object:[5,8,9,16,18,23,24,27,28,30,31,32],obstabl:30,obtain:[9,24],obviou:30,occupi:4,occur:[12,13,31],occurr:[12,13],odd:[0,6],off:10,offer:[20,23,24,26,30,32],offici:30,offset:8,often:[20,30,31,32],older:[13,23,28,30],onc:[20,23,28],one:[1,3,9,10,11,12,13,18,20,23,24,26,27,28,30,32],ones:[8,22,30],ones_lik:8,onli:[0,1,3,5,6,7,9,10,11,12,13,14,15,16,17,18,20,22,23,24,27,28,30,31,32,33],onnx:30,onto:22,open:[3,9],opencl:0,openmp:26,oper:[1,4,6,8,9,10,13,15,16,17,22,23,24,28,30,31,32],operand:[0,6,16,21],oppos:0,optim:[21,22,32],option:[0,3,6,7,10,11,12,13,14,15,17,26,30,31,32],ord:8,order:[0,3,6,7,9,10,11,12,13,14,15,16,17,21,23,28,31],organ:[5,31,32],origin:[0,6,11,22,31],other:[5,6,8,9,15,18,21,23,24,27,30,32],other_i:0,otherwis:[0,3,6,9,10,11,12,13,14,15,17,18,24],out:[0,3,4,6,7,9,10,11,12,13,14,15,17,20,22,23,26,32],out_i:6,outer:8,outlin:30,output:[3,10,11,18,22,24,27,30],outsid:[11,16],over:[3,7,10,15,17,21,22,23,26,30],overflow:[0,6,16],overview:8,overwrit:22,own:[18,23,30],packag:[23,27,28,30,31,32],package_nam:30,pad:30,page:32,pain:32,pair:[6,10],panda:[30,31],parallel:[18,25,30,32],paramet:[7,18,27],part:[0,16,23,26,28,30,32],particip:16,particular:[9,20,23,27,30,32,33],pass:[6,18,21,23,24],past:30,pattern:[23,24,26,31,32],pep:[23,28],per:[0,20,23],perform:[0,9,17,20,21,22,23,30,31,32],perhap:23,periodogram:32,permut:[0,10],perspect:9,phrase:21,physic:24,pick:30,pin:24,pinv:8,pip:33,place:[3,8,11,22,24],placement:24,plan:[19,30],point:[0,2,3,4,6,8,10,15,17,21,24,30,32],pointer:[0,23],polici:24,polynomi:30,popul:15,portabl:[21,22],pos:0,posit:[0,2,3,7,8,9,10,11,12,13,14,15,17,18,21,27,31],possibl:[3,18,20,21,22,23,24,26,27,30,31,32,33],post:28,potenti:[0,1,6,22,30],pow:[0,8,21],power:[0,6,32],practic:[7,23,31],preced:24,precis:[0,5,6,16,21,30],predict:18,prefer:[0,18,30,32],prepend:1,presenc:30,present:[22,24,28,30],preserv:[9,11,24],preval:31,previou:32,primari:18,princip:6,principl:31,prioriti:24,probabl:13,problem:[22,27,31,32],problemat:[20,22],process:[28,31],process_docu:28,prod:8,produc:[0,23,32],product:[0,6,10,15],program:30,progress:[27,33],project:[20,32],promin:[23,30],promot:[0,1,4,5,6,8,10,11,12,15,17],propag:21,properti:[24,27,30],propos:[28,30,31,32],protocol:[3,18,23,27,30,32],proverbi:31,provid:[0,2,3,4,5,6,9,10,11,12,13,14,15,17,18,20,22,23,24,26,27,28,30,31,32],publicli:31,publish:31,pure:32,purpos:[1,5,6,18,29,32],push:30,put:[18,30,32],pxx:32,pyarray_cancastarrayto:32,pycapsul:[0,23],pydata:30,pyfunc:32,pypi:[20,31,32],pytest:33,python:[0,3,7,8,9,11,18,23,26,27,28,30,31],pythran:30,pytorch:[22,24,30,31,32],quadrant:6,quantifi:31,queri:23,question:[20,30],queue:24,quickli:30,quit:[20,30,32],quotient:[0,6,9],qutip:20,radian:6,rai:6,rais:[0,3,6,9,11,12,16,17,18,23,24,30],random:30,rang:30,rank:[1,9,10,11,12,17,30],rare:[30,31],rather:[16,18,20,24,26,30],rational:[7,9,23,28,30],reach:[28,32],read:22,readabl:[7,16,31],reader:21,readi:[20,30],readili:32,readm:33,real:28,rearrang:32,reason:[22,30,31],recogn:21,recommend:[0,7,21,22,23,24,30],reconstruct:13,record:31,reduc:[1,9,12,15,17,31,32],reduct:17,refer:[1,3,6,9,15,17,23,27],referenc:30,reflect:8,regard:32,regardless:16,regular:[28,30],reimplement:20,reinvent:31,rel:[0,10,11,14],relat:[9,24,26,30,32],releas:[23,28,30,31],relev:[20,24,27,30],reli:[20,27,32],remain:[0,6,9,11,22],remaind:[0,8,9],remov:[9,10,11],reorder:11,repeat:[1,32],replac:[9,33],repo:33,report:21,repositori:31,repres:[0,6,21,24,31,32],represent:[0,2,4,6,21,31],reproduc:21,request:[23,30],requir:[6,9,11,18,20,21,23,24,27,30,31,32],res:32,research:32,resembl:28,reshap:8,resid:[0,9,11],resolv:30,resourc:[31,32],respect:[0,6,9,10,21,24],rest:[20,30,32],restor:11,result:[0,1,4,6,9,10,11,12,13,15,16,17,21,22,30,31,32,33],result_typ:8,retain:9,retriev:[0,9,18,32],return_count:8,return_index:8,return_invers:8,reus:[3,22,30],revers:[0,6,10,11],review:30,rfc2119:30,rfc:[23,30],right:[6,20],rigor:21,rise:30,robust:21,rocm:[20,23],role:6,roll:8,root:6,roughli:30,round:[0,3,8,21],roundtiestoeven:21,rout:22,routin:30,row:[3,9,10,12,23],rrai:30,rshift:0,rule:[0,4,5,6,8,9,10,11,12,15,17,23,30,32],run:[18,31,32],runtim:[26,27,28,30,32],rust:30,safe:0,sai:[0,32,33],said:27,same:[0,3,6,7,9,10,11,13,14,15,16,18,22,23,24,27,30,32],sampl:[3,15,31],satisfi:[6,9,21,31],save:22,scalar:[0,3,8,10,32],scale:24,schedul:30,scheme:28,scienc:30,scientif:30,scikit:[20,26,30,31,32],scipi:[20,26,30,31],scope:[20,26,29,31],scott:30,scrape:31,search:8,second:[1,6,10,11,12,30],section:[20,23,24,27,30,32],sector:6,see:[0,3,4,5,6,10,12,15,16,17,18,20,23,24,27,30,31,32,33],seek:[21,31],seem:[20,23,32],select:9,self:[7,8,23,32],self_i:0,semant:[0,6,8,10,12,15,17,18,22,26,30,31,32],sens:[13,20,30,32],separ:[9,23,30],sequenc:[3,4,9,11],seriou:30,serv:32,set:[1,6,8,9,10,14,15,20,21,22,23,24,26,27,30,32,33],sever:[21,22,28,30],shall:28,shape1:1,shape2:1,shape:[1,8,9,10,14,27,30,32],share:[18,30],shift:[6,8],shorten:32,shorthand:9,should:[0,5,6,9,10,13,20,21,23,24,27,30,32,33],shown:30,side:[9,23],sign:[0,5,8],signal:[0,32],signatur:[8,18,27,30,31],signific:[18,21,22,30],significantli:18,similar:[20,30,31,32],simpl:[22,28],simplest:30,simpli:[6,20,27,30,32],sin:[8,21,22,27],sinc:24,sine:6,singl:[0,5,7,8,16,20,23,24,27,30,31,32],singleton:[1,10,11,12,15,17,30],singular:10,sinh:[8,21],situat:[22,23,24,30,32],size:[1,3,8,9,10,11,12,23,26,30],skimag:31,sklearn:31,slice:[0,8,22],slightli:22,slogdet:8,small:[0,6,21,32],smaller:[11,32],smallest:[4,6,10],soft:18,softwar:[30,32],sole:[0,3,6,7,10,11,12,13,14,15,17],solut:[22,32],solv:[8,27],some:[6,9,20,21,22,23,24,27,30,32,33],some_func:32,someth:[20,22,30],sometim:31,sort:8,sound:21,sourc:[31,33],space:3,span:21,spars:30,spec:33,special:20,specif:[0,1,2,3,4,5,6,9,10,11,12,13,14,15,16,17,18,20,21,23,24,27,28,29,30,31,32,33],specifi:[0,3,5,9,10,11,12,13,14,16,17,21,22,23,24,27,28,30,32,33],spectral:32,spectrogram:32,speed:30,sqrt:[8,10],squar:[8,10],squeez:8,stabil:14,stabl:[8,23],stack:[8,10,26],stage:28,standalon:33,standard:[0,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18,21,22,23,24,26,27,31,32],start:[8,9,27,30,32],state:[0,6,9,10,11,12,13,14,15,17,30],statist:8,statsmodel:20,std:8,stdlib:30,steep:30,step:[8,9,31],stft:32,still:[7,27,30,31,32,33],stop:[8,9,31],store:[1,10,24],stori:31,str:[0,7,31],strategi:[20,24],stream:[8,23,24],strength:30,strict:18,stride:[22,23],string:[0,28,30],strong:28,strongli:[7,32],struct:23,structur:[18,27,30,31],style:[9,12],sub:[0,9,10],subclass:[27,30],subject:16,submodul:20,suboptim:32,subsequ:31,subset:[6,21,31,32],subtract:[0,8,21],subtrahend:0,subtyp:27,sugar:9,suggest:32,suit:[21,29,30,31],suitabl:31,sum:[0,6,8,10],summar:31,summari:[28,31],summat:21,sun:21,superced:30,superclass:27,support:[0,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18,21,22,23,25,27,30,31],supportsbufferprotocol:3,supportsdlpack:3,sure:30,surfac:30,survei:32,svd:8,switchabl:24,synchron:[0,23,30],syntact:9,syntax:[8,22,30],system:[13,18,30],tabl:8,taco:30,take:[10,24,27,30],taken:30,tan:[8,21],tangent:6,tanh:[8,21],target:20,task:[30,32],technic:31,temporari:1,tend:[20,22,32],tensor:[0,30,32],tensorflow:[22,30,31,32],tensorli:32,term:[9,24,31],test:[6,17,21,29,30,31,32],text:23,than:[0,4,6,9,10,11,13,15,16,18,20,22,24,26,28,30,32],thei:[0,7,16,20,24,26,27,28,30,32,33],them:[20,22,30,32],themselv:7,theoret:21,therefor:[18,23,24,27,28,30,32],thi:[0,3,5,6,7,9,11,13,15,16,18,20,21,22,23,24,26,27,28,31,32,33],thin:18,thing:26,think:0,those:[0,3,5,7,16,22,23,24,28,30,31,32],though:[18,27,30,32],thread:[0,30,32],three:24,through:[1,3,6,23,28,31,32],thu:21,thwart:31,tied:30,ties:21,time:[7,12,13,18,23,26,30,32],to_devic:24,todai:[20,22],todo:[0,10,13,30],togeth:[16,23],too:[0,6,30],tool:[31,32],top:[0,18,30,32],topic:[24,26,29,30,32],torch:32,total:[0,12,15],toward:[11,21,31],tpu:[18,23],trace:[8,22,31],tractabl:32,tradit:6,transfer:24,transform:[30,31],translat:32,transon:30,transpos:[0,8],tri:[23,32],tricki:24,truediv:0,trunc:8,truth:[0,6,33],tupl:[0,1,3,9,10,11,12,13,15,17,18,30],turn:[3,18],tvm:30,two:[1,3,6,9,10,13,16,23,24,26,30,31,32,33],type:[0,3,6,7,8,9,10,11,12,13,14,15,17,18,20,22,23,25,28,30,31],typeerror:[23,32],typevar:27,typic:[18,22,28,32,33],ufunc:30,uint16:[8,16],uint32:[8,16],uint64:[8,16],uint8:[8,16],unambigu:[18,22,23,31],unbias:15,unchang:11,undefin:16,under:30,underflow:[0,6],underli:[6,11,21],understand:[30,31],understood:16,undesir:[13,23],unduli:21,unequ:1,unexpect:30,unfortun:21,unifi:[31,32],uniform:30,uniformli:30,unimport:30,uniniti:3,unintend:30,union:[0,3,4,10,11,13,15,17,31],uniqu:8,univers:[20,30],unless:[0,6,10,11,12,13,14,15,17],unlik:[28,30],unnecessari:[1,23],unsign:[5,8],unspecifi:[9,11,16,30],unsuccess:32,until:1,unumpi:[30,32],unwil:18,updat:[28,30],update_index:22,upon:30,upper:3,usabl:[0,3,6,7,10,11,12,13,14,15,17],usag:[29,30],use:[0,7,16,20,21,22,23,24,28,30],used:[0,3,5,9,10,11,16,22,23,24,26,28,30,31,32],used_dltensor:23,useful:22,user:[1,7,18,20,21,22,23,24,26,30,31,32],uses:[21,23,26,28,32],using:[7,9,20,24,26,27,30,33],usual:30,util:[8,28,31],vacuum:31,val:22,valid:[0,9,11,17,21,31],valu:[1,3,5,6,8,10,11,12,14,15,16,18,21,22,23,27,30,32],valueerror:[3,32],vari:[13,16,21],variabl:[26,33],varianc:15,variat:[27,31],varieti:18,vector:[1,10,30],vendor:33,verbos:24,veri:[22,32],verif:[29,30],verifi:30,version:[0,5,18,20,23,24,26,27,32],via:[0,9,20,23,24,26,28,30],view:[0,3,23,25],virtual:1,visibl:23,visual:20,vpi:0,vta:32,vulkan:0,wai:[5,18,20,23,24,28,30,31,32,33],wait:23,want:[0,20,30,32,33],wealth:30,welch:32,weld:30,well:[0,5,20,23,24,32,33],were:[7,30],what:[18,23,27,30,31,32,33],whatev:22,wheel:31,when:[0,3,6,7,10,11,12,13,14,15,16,17,20,22,23,26,27,30,31,32],whenev:32,where:[0,3,6,8,9,10,11,15,16,17,20,23,24,30,31,32],whether:[0,3,6,17,23,24,32],which:[0,1,3,4,7,9,10,11,12,14,15,17,20,21,23,24,28,30,31,32],who:[0,21,31],whose:[0,1,3,5,6,9,10,11,30,32],why:30,wide:[22,23,30],wider:[30,32],widest:23,wise:[0,1,8,21,30],wish:32,within:[0,3,9,16,18,23,24,30],without:[1,7,11,18,20,21,30,32],won:26,word:30,work:[20,22,23,27,30,32,33],worker:[26,32],world:28,worri:7,would:[3,9,22,30,32],wrap:32,write:[18,22,30,32],written:[18,30,32],x1_i:[0,6,12],x2_i:[0,6,12],x_i:[0,6],x_np:32,xarrai:[30,31],xla:32,xnd:[30,32],xor:[0,6],xtensor:30,y_i:6,year:[28,30],yet:[27,30],yield:12,york:30,you:[22,33],yyyi:[0,28],zero:[0,5,6,8,9,10,11,12,15,16,17,20,23,32],zeros_lik:8},titles:["Array object","Broadcasting","Constants","Creation Functions","Data type functions","Data Types","Element-wise Functions","Function and method signatures","API specification","Indexing","Linear Algebra Functions","Manipulation Functions","Searching Functions","Set Functions","Sorting Functions","Statistical Functions","Type Promotion Rules","Utility Functions","Assumptions","Benchmark suite","C API","Accuracy","Copy-view behaviour and mutability","Data interchange mechanisms","Device support","Design topics & constraints","Parallelism","Static typing","Future API standard evolution","Python array API standard","Purpose and scope","Usage Data","Use cases","Verification - test suite"],titleterms:{"boolean":[5,9],"case":[0,6,32],"float":[5,16],"function":[3,4,6,7,10,11,12,13,14,15,17,21],"return":[0,3,4,6,9,10,11,12,13,14,15,17],"static":27,"true":[3,14],"var":15,Use:[31,32],__abs__:0,__add__:0,__and__:0,__array_namespace__:0,__bool__:0,__dlpack__:0,__dlpack_device__:0,__eq__:0,__float__:0,__floordiv__:0,__ge__:0,__getitem__:0,__gt__:0,__int__:0,__invert__:0,__le__:0,__len__:0,__lshift__:0,__lt__:0,__matmul__:0,__mod__:0,__mul__:0,__ne__:0,__neg__:0,__or__:0,__pos__:0,__pow__:0,__rshift__:0,__setitem__:0,__sub__:0,__truediv__:0,__xor__:0,abs:6,acceler:32,accuraci:21,aco:6,acosh:6,add:[6,32],adding:32,adopt:30,algebra:[10,21],algorithm:1,all:17,ani:17,api:[2,3,4,6,8,10,11,12,13,14,15,17,20,28,29,30,32],api_vers:0,approach:20,arang:3,argmax:12,argmin:12,argsort:14,arithmet:21,arrai:[0,9,11,16,29,32],arrays_and_dtyp:4,asarrai:3,asin:6,asinh:6,assign:24,assumpt:18,atan2:6,atan:6,atanh:6,attribut:0,axes:10,axi:[9,10,11,12,14,15,17],axis1:10,axis2:10,backend:32,backward:[18,28],behaviour:22,benchmark:19,bitwise_and:6,bitwise_invert:6,bitwise_left_shift:6,bitwise_or:6,bitwise_right_shift:6,bitwise_xor:6,bool:5,broadcast:1,categori:5,ceil:6,choleski:10,code:[18,20],compat:[18,28],compil:32,comput:32,concat:11,concret:32,condit:12,conform:[30,33],constant:2,constraint:25,contain:20,content:29,copi:[3,22],correct:15,cos:6,cosh:6,creation:3,cross:10,cuda:0,cython:20,data:[4,5,23,31],decis:31,definit:30,depend:18,descend:14,design:[25,31],det:10,devic:[0,3,20,24],diagon:10,directli:20,distribut:32,divid:6,dlpack:23,document:30,dot:10,dtype:[0,3],easier:32,eig:10,eigvalsh:10,einop:32,einsum:10,element:6,empti:3,empty_lik:3,endpoint:3,environ:18,equal:6,evolut:28,exampl:[1,20],exp:6,expand_dim:11,expm1:6,extens:[5,20,28],eye:3,fals:[10,12,13,14,15,17],fill_valu:3,finfo:4,flip:11,float32:5,float64:5,floor:6,floor_divid:6,from_dlpack:3,full:3,full_lik:3,further:20,futur:[5,28],goal:30,greater:6,greater_equ:6,hardwar:[18,32],histori:30,how:30,hpy:20,iinfo:4,implement:23,implic:30,includ:30,index:9,inf:2,int16:5,int32:5,int64:5,int8:5,integ:[5,16],intend:24,interact:18,interchang:23,introduct:[30,31],inv:10,isfinit:6,isinf:6,isnan:6,jit:32,keepdim:[10,12,15,17],kei:0,later:30,less:6,less_equ:6,limit:20,linear:[10,21],linspac:3,log10:6,log1p:6,log2:6,log:6,logaddexp:6,logical_and:6,logical_not:6,logical_or:6,logical_xor:6,longer:20,lot:20,lstsq:10,make:[31,32],manipul:11,mathemat:21,matmul:10,matrix_pow:10,matrix_rank:10,max:15,mean:15,measur:33,mechan:23,method:[0,7],min:15,mix:16,more:32,mostli:20,multi:9,multipli:6,mutabl:22,nan:2,ndim:0,neg:6,non:30,none:[0,3,10,11,12,15,17],nonzero:12,norm:[10,30],not_equ:6,note:16,num:3,number:20,numer:5,numpi:20,obj:3,object:[0,2,3,4,6,10,11,12,13,14,15,17],offset:10,ones:3,ones_lik:3,oper:[0,21],ord:10,other:[0,20],out:[24,30],outer:10,overview:1,packag:20,parallel:26,paramet:[0,3,4,6,10,11,12,13,14,15,17],pinv:10,place:[0,1],point:[5,16],posit:6,pow:6,prod:15,product:18,promot:16,pure:20,purpos:30,python:[16,20,29,32],read:30,refer:30,reflect:0,remaind:6,remov:32,reshap:11,result_typ:4,return_count:13,return_index:13,return_invers:13,robust:32,rocm:0,roll:11,round:6,rule:16,run:33,scalar:16,scipi:32,scope:[24,28,30],search:12,self:0,semant:[1,23,24],set:13,shape:[0,3,11],shift:11,sign:[6,16],signatur:7,simplifi:32,sin:6,singl:9,sinh:6,situat:20,size:0,slice:9,slogdet:10,softwar:18,solv:10,sort:14,special:[0,6],specif:8,sqrt:6,squar:6,squeez:11,stabl:14,stack:11,stakehold:30,standard:[20,28,29,30],start:3,statist:[15,21],std:15,step:3,stop:3,stream:0,subtract:6,suit:[19,33],sum:15,support:[20,24,32],svd:10,syntax:[9,23,24],system:32,tabl:16,tan:6,tanh:6,tbd:30,term:[20,30],test:33,thi:30,topic:25,trace:10,transpos:10,trunc:6,type:[4,5,16,27,32],uint16:5,uint32:5,uint64:5,uint8:5,uniqu:13,unsign:16,usag:[20,24,31],use:[18,32],uses:20,util:17,valu:[0,9],verif:33,version:[28,30],view:22,where:12,whether:30,wise:6,xtensor:32,zero:3,zeros_lik:3}}) \ No newline at end of file diff --git a/latest/usage_data.html b/latest/usage_data.html new file mode 100644 index 000000000..b335f9bb1 --- /dev/null +++ b/latest/usage_data.html @@ -0,0 +1,698 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Usage Data — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ + +

+ Usage Data + + ¶ + +

+
+
+

+ Summary of existing array API design and usage. +

+
+
+
+

+ Introduction + + ¶ + +

+

+ With rare exception, technical standardization (“standardization”) occurs neither in a vacuum nor from first principles. Instead, standardization finds its origins in two or more, sometimes competing, implementations differing in design and behavior. These differences introduce friction as those (e.g., downstream end-users and library authors) who operate at higher levels of abstraction must either focus on an implementation subset (e.g., only NumPy-like array libraries) or accommodate variation through increased complexity (e.g., if NumPy array, call method + + + .foo() + + + ; else if Dask array, call method + + + .bar() + + + ). +

+

+ Standardization aspires to reduce this friction and is a process which codifies that which is common, while still encouraging experimentation and innovation. Through the process of standardization, implementations can align around a subset of established practices and channel development resources toward that which is new and novel. In short, standardization aims to thwart reinventing the proverbial wheel. +

+

+ A foundational step in standardization is articulating a subset of established practices and defining those practices in unambiguous terms. To this end, the standardization process must approach the problem from two directions: + + design + + and + + usage + + . The former direction seeks to understand +

+
    +
  • +

    + current implementation design (APIs, names, signatures, classes, and objects) +

    +
  • +
  • +

    + current implementation semantics (calling conventions and behavior) +

    +
  • +
+

+ while the latter direction seeks to quantify API +

+
    +
  • +

    + consumers (e.g., which downstream libraries utilize an API?) +

    +
  • +
  • +

    + usage frequency (e.g., how often is an API consumed?) +

    +
  • +
  • +

    + consumption patterns (e.g., which optional arguments are provided and in what context?) +

    +
  • +
+

+ By analyzing both design and usage, the standardization process grounds specification decisions in empirical data and analysis. +

+
+
+

+ Design + + ¶ + +

+

+ To understand API design, standardization follows the following process. +

+
    +
  • +

    + Identify a representative sample of commonly used Python array libraries (e.g., NumPy, Dask Array, CuPy, MXNet, JAX, TensorFlow, and PyTorch). +

    +
  • +
  • +

    + Acquire public APIs (e.g., by analyzing module exports and scraping public documentation). +

    +
  • +
  • +

    + Unify and standardize public API data representation for subsequent analysis. +

    +
  • +
  • +

    + Extract commonalities and differences by analyzing the intersection and complement of available APIs. +

    +
  • +
  • +

    + Derive a common API subset suitable for standardization (based on prevalence and ease of implementation), where such a subset may include attribute names, method names, and positional and keyword arguments. +

    +
  • +
  • +

    + Leverage usage data to validate API need and to inform naming conventions, supported data types, and/or optional arguments. +

    +
  • +
  • +

    + Summarize findings and provide tooling for additional analysis and exploration. +

    +
  • +
+

+ See the + + + + array-api-comparison + + + + repository for design data and summary analysis. +

+
+
+

+ Usage + + ¶ + +

+

+ To understand usage patterns, standardization follows the following process. +

+
    +
  • +

    + Identify a representative sample of commonly used Python libraries (“downstream libraries”) which consume the subset of array libraries identified during design analysis (e.g., pandas, Matplotlib, SciPy, Xarray, scikit-learn, and scikit-image). +

    +
  • +
  • +

    + Instrument downstream libraries in order to record Python array API calls. +

    +
  • +
  • +

    + Collect traces while running downstream library test suites. +

    +
  • +
  • +

    + Transform trace data into structured data (e.g., as JSON) for subsequent analysis. +

    +
  • +
  • +

    + Generate empirical APIs based on provided arguments and associated types, noting which downstream library called which empirical API and at what frequency. +

    +
  • +
  • +

    + Derive a single inferred API which unifies the individual empirical API calling semantics. +

    +
  • +
  • +

    + Organize API results in human-readable form as type definition files. +

    +
  • +
  • +

    + Compare the inferred API to the documented API. +

    +
  • +
+

+ The following is an inferred API for + + + numpy.arange + + + . The docstring includes the number of lines of code that invoked this function for each downstream library when running downstream library test suites. +

+
+
+
def arange(
+    _0: object,
+    /,
+    *_args: object,
+    dtype: Union[type, str, numpy.dtype, None] = ...,
+    step: Union[int, float] = ...,
+    stop: int = ...,
+):
+    """
+    usage.dask: 347
+    usage.matplotlib: 359
+    usage.pandas: 894
+    usage.sample-usage: 4
+    usage.scipy: 1173
+    usage.skimage: 174
+    usage.sklearn: 373
+    usage.xarray: 666
+    """
+    ...
+
+
+
+

+ See the + + + + python-record-api + + + + repository for source code, usage data, and analysis. To perform a similar analysis on additional downstream libraries, including those not publicly released, see the published PyPI + + package + + . +

+
+
+

+ Use in Decision-Making + + ¶ + +

+

+ Design and usage data support specification decision-making in the following ways. +

+
    +
  • +

    + Validate user stories to ensure that proposals satisfy existing needs. +

    +
  • +
  • +

    + Define scope to ensure that proposals address general array library design requirements (i.e., proposals must have broad applicability and be possible to implement with a reasonable amount of effort). +

    +
  • +
  • +

    + Inform technical design discussions to ensure that proposals are grounded in empirical data. +

    +
  • +
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/use_cases.html b/latest/use_cases.html new file mode 100644 index 000000000..41cb2ebb0 --- /dev/null +++ b/latest/use_cases.html @@ -0,0 +1,1070 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Use cases — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ + +
+
+
+ + +

+ Use cases + + ¶ + +

+

+ Use cases inform the requirements for, and design choices made in, this array +API standard. This section first discusses what types of use cases are +considered, and then works out a few concrete use cases in more detail. +

+
+

+ Types of use cases + + ¶ + +

+
    +
  • +

    + Packages that depend on a specific array library currently, and would like +to support multiple of them (e.g. for GPU or distributed array support, for +improved performance, or for reaching a wider user base). +

    +
  • +
  • +

    + Writing new libraries/tools that wrap multiple array libraries. +

    +
  • +
  • +

    + Projects that implement new types of arrays with, e.g., hardware-specific +optimizations or auto-parallelization behavior, and need an API to put on +top that is familiar to end users. +

    +
  • +
  • +

    + End users that want to switch from one library to another without learning +about all the small differences between those libraries. +

    +
  • +
+
+
+

+ Concrete use cases + + ¶ + +

+ +
+ + +

+ Use case 1: add hardware accelerator and distributed support to SciPy + + ¶ + +

+

+ When surveying a representative set of advanced users and research software +engineers in 2019 (for + + this NSF proposal + + ), +the single most common pain point brought up about SciPy was performance. +

+

+ SciPy heavily relies on NumPy (its only non-optional runtime dependency). +NumPy provides an array implementation that’s in-memory, CPU-only and +single-threaded. Common performance-related wishes users have are: +

+
    +
  • +

    + parallel algorithms (can be multi-threaded or multiprocessing based) +

    +
  • +
  • +

    + support for distributed arrays (with Dask in particular) +

    +
  • +
  • +

    + support for GPUs and other hardware accelerators (shortened to just “GPU” +in the rest of this use case) +

    +
  • +
+

+ Some parallelism can be supported in SciPy, it has a + + + workers + + + keyword +(similar to scikit-learn’s + + + n_jobs + + + keyword) that allows specifying to use +parallelism in some algorithms. However SciPy itself will not directly start +depending on a GPU or distributed array implementation, or contain (e.g.) +CUDA code - that’s not maintainable given the resources for development. + + However + + , there is a way to provide distributed or GPU support. Part of the +solution is provided by NumPy’s “array protocols” (see gh-1), that allow +dispatching to other array implementations. The main problem then becomes how +to know whether this will work with a particular distributed or GPU array +implementation - given that there are zero other array implementations that +are even close to providing full NumPy compatibility - without adding that +array implementation as a dependency. +

+

+ It’s clear that SciPy functionality that relies on compiled extensions (C, +C++, Cython, Fortran) directly can’t easily be run on another array library +than NumPy (see + + + C API + + + for more details about this topic). Pure Python +code can work though. There’s two main possibilities: +

+
    +
  1. +

    + Testing with another package, manually or in CI, and simply provide a list +of functionality that is found to work. Then make ad-hoc fixes to expand +the set that works. +

    +
  2. +
  3. +

    + Start relying on a well-defined subset of the NumPy API (or a new +NumPy-like API), for which compatibility is guaranteed. +

    +
  4. +
+

+ Option (2) seems strongly preferable, and that “well-defined subset” is + + what +an API standard should provide + + . Testing will still be needed, to ensure there +are no critical corner cases or bugs between array implementations, however +that’s then a very tractable task. +

+

+ As a concrete example, consider the spectral analysis functions in + + + scipy.signal + + + . +All of those functions (e.g., + + + periodogram + + + , + + + spectrogram + + + , + + + csd + + + , + + + welch + + + , + + + stft + + + , + + + istft + + + ) are pure Python - with the exception of + + + lombscargle + + + which is ~40 +lines of Cython - and uses NumPy function calls, array attributes and +indexing. The beginning of each function could be changed to retrieve the +module that implements the array API standard for the given input array type, +and then functions from that module could be used instead of NumPy functions. +

+

+ If the user has another array type, say a CuPy or PyTorch array + + + x + + + on their +GPU, doing: +

+
+
+
from scipy import signal
+
+signal.welch(x)
+
+
+
+

+ will result in: +

+
+
+
# For CuPy
+ValueError: object __array__ method not producing an array
+
+# For PyTorch
+TypeError: can't convert cuda:0 device type tensor to numpy.
+
+
+
+

+ and therefore the user will have to explicitly convert to and from a + + + numpy.ndarray + + + (which is quite inefficient): +

+
+
+
# For CuPy
+x_np = cupy.asnumpy(x)
+freq, Pxx = (cupy.asarray(res) for res in signal.welch(x_np))
+
+# For PyTorch
+x_np = x.cpu().numpy()
+# Note: ends up with tensors on CPU, may still have to move them back
+freq, Pxx = (torch.tensor(res) for res in signal.welch(x_np))
+
+
+
+

+ This code will look a little different for each array library. The end goal +here is to be able to write this instead as: +

+
+
+
freq, Pxx = signal.welch(x)
+
+
+
+

+ and have + + + freq + + + , + + + Pxx + + + be arrays of the same type and on the same device as + + + x + + + . +

+
+

+ Note +

+

+ This type of use case applies to many other libraries, from scikit-learn +and scikit-image to domain-specific libraries like AstroPy and +scikit-bio, to code written for a single purpose or user. +

+
+
+
+ + +

+ Use case 2: simplify einops by removing the backend system + + ¶ + +

+

+ + einops + + is a library that provides flexible tensor operations and supports many array libraries (NumPy, TensorFlow, PyTorch, CuPy, MXNet, JAX). +Most of the code in + + + einops + + + is: +

+
    +
  • +

    + + einops.py + + contains the functions it offers as public API ( + + + rearrange + + + , + + + reduce + + + , + + + repeat + + + ). +

    +
  • +
  • +

    + + _backends.py + + contains the glue code needed to support that many array libraries. +

    +
  • +
+

+ The amount of code in each of those two files is almost the same (~550 LoC each). +The typical pattern in + + + einops.py + + + is: +

+
+
+
def some_func(x):
+    ...
+    backend = get_backend(x)
+    shape = backend.shape(x)
+    result = backend.reduce(x)
+    ...
+
+
+
+

+ With a standard array API, the + + + _backends.py + + + glue layer could almost completely disappear, +because the purpose it serves (providing a unified interface to array operations from each +of the supported backends) is already addressed by the array API standard. +Hence the complete + + + einops + + + code base could be close to 50% smaller, and easier to maintain or add to. +

+
+

+ Note +

+

+ Other libraries that have a similar backend system to support many array libraries +include + + TensorLy + + , the (now discontinued) +multi-backend version of + + Keras + + , + + Unumpy + + and + + EagerPy + + . Many end users and +organizations will also have such glue code - it tends to be needed whenever +one tries to support multiple array types in a single API. +

+
+
+
+ + +

+ Use case 3: adding a Python API to xtensor + + ¶ + +

+

+ + xtensor + + is a C++ array library +that is NumPy-inspired and provides lazy arrays. It has Python (and Julia and R) +bindings, however it does not have a Python array API. +

+

+ Xtensor aims to follow NumPy closely, however it only implements a subset of functionality +and documents some API differences in + + Notable differences with NumPy + + . +

+

+ Note that other libraries document similar differences, see for example + + this page for JAX + + and + + this page for TensorFlow + + . +

+

+ Each time an array library author designs a new API, they have to choose (a) +what subset of NumPy makes sense to implement, and (b) where to deviate +because NumPy’s API for a particular function is suboptimal or the semantics +don’t fit their execution model. +

+

+ This array API standard aims to provide an API that can be readily adopted, +without having to make the above-mentioned choices. +

+
+

+ Note +

+

+ XND is another array library, written in C, that still needs a Python API. +Array implementations in other languages are often in a similar situation, +and could translate this array API standard 1:1 to their language. +

+
+
+
+ + +

+ Use case 4: make JIT compilation of array computations easier and more robust + + ¶ + +

+

+ + Numba + + is a Just-In-Time (JIT) compiler for +numerical functions in Python; it is NumPy-aware. + + PyPy + + is an implementation of Python with a JIT at its core; its NumPy support relies +on running NumPy itself through a compatibility layer ( + + + cpyext + + + ), while a +previous attempt to implement NumPy support directly was unsuccessful. +

+

+ Other array libraries may have an internal JIT (e.g., TensorFlow, PyTorch, +JAX, MXNet) or work with an external JIT like + + XLA + + or + + VTA + + . +

+

+ Numba currently has to jump through some hoops to accommodate NumPy’s casting rules +and may not attain full compatibility with NumPy in some cases - see, e.g., + + this + + or + + this + + example issue regarding (array) scalar +return values. +

+

+ An + + explicit suggestion from a Numba developer + + for this array API standard was: +

+
+
+

+ for JIT compilers (e.g. Numba) it will be important, that the type of the +returned value(s) depends only on the + + types + + of the input but not on the + + values + + . +

+
+
+

+ A concrete goal for this use case is to have better matching between +JIT-compiled and non-JIT execution. Here is an example from the Numba code +base, the need for which should be avoided in the future: +

+
+
+
def check(x, y):
+    got = cfunc(x, y)
+    np.testing.assert_array_almost_equal(got, pyfunc(x, y))
+    # Check the power operation conserved the input's dtype
+    # (this is different from Numpy, whose behaviour depends on
+    #  the *values* of the arguments -- see PyArray_CanCastArrayTo).
+    self.assertEqual(got.dtype, x.dtype)
+
+
+
+
+
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/latest/verification_test_suite.html b/latest/verification_test_suite.html new file mode 100644 index 000000000..89ba7414e --- /dev/null +++ b/latest/verification_test_suite.html @@ -0,0 +1,548 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Verification - test suite — Python array API standard 2021.01-DRAFT documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + +
+ +
+
+ +
+
+ +
+ +
+
+
+
+

+ Verification - test suite + + ¶ + +

+
+

+ Measuring conformance + + ¶ + +

+

+ In addition to the specification documents, a test suite is being developed to +aid library developers check conformance to the spec. + + NOTE: The test suite +is still a work in progress. + + It can be found at + + https://github.com/data-apis/array-api-tests + + . +

+

+ It is important to note that while the aim of the array API test suite is to +cover as much of the spec as possible, there are necessarily some aspects of +the spec that are not covered by the test suite, typically because they are +impossible to effectively test. Furthermore, if the test suite appears to +diverge in any way from what the spec documents say, this should be considered +a bug in the test suite. The specification is the ground source of truth. +

+
+
+

+ Running the tests + + ¶ + +

+

+ To run the tests, first clone the + + test suite +repo + + , and install the testing +dependencies, +

+
+
+
pip install pytest hypothesis
+
+
+
+

+ or +

+
+
+
conda install pytest hypothesis
+
+
+
+

+ as well as the array libraries that you want to test. To run the tests, you +need to specify the array library that is to be tested. There are two ways to +do this. One way is to set the + + + ARRAY_API_TESTS_MODULE + + + environment variable. +For example +

+
+
+
ARRAY_API_TESTS_MODULE=numpy pytest
+
+
+
+

+ Alternatively, edit the + + + array_api_tests/_array_module.py + + + file and change the +line +

+
+
+
array_module = None
+
+
+
+

+ to +

+
+
+
import numpy as array_module
+
+
+
+

+ (replacing + + + numpy + + + with the array module namespace to be tested). +

+

+ In either case, the tests should be run with the + + + pytest + + + command. +

+

+ Aside from the two testing dependencies ( + + + pytest + + + and + + + hypothesis + + + ), the test +suite has no dependencies. In particular, it does not depend on any specific +array libraries such as NumPy. All tests are run using only the array library +that is being tested, comparing results against the behavior as defined in the +spec. The test suite is designed to be standalone so that it can easily be vendored. +

+

+ See the + + README + + in the test suite repo for more information about how to run and interpret the +test suite results. +

+
+
+
+
+
+
+
+ + + + + \ No newline at end of file