text:
abstract type ChebInterp end

struct ChebPoly{T<:AbstractFloat, S<:Integer, N}

  weights::Array{T,N}
  order::Union{S,Array{S,1}}
  domain::Union{Array{T,1},Array{T,2}}

end

struct ChebInterpRoots{T<:AbstractFloat, S<:Integer, N} <: ChebInterp

  data::Array{T,N}
  nodes::NTuple{N,Array{T,1}}
  order::Union{S,Array{S,1}}
  domain::Union{Array{T,1},Array{T,2}}

end

struct ChebInterpExtrema{T<:AbstractFloat, S<:Integer, N} <: ChebInterp

  data::Array{T,N}
  nodes::NTuple{N,Array{T,1}}
  order::Union{S,Array{S,1}}
  domain::Union{Array{T,1},Array{T,2}}

end

struct ChebInterpExtended{T<:AbstractFloat, S<:Integer, N} <: ChebInterp

  data::Array{T,N}
  nodes::NTuple{N,Array{T,1}}
  order::Union{S,Array{S,1}}
  domain::Union{Array{T,1},Array{T,2}}

end

struct ChebInterpVertesi{T<:AbstractFloat, S<:Integer, N} <: ChebInterp

  data::Array{T,N}
  nodes::NTuple{N,Array{T,1}}
  order::Union{S,Array{S,1}}
  domain::Union{Array{T,1},Array{T,2}}

end

function chebyshev_nodes(n::S,domain = [1.0,-1.0]) where {S <: Integer}

  if n <= 0
    error("The number of nodes must be positive.")
  end

  nodes = zeros(n)

  if isodd(n)
    nodes[div(n-1,2)+1] = (domain[1]+domain[2])/2.0
  end

  for i = 1:div(n,2)
    x = -cos((i-0.5)*pi/n)*(domain[1]-domain[2])/2.0
    nodes[i]       = (domain[1]+domain[2])/2.0 + x
    nodes[end-i+1] = (domain[1]+domain[2])/2.0 - x
  end

  return nodes

end

function chebyshev_extrema(n::S,domain = [1.0,-1.0]) where S <: Integer

  if n <= 0
    error("The number of nodes must be positive.")
  end

  nodes = zeros(n)

  if isodd(n)
    nodes[div(n-1,2)+1] = (domain[1]+domain[2])/2.0
  end

  for i = 1:div(n,2)
    x = -cos((i-1)*pi/(n-1))*(domain[1]-domain[2])/2.0
    nodes[i]       = (domain[1]+domain[2])/2.0  + x
    nodes[end-i+1] = (domain[1]+domain[2])/2.0  - x
  end

  return nodes

end

function chebyshev_extended(n::S,domain = [1.0,-1.0]) where {S <: Integer}

  if n <= 0
    error("The number of nodes must be positive.")
  end

  nodes = zeros(n)

  if isodd(n)
    nodes[div(n-1,2)+1] = (domain[1]+domain[2])/2.0
  end

  for i = 1:div(n,2)
    x = -cos((i-0.5)*pi/n)*(domain[1]-domain[2])/2.0
    nodes[i]       = (domain[1]+domain[2])/2.0  + x
    nodes[end-i+1] = (domain[1]+domain[2])/2.0  - x
  end

  return nodes/(cos(pi/(2n)))

end

function vertesi_nodes(n::S,domain = [1.0,-1.0]) where {S <: Integer}

  if n <= 0
    error("The number of nodes must be positive.")
  end

  nodes = zeros(n)

  if isodd(n)
    nodes[div(n-1,2)+1] = (domain[1]+domain[2])/2.0
  end

  if n == 1

    return nodes

  elseif n == 2

    nodes[1] = domain[2]
    nodes[n] = domain[1]

    return nodes

  else

    nodes[1] = domain[2]
    nodes[n] = domain[1]

    for i = 2:div(n,2)
      x = -cos((pi/2)*(2(i-1)+1.0)/(n))/cos((pi/(2*(n)))*(1.0+1/(4*log(n))))*(domain[1]-domain[2])/2.0
      nodes[i]     = (domain[1]+domain[2])/2.0 + x
      nodes[n-i+1] = (domain[1]+domain[2])/2.0 - x
    end

    return nodes

  end

end

function chebyshev_quadrature(node_type::Function,n::S,domain = [1.0,-1.0]) where {S <: Integer}

  if n <= 0
    error("The number of nodes must be positive.")
  end

  nodes   = zeros(n)
  weights = zeros(n)

  if node_type == chebyshev_nodes # weighting function is (1.0 .- nodes.^2).^(-1/2) -- (first kind)

    for i = 1:n
      nodes[i] = (domain[1]+domain[2])/2.0 - cos((i-0.5)*pi/n)*(domain[1]-domain[2])/2.0
      weights[i] = pi/n
    end

    return nodes, weights

  elseif node_type == chebyshev_extrema # weighting function is (1.0 .- nodes.^2).^(1/2) -- (second kind)

    for i = 1:n
      nodes[i] = (domain[1]+domain[2])/2.0 - cos((i-1)*pi/(n-1))*(domain[1]-domain[2])/2.0
      weights[i] = (pi/(n-1))*sin(((i-1)/(n-1))*pi)^2
    end

    return nodes, weights

  else

    error("This node type is not supported")

  end

end

function normalize_node(node::R,domain::Array{T,1}) where {R<:Number,T<:AbstractFloat}

  if domain[1] == domain[2]
    norm_node = zero(T)
    return norm_node
  else
    norm_node = 2.0*(node-domain[2])/(domain[1]-domain[2])-1.0
    return norm_node
  end

end

function normalize_node(node::Array{R,1},domain::Array{T,1}) where {R<:Number,T<:AbstractFloat}

  norm_nodes = similar(node)
  for i in eachindex(node)
    norm_nodes[i] = normalize_node(node[i],domain)
  end

  return norm_nodes

end

function normalize_node!(node::Array{R,1},domain::Array{T,1}) where {R<:Number,T<:AbstractFloat}

  for i in eachindex(node)
    node[i] = normalize_node(node[i],domain)
  end

end

function chebyshev_polynomial(order::S,x::T) where {T<:Number,S<:Integer}

  polynomial    = Array{T}(undef,1,order+1)
  polynomial[1] = one(T)

  for i = 2:order+1
    if i == 2
      polynomial[i] = x
    else
      polynomial[i] = 2*x*polynomial[i-1]-polynomial[i-2]
    end
  end

  return polynomial

end

function chebyshev_polynomial(order::S,x::AbstractArray{T,1}) where {T<:Number,S<:Integer}

  polynomial      = Array{T}(undef,length(x),order+1)
  polynomial[:,1] = ones(T,length(x))

  for i = 2:order+1
    for j in eachindex(x)
      if i == 2
        polynomial[j,i] = x[j]
      else
        polynomial[j,i] = 2*x[j]*polynomial[j,i-1]-polynomial[j,i-2]
      end
    end
  end

  return polynomial

end

function derivative_of_chebyshev_polynomial(order::S,x::T) where {T<:Number,S<:Integer}

  polynomial    = Array{T}(undef,1,order+1)
  poly_deriv    = Array{T}(undef,1,order+1)
  polynomial[1] = one(T)
  poly_deriv[1] = zero(T)

  for i = 2:order+1
    if i == 2
      polynomial[i] = x
      poly_deriv[i] = one(T)
    else
      polynomial[i] = 2*x*polynomial[i-1]-polynomial[i-2]
      poly_deriv[i] = 2*polynomial[i-1]+2*x*poly_deriv[i-1]-poly_deriv[i-2]
    end
  end

  return poly_deriv

end

function derivative_of_chebyshev_polynomial(order::S,x::AbstractArray{T,1}) where {S<:Integer,T<:Number}

  polynomial    = Array{T}(undef,length(x),order+1)
  poly_deriv    = Array{T}(undef,length(x),order+1)
  polynomial[:,1] = one(T,length(x))
  poly_deriv[:,1] = zero(T,length(x))

  for i = 2:order+1
      for j in eachindex(x)
          if i == 2
              polynomial[j,i] = x[j]
              poly_deriv[j,i] = one(T)
          else
              polynomial[j,i] = 2*x[j]*polynomial[j,i-1]-polynomial[j,i-2]
              poly_deriv[j,i] = 2*polynomial[j,i-1]+2*x[j]*poly_deriv[j,i-1]-poly_deriv[j,i-2]
          end
      end
  end

  return poly_deriv

end

function chebyshev_weights(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  poly = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order[i],normalize_node(nodes[i],domain[:,i]))
  end

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      product = one(T)
      @inbounds for j = 1:N
        product *= poly[j][s[j],i[j]]
      end

      numerator   += f[s]*product
      denominator += product^2

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_extrema(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  n = size(f)

  poly = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order[i],normalize_node(nodes[i],domain[:,i]))
  end

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      num = f[s]
      den = one(T)
      @inbounds for j = 1:N
        if s[j] === 1 || s[j] === n[j]
          scale = 0.5
        else
          scale = 1.0
        end
        temp = poly[j][s[j],i[j]]
        num *= temp*scale
        den *= (temp^2)*scale
      end

      numerator   += num
      denominator += den

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_extended(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  poly       = Array{Array{T,2},1}(undef,N)
  complement = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i]       = chebyshev_polynomial(order[i],normalize_node(nodes[i],domain[:,i]))
    complement[i] = pinv(poly[i])'
  end

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      num = f[s]
      den = one(T)
      @inbounds for j = 1:N
        temp = complement[j][s[j],i[j]]
        num *= temp
        den *= temp*poly[j][s[j],i[j]]
      end

      numerator   += num
      denominator += den

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      product = one(T)
      @inbounds for j = 1:N
        product *= poly[j][s[j],i[j]]
      end

      numerator   += f[s]*product
      denominator += product^2

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_extrema(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  n = size(f)

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      num = f[s]
      den = one(T)
      @inbounds for j = 1:N
        if s[j] == 1 || s[j] == n[j]
          scale = 0.5
        else
          scale = 1.0
        end
        temp = poly[j][s[j],i[j]]
        num *= temp*scale
        den *= (temp^2)*scale
      end

      numerator   += num
      denominator += den

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_extended(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  complement = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    complement[i] = pinv(poly[i])'
  end

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      num = f[s]
      den = one(T)
      @inbounds for j = 1:N
        temp = complement[j][s[j],i[j]]
        num *= temp
        den *= temp*poly[j][s[j],i[j]]
      end

      numerator   += num
      denominator += den

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  poly = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order,normalize_node(nodes[i],domain[:,i]))
  end

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        product = one(T)
        @inbounds for j = 1:N
          product *= poly[j][s[j],i[j]]
        end

        numerator   += f[s]*product
        denominator += product^2

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_extrema(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  n = size(f)

  poly = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order,normalize_node(nodes[i],domain[:,i]))
  end

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        num = f[s]
        den = one(T)
        @inbounds for j = 1:N
          if s[j] == 1 || s[j] == n[j]
            scale = 0.5
          else
            scale = 1.0
          end
          temp = poly[j][s[j],i[j]]
          num *= temp*scale
          den *= (temp^2)*scale
        end

        numerator   += num
        denominator += den

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_extended(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  poly       = Array{Array{T,2},1}(undef,N)
  complement = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i]       = chebyshev_polynomial(order,normalize_node(nodes[i],domain[:,i]))
    complement[i] = pinv(poly[i])'
  end

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        num = f[s]
        den = one(T)
        @inbounds for j = 1:N
          temp = complement[j][s[j],i[j]]
          num *= temp
          den *= temp*poly[j][s[j],i[j]]
        end

        numerator   += num
        denominator += den

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::S) where {T<:AbstractFloat,N,S<:Integer}

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        product = one(T)
        @inbounds for j = 1:N
          product *= poly[j][s[j],i[j]]
        end

        numerator   += f[s]*product
        denominator += product^2

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_extrema(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::S) where {T<:AbstractFloat,N,S<:Integer}

  n = size(f)

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        num = f[s]
        den = one(T)
        @inbounds for j = 1:N
          if s[j] == 1 || s[j] == n[j]
            scale = 0.5
          else
            scale = 1.0
          end
          temp = poly[j][s[j],i[j]]
          num *= temp*scale
          den *= (temp^2)*scale
        end

        numerator   += num
        denominator += den

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_extended(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::S) where {T<:AbstractFloat,N,S<:Integer}

  complement = Array{Array{T,2},1}(undef,N)
  @inbounds for i = 1:N
    complement[i] = pinv(poly[i])'
  end

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        num = f[s]
        den = one(T)
        @inbounds for j = 1:N
          temp = complement[j][s[j],i[j]]
          num *= temp
          den *= temp*poly[j][s[j],i[j]]
        end

        numerator   += num
        denominator += den

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_threaded(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  poly = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order[i],normalize_node(nodes[i],domain[:,i]))
  end

  weights = zeros(Tuple(order.+1))

  @inbounds @sync @qthreads for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      product = one(T)
      @inbounds for j = 1:N
        product *= poly[j][s[j],i[j]]
      end

      numerator   += f[s]*product
      denominator += product^2

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_extrema_threaded(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  n = size(f)

  poly = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order[i],normalize_node(nodes[i],domain[:,i]))
  end

  weights = zeros(Tuple(order.+1))

  @inbounds @sync @qthreads for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      num = f[s]
      den = one(T)
      @inbounds for j = 1:N
        if s[j] == 1 || s[j] == n[j]
          scale = 0.5
        else
          scale = 1.0
        end
        temp = poly[j][s[j],i[j]]
        num *= temp*scale
        den *= (temp^2)*scale
      end

      numerator   += num
      denominator += den

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_extended_threaded(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  poly       = Array{Array{T,2},1}(undef,N)
  complement = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i]       = chebyshev_polynomial(order[i],normalize_node(nodes[i],domain[:,i]))
    complement[i] = pinv(poly[i])'
  end

  weights = zeros(Tuple(order.+1))

  @inbounds @sync @qthreads for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      num = f[s]
      den = one(T)
      @inbounds for j = 1:N
        temp = complement[j][s[j],i[j]]
        num *= temp
        den *= temp*poly[j][s[j],i[j]]
      end

      numerator   += num
      denominator += den

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_threaded(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds @sync @qthreads for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      product = one(T)
      @inbounds for j = 1:N
        product *= poly[j][s[j],i[j]]
      end

      numerator   += f[s]*product
      denominator += product^2

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_extrema_threaded(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  n = size(f)

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds @sync @qthreads for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      num = f[s]
      den = one(T)
      @inbounds for j = 1:N
        if s[j] == 1 || s[j] == n[j]
          scale = 0.5
        else
          scale = 1.0
        end
        temp = poly[j][s[j],i[j]]
        num *= temp*scale
        den *= (temp^2)*scale
      end

      numerator   += num
      denominator += den

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_extended_threaded(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  complement = Array{Array{T,2},1}(undef,N)
  @inbounds for i = 1:N
    complement[i] = pinv(poly[i])'
  end

  weights = Array{T,N}(undef,Tuple(order.+1))

  @inbounds @sync @qthreads for i in CartesianIndices(weights)

    numerator   = zero(T)
    denominator = zero(T)

    @inbounds for s in CartesianIndices(f)

      num = f[s]
      den = one(T)
      @inbounds for j = 1:N
        temp = complement[j][s[j],i[j]]
        num *= temp
        den *= temp*poly[j][s[j],i[j]]
      end

      numerator   += num
      denominator += den

    end

    weights[i] = numerator/denominator

  end

  return weights

end

function chebyshev_weights_threaded(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  poly = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order,normalize_node(nodes[i],domain[:,i]))
  end

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds @sync @qthreads for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        product = one(T)
        @inbounds for j = 1:N
          product *= poly[j][s[j],i[j]]
        end

        numerator   += f[s]*product
        denominator += product^2

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_extrema_threaded(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  n = size(f)

  poly = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order,normalize_node(nodes[i],domain[:,i]))
  end

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds @sync @qthreads for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        num = f[s]
        den = one(T)
        @inbounds for j = 1:N
          if s[j] == 1 || s[j] == n[j]
            scale = 0.5
          else
            scale = 1.0
          end
          temp = poly[j][s[j],i[j]]
          num *= temp*scale
          den *= (temp^2)*scale
        end

        numerator   += num
        denominator += den

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_extended_threaded(f::Array{T,N},nodes::NTuple{N,Array{T,1}},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  poly       = Array{Array{T,2},1}(undef,N)
  complement = Array{Array{T,2},1}(undef,N)

  @inbounds for i = 1:N
    poly[i]       = chebyshev_polynomial(order,normalize_node(nodes[i],domain[:,i]))
    complement[i] = pinv(poly[i])'
  end

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds @sync @qthreads for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        num = f[s]
        den = one(T)
        @inbounds for j = 1:N
          temp = complement[j][s[j],i[j]]
          num *= temp
          den *= temp*poly[j][s[j],i[j]]
        end

        numerator   += num
        denominator += den

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_threaded(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::S) where {T<:AbstractFloat,N,S<:Integer}

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds @sync @qthreads for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        product = one(T)
        @inbounds for j = 1:N
          product *= poly[j][s[j],i[j]]
        end

        numerator   += f[s]*product
        denominator += product^2

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_extrema_threaded(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::S) where {T<:AbstractFloat,N,S<:Integer}

  n = size(f)

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds @sync @qthreads for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        num = f[s]
        den = one(T)
        @inbounds for j = 1:N
          if s[j] == 1 || s[j] == n[j]
            scale = 0.5
          else
            scale = 1.0
          end
          temp = poly[j][s[j],i[j]]
          num *= temp*scale
          den *= (temp^2)*scale
        end

        numerator   += num
        denominator += den

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights_extended_threaded(f::Array{T,N},poly::NTuple{N,Array{T,2}},order::S) where {T<:AbstractFloat,N,S<:Integer}

  complement = Array{Array{T,2},1}(undef,N)
  @inbounds for i = 1:N
    complement[i] = pinv(poly[i])'
  end

  ord = (order,)
  for i = 2:N
    ord = (ord...,order)
  end

  weights = Array{T,N}(undef,ord.+1)

  @inbounds @sync @qthreads for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N

      numerator   = zero(T)
      denominator = zero(T)

      @inbounds for s in CartesianIndices(f)

        num = f[s]
        den = one(T)
        @inbounds for j = 1:N
          temp = complement[j][s[j],i[j]]
          num *= temp
          den *= temp*poly[j][s[j],i[j]]
        end

        numerator   += num
        denominator += den

      end

      weights[i] = numerator/denominator

    else
      weights[i] = zero(T)
    end

  end

  return weights

end

function chebyshev_weights(cheb::ChebInterpRoots)

  weights = chebyshev_weights_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  return weights

end

function chebyshev_weights(cheb::ChebInterpExtrema)

  weights = chebyshev_weights_extrema_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  return weights

end

function chebyshev_weights(cheb::ChebInterpExtended)

  weights = chebyshev_weights_extended_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  return weights

end

function chebyshev_weights(cheb::ChebInterpVertesi)

  weights = chebyshev_weights_vertesi_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  return weights

end

# Functions for the one-variable case where the nodes are a vector

function chebyshev_weights(f::Array{T,1},nodes::Array{T,1},order::Union{S,Array{S,1}},domain=[one(T);-one(T)]) where {T<:AbstractFloat,S<:Integer}

  weights = chebyshev_weights(f,(nodes,),order,domain)

  return weights

end

function chebyshev_weights_extrema(f::Array{T,1},nodes::Array{T,1},order::Union{S,Array{S,1}},domain=[one(T);-one(T)]) where {T<:AbstractFloat,S<:Integer}

  weights = chebyshev_weights_extrema(f,(nodes,),order,domain)

  return weights

end

function chebyshev_weights_extended(f::Array{T,1},nodes::Array{T,1},order::Union{S,Array{S,1}},domain=[one(T);-one(T)]) where {T<:AbstractFloat,S<:Integer}

  weights = chebyshev_weights_extended(f,(nodes,),order,domain)

  return weights

end

function chebyshev_weights(f::Array{T,1},poly::Array{T,2},order::Union{S,Array{S,1}}) where {T<:AbstractFloat,S<:Integer}

  weights = chebyshev_weights(f,(poly,),order)

  return weights

end

function chebyshev_weights_extrema(f::Array{T,1},poly::Array{T,2},order::Union{S,Array{S,1}}) where {T<:AbstractFloat,S<:Integer}

  weights = chebyshev_weights_extrema(f,(poly,),order)

  return weights

end

function chebyshev_weights_extended(f::Array{T,1},poly::Array{T,2},order::Union{S,Array{S,1}}) where {T<:AbstractFloat,S<:Integer}

  weights = chebyshev_weights_extended(f,(poly,),order)

  return weights

end

# Functions that allow the nodes to be in an array of arrays

function chebyshev_weights(f::Array{T,N},nodes::Array{Array{T,1},1},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_extrema(f::Array{T,N},nodes::Array{Array{T,1},1},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extrema(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_extended(f::Array{T,N},nodes::Array{Array{T,1},1},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extended(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights(f::Array{T,N},poly::Array{Array{T,2},1},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_extrema(f::Array{T,N},poly::Array{Array{T,2},1},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extrema(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_extended(f::Array{T,N},poly::Array{Array{T,2},1},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extended(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights(f::Array{T,N},nodes::Array{Array{T,1},1},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_extrema(f::Array{T,N},nodes::Array{Array{T,1},1},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extrema(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_extended(f::Array{T,N},nodes::Array{Array{T,1},1},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extended(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights(f::Array{T,N},poly::Array{Array{T,2},1},order::S) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_extrema(f::Array{T,N},poly::Array{Array{T,2},1},order::S) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extrema(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_extended(f::Array{T,N},poly::Array{Array{T,2},1},order::S) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extended(f,tuple(poly...),order)

  return weights

end

# Threaded functions

function chebyshev_weights_threaded(f::Array{T,N},nodes::Array{Array{T,1},1},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_threaded(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_extrema_threaded(f::Array{T,N},nodes::Array{Array{T,1},1},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extrema_threaded(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_extended_threaded(f::Array{T,N},nodes::Array{Array{T,1},1},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extended_threaded(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_threaded(f::Array{T,N},poly::Array{Array{T,2},1},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_threaded(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_extrema_threaded(f::Array{T,N},poly::Array{Array{T,2},1},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extrema_threaded(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_extended_threaded(f::Array{T,N},poly::Array{Array{T,2},1},order::Array{S,1}) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extended_threaded(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_threaded(f::Array{T,N},nodes::Array{Array{T,1},1},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_threaded(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_extrema_threaded(f::Array{T,N},nodes::Array{Array{T,1},1},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extrema_threaded(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_extended_threaded(f::Array{T,N},nodes::Array{Array{T,1},1},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extended_threaded(f,tuple(nodes...),order,domain)

  return weights

end

function chebyshev_weights_threaded(f::Array{T,N},poly::Array{Array{T,2},1},order::S) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_threaded(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_extrema_threaded(f::Array{T,N},poly::Array{Array{T,2},1},order::S) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extrema_threaded(f,tuple(poly...),order)

  return weights

end

function chebyshev_weights_extended_threaded(f::Array{T,N},poly::Array{Array{T,2},1},order::S) where {T<:AbstractFloat,N,S<:Integer}

  weights = chebyshev_weights_extended_threaded(f,tuple(poly...),order)

  return weights

end

const chebyshev_weights_vertesi          = chebyshev_weights_extended
const chebyshev_weights_vertesi_threaded = chebyshev_weights_extended_threaded

# Regular functions for evaluating Chebyshev polynominals

function chebyshev_evaluate(weights::Array{T,N},x::AbstractArray{R,1},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,R<:Number,N,S<:Integer}

  poly = Array{Array{R,2},1}(undef,N)
  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order[i],normalize_node(x[i],domain[:,i]))
  end

  yhat = zero(T)
  @inbounds for i in CartesianIndices(weights)
    poly_product = poly[1][i[1]]
    @inbounds for j = 2:N
      poly_product *= poly[j][i[j]]
    end
    yhat += weights[i]*poly_product
  end

  return yhat

end

function chebyshev_evaluate(weights::Array{T,N},x::AbstractArray{R,1},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,R<:Number,N,S<:Integer}

  poly = Array{Array{R,2},1}(undef,N)
  @inbounds for i = 1:N
    poly[i] = chebyshev_polynomial(order,normalize_node(x[i],domain[:,i]))
  end

  yhat = zero(T)
  @inbounds for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N
      poly_product = poly[1][i[1]]
      @inbounds for j = 2:N
        poly_product *= poly[j][i[j]]
      end
      yhat += weights[i]*poly_product
    end
  end

  return yhat

end

function chebyshev_evaluate(cheb_poly::ChebPoly,x::AbstractArray{R,1}) where {R<:Number}

  yhat = chebyshev_evaluate(cheb_poly.weights,x,cheb_poly.order,cheb_poly.domain)

  return yhat

end

function cheb_interp(cheb::ChebInterpRoots,x::AbstractArray{R,1}) where {R<:Number}

  weights = chebyshev_weights_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  yhat    = chebyshev_evaluate(weights,x,cheb.order,cheb.domain)

  return yhat

end

function cheb_interp(cheb::ChebInterpExtrema,x::AbstractArray{R,1}) where {R<:Number}

  weights = chebyshev_weights_extrema_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  yhat    = chebyshev_evaluate(weights,x,cheb.order,cheb.domain)

  return yhat

end

function cheb_interp(cheb::ChebInterpExtended,x::AbstractArray{R,1}) where {R<:Number}

  weights = chebyshev_weights_extended_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  yhat    = chebyshev_evaluate(weights,x,cheb.order,cheb.domain)

  return yhat

end

function cheb_interp(cheb::ChebInterpVertesi,x::AbstractArray{R,1}) where {R<:Number}

  weights = chebyshev_weights_vertesi_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  yhat    = chebyshev_evaluate(weights,x,cheb.order,cheb.domain)

  return yhat

end

function chebyshev_evaluate(weights::Array{T,N},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T <: AbstractFloat,N,S <: Integer}

  function chebeval(x::AbstractArray{R,1}) where {R <: Number}

    return chebyshev_evaluate(weights,x,order,domain)

  end

  return chebeval

end

function chebyshev_evaluate(weights::Array{T,N},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T <: AbstractFloat,N,S <: Integer}

  function chebeval(x::AbstractArray{R,1}) where {R <: Number}

    return chebyshev_evaluate(weights,x,order,domain)

  end

  return chebeval

end

function chebyshev_evaluate(cheb_poly::ChebPoly)

  function chebeval(x::AbstractArray{R,1}) where {R <: Number}

    return chebyshev_evaluate(cheb_poly,x)

  end

  return chebeval

end

function cheb_interp(cheb::ChebInterpRoots)

  weights = chebyshev_weights_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebeval(x::AbstractArray{R,1}) where {R <: Number}

    return chebyshev_evaluate(weights,x,cheb.order,cheb.domain)

  end

  return chebeval

end

function cheb_interp(cheb::ChebInterpExtrema)

  weights = chebyshev_weights_extrema_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebeval(x::AbstractArray{R,1}) where {R <: Number}

    return chebyshev_evaluate(weights,x,cheb.order,cheb.domain)

  end

  return chebeval

end

function cheb_interp(cheb::ChebInterpExtended)

  weights = chebyshev_weights_extended_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebeval(x::AbstractArray{R,1}) where {R <: Number}

    return chebyshev_evaluate(weights,x,cheb.order,cheb.domain)

  end

  return chebeval

end

function cheb_interp(cheb::ChebInterpVertesi)

  weights = chebyshev_weights_vertesi_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebeval(x::AbstractArray{R,1}) where {R <: Number}

    return chebyshev_evaluate(weights,x,cheb.order,cheb.domain)

  end

  return chebeval

end

# Regular functions for evaluating derivatives and gradients of Chebyshev polynomials

# Regular functions for derivatives

function chebyshev_derivative(weights::Array{T,N},x::AbstractArray{R,1},pos::S,order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,R<:Number,N,S<:Integer}

  poly = Array{Array{R,2},1}(undef,N)
  @inbounds for i = 1:N
    if i === pos
      poly[i] = derivative_of_chebyshev_polynomial(order[i],normalize_node(x[i],domain[:,i]))
    else
      poly[i] = chebyshev_polynomial(order[i],normalize_node(x[i],domain[:,i]))
    end
  end

  derivative = zero(T)
  @inbounds for i in CartesianIndices(weights)
    poly_product = poly[1][i[1]]
    @inbounds for j = 2:N
      poly_product *= poly[j][i[j]]
    end
    derivative += weights[i]*poly_product
  end

  return derivative*(2.0/(domain[1,pos]-domain[2,pos]))

end

function chebyshev_derivative(weights::Array{T,N},x::AbstractArray{R,1},pos::S,order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,R<:Number,N,S<:Integer}

  poly = Array{Array{R,2},1}(undef,N)
  @inbounds for i = 1:N
    if i === pos
      poly[i] = derivative_of_chebyshev_polynomial(order,normalize_node(x[i],domain[:,i]))
    else
      poly[i] = chebyshev_polynomial(order,normalize_node(x[i],domain[:,i]))
    end
  end

  derivative = zero(T)
  @inbounds for i in CartesianIndices(weights)
    if sum(Tuple(i)) <= order+N
      poly_product = poly[1][i[1]]
      @inbounds for j = 2:N
        poly_product *= poly[j][i[j]]
      end
      derivative += weights[i]*poly_product
    end
  end

  return derivative*(2.0/(domain[1,pos]-domain[2,pos]))

end

function chebyshev_derivative(cheb_poly::ChebPoly,x::AbstractArray{R,1},pos::S) where {T<:AbstractFloat,R<:Number,S<:Integer}

  derivative = chebyshev_derivative(cheb_poly.weights,x,pos,cheb_poly.order,cheb_poly.domain)

  return derivative

end

function chebyshev_derivative(cheb::ChebInterpRoots,x::AbstractArray{R,1},pos::S) where {T<:AbstractFloat,R<:Number,S<:Integer}

  weights    = chebyshev_weights_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  derivative = chebyshev_derivative(weights,x,pos,cheb.order,cheb.domain)

  return derivative

end

function chebyshev_derivative(cheb::ChebInterpExtrema,x::AbstractArray{R,1},pos::S) where {T<:AbstractFloat,R<:Number,S<:Integer}

  weights    = chebyshev_weights_extrema_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  derivative = chebyshev_derivative(weights,x,pos,cheb.order,cheb.domain)

  return derivative

end

function chebyshev_derivative(cheb::ChebInterpExtended,x::AbstractArray{R,1},pos::S) where {T<:AbstractFloat,R<:Number,S<:Integer}

  weights    = chebyshev_weights_extended_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  derivative = chebyshev_derivative(weights,x,pos,cheb.order,cheb.domain)

  return derivative

end

# Regular functions for gradients

function chebyshev_gradient(weights::Array{T,N},x::AbstractArray{R,1},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,R<:Number,N,S<:Integer}

  gradient = Array{R,2}(undef,1,N)

  @inbounds for i = 1:N
    gradient[i] = chebyshev_derivative(weights,x,i,order,domain)
  end

  return gradient

end

function chebyshev_gradient(weights::Array{T,N},x::AbstractArray{R,1},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T<:AbstractFloat,R<:Number,N,S<:Integer}

  gradient = Array{R,2}(undef,1,N)

  @inbounds for i = 1:N
    gradient[i] = chebyshev_derivative(weights,x,i,order,domain)
  end

  return gradient

end

function chebyshev_gradient(cheb_poly::ChebPoly,x::AbstractArray{R,1}) where {R<:Number}

  gradient = chebyshev_gradient(cheb_poly.weights,x,cheb_poly.order,cheb_poly.domain)

  return gradient

end

function chebyshev_gradient(cheb::ChebInterpRoots,x::AbstractArray{R,1}) where {R<:Number}

  weights  = chebyshev_weights_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  gradient = chebyshev_gradient(weights,x,cheb.order,cheb.domain)

  return gradient

end

function chebyshev_gradient(cheb::ChebInterpExtrema,x::AbstractArray{R,1}) where {R<:Number}

  weights  = chebyshev_weights_extrema_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  gradient = chebyshev_gradient(weights,x,cheb.order,cheb.domain)

  return gradient

end

function chebyshev_gradient(cheb::ChebInterpExtended,x::AbstractArray{R,1}) where {R<:Number}

  weights  = chebyshev_weights_extended_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  gradient = chebyshev_gradient(weights,x,cheb.order,cheb.domain)

  return gradient

end

function chebyshev_gradient(cheb::ChebInterpVertesi,x::AbstractArray{R,1}) where {R<:Number}

  weights  = chebyshev_weights_vertesi_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)
  gradient = chebyshev_gradient(weights,x,cheb.order,cheb.domain)

  return gradient

end

function chebyshev_derivative(weights::Array{T,N},pos::S,order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T <: AbstractFloat,N,S <: Integer}

  function chebderiv(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_derivative(weights,x,pos,order,domain)

  end

  return chebderiv

end

function chebyshev_derivative(weights::Array{T,N},pos::S,order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T <: AbstractFloat,N,S <: Integer}

  function chebderiv(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_derivative(weights,x,pos,order,domain)

  end

  return chebderiv

end

function chebyshev_derivative(cheb_poly::ChebPoly,pos::S) where {S <: Integer}

  function chebderiv(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_derivative(cheb_poly,x,pos)

  end

  return chebderiv

end

function chebyshev_derivative(cheb::ChebInterpRoots,pos::S) where {S <: Integer}

  weights = chebyshev_weights_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebderiv(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_derivative(weights,x,pos,cheb.order,cheb.domain)

  end

  return chebderiv

end

function chebyshev_derivative(cheb::ChebInterpExtrema,pos::S) where {S <: Integer}

  weights = chebyshev_weights_extrema_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebderiv(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_derivative(weights,x,pos,cheb.order,cheb.domain)

  end

  return chebderiv

end

function chebyshev_derivative(cheb::ChebInterpExtended,pos::S) where {S <: Integer}

  weights = chebyshev_weights_extended_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebderiv(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_derivative(weights,x,pos,cheb.order,cheb.domain)

  end

  return chebderiv

end

function chebyshev_derivative(cheb::ChebInterpVertesi,pos::S) where {S <: Integer}

  weights = chebyshev_weights_vertesi_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebderiv(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_derivative(weights,x,pos,cheb.order,cheb.domain)

  end

  return chebderiv

end

function chebyshev_gradient(weights::Array{T,N},order::Array{S,1},domain=[ones(T,1,N);-ones(T,1,N)]) where {T <: AbstractFloat,N,S <: Integer}

  function chebgrad(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_gradient(weights,x,pos,order,domain)

  end

  return chebgrad

end

function chebyshev_gradient(weights::Array{T,N},order::S,domain=[ones(T,1,N);-ones(T,1,N)]) where {T <: AbstractFloat,N,S <: Integer}

  function chebgrad(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_gradient(weights,x,pos,order,domain)

  end

  return chebgrad

end

function chebyshev_gradient(cheb_poly::ChebPoly) where {S <: Integer}

  function chebgrad(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_gradient(cheb_poly,x)

  end

  return chebgrad

end

function chebyshev_gradient(cheb::ChebInterpRoots) where {S <: Integer}

  weights = chebyshev_weights_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebgrad(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_gradient(weights,x,cheb.order,cheb.domain)

  end

  return chebgrad

end

function chebyshev_gradient(cheb::ChebInterpExtrema) where {S <: Integer}

  weights = chebyshev_weights_extrema_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebgrad(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_gradient(weights,x,cheb.order,cheb.domain)

  end

  return chebgrad

end

function chebyshev_gradient(cheb::ChebInterpExtended) where {S <: Integer}

  weights = chebyshev_weights_extended_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebgrad(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_gradient(weights,x,cheb.order,cheb.domain)

  end

  return chebgrad

end

function chebyshev_gradient(cheb::ChebInterpVertesi) where {S <: Integer}

  weights = chebyshev_weights_vertesi_threaded(cheb.data,cheb.nodes,cheb.order,cheb.domain)

  function chebgrad(x::AbstractArray{R,1}) where {R<:Number}

    return chebyshev_gradient(weights,x,cheb.order,cheb.domain)

  end

  return chebgrad

end


text:
namespace Bridge.Html5
{
    /// <summary>
    /// The HTMLUnknownElement interface represents an invalid HTML element and derives from the HTMLElement interface, but without implementing any additional properties or methods.
    /// Obsolete or non-standard HTML elements implementing this interface: <bgsound>, <blink>, <isindex>, <multicol>, <nextid>, <rb>, <spacer>
    /// </summary>
    [External]
    [Name("HTMLUnknownElement")]
    public sealed class HTMLUnknownElement : HTMLElement<HTMLUnknownElement>
    {
        [Template("document.createElement({0})")]
        public extern HTMLUnknownElement(string tagName);
    }
}

redpajama_set_name: RedPajamaGithub


text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// File: DataBlob.h
//

//
// Class code:MetaData::DataBlob provides secure access to a block of memory from MetaData (i.e. with fixed
// endianess).
//
// ======================================================================================

#pragma once

#include "external.h"

namespace MetaData
{

// --------------------------------------------------------------------------------------
//
// This class provides secure access to a block of memory.
//
class DataBlob
{
private:
    //
    // Private data
    //

    // The memory block of size code:m_cbSize. Can be non-NULL even if code:m_cbSize is 0.
    __field_bcount(m_cbSize)
    BYTE  *m_pbData;
    // Size of the memory block starting at code:m_pbData. If it is 0, then value of code:m_pbData can be
    // anything (incl. NULL).
    UINT32 m_cbSize;

public:
    //
    // Initialization
    //

    // Creates empty memory block.
    inline DataBlob();
    // Creates memory block (pbData, of size cbSize).
    inline DataBlob(
        __in_bcount_opt(cbSize) BYTE  *pbData,
                                UINT32 cbSize);
    // Creates memory block copy.
    inline DataBlob(
        const DataBlob &source);
    // Initializes memory block to empty data. The object could be already initialzied.
    inline void Clear();
    // Initializes memory block to data (pbData, of size cbSize). The object should be empty before.
    inline void Init(
        __in_bcount_opt(cbSize) BYTE  *pbData,
                                UINT32 cbSize);

    //
    // Getters
    //

    //#PeekUx_Functions
    // Reads the U1/U2/U4/U8 from the data blob without skipping the read data.
    // Returns FALSE if there's not enough data in the blob, doesn't initialize the value '*pnValue' then.
    // Returns TRUE otherwise, fills *pnValue, but doesn't move the memory block (doesn't skip the read
    // data).
    __checkReturn __success(return) inline BOOL PeekU1(__out BYTE   *pnValue) const;
    __checkReturn __success(return) inline BOOL PeekU2(__out UINT16 *pnValue) const;
    __checkReturn __success(return) inline BOOL PeekU4(__out UINT32 *pnValue) const;
    __checkReturn __success(return) inline BOOL PeekU8(__out UINT64 *pnValue) const;

    //#GetUx_Functions
    // Reads the U1/U2/U4/U8 from the data blob and skips the read data.
    // Returns FALSE if there's not enough data in the blob, doesn't initialize the value '*pnValue' then.
    // Returns TRUE otherwise, fills *pnValue and moves the memory block behind the read data.
    __checkReturn __success(return) inline BOOL GetU1(__out BYTE   *pnValue);
    __checkReturn __success(return) inline BOOL GetU2(__out UINT16 *pnValue);
    __checkReturn __success(return) inline BOOL GetU4(__out UINT32 *pnValue);
    __checkReturn __success(return) inline BOOL GetU8(__out UINT64 *pnValue);

    // Reads compressed integer (1, 2 or 4 bytes of format code:CompressedInteger#Format - returns the size
    // in *pcbCompressedValueSize) from the data blob without skipping the read data.
    // Returns FALSE if there's not enough data in the blob or the compression is invalid (starts with byte
    // 111? ????), doesn't initialize the value *pnValue nor the size of the compressed value
    // *pcbCompressedValueSize then.
    // Returns TRUE otherwise, fills *pnValue and *pcbCompressedValueSize (with number 1,2 or 4), but
    // doesn't move the memory block (doesn't skip the read data).
    __checkReturn
    __success(return)
    inline BOOL PeekCompressedU(
        __out UINT32 *pnValue,
        __out UINT32 *pcbCompressedValueSize);
    // Reads compressed integer (1, 2 or 4 bytes of format code:CompressedInteger#Format) from the data blob
    // and skips the read data.
    // Returns FALSE if there's not enough data in the blob or the compression is invalid (starts with byte
    // 111? ????), doesn't initialize the value *pnValue then.
    // Returns TRUE otherwise, fills *pnValue and moves the memory block behind the read data.
    __checkReturn
    __success(return)
    inline BOOL GetCompressedU(__out UINT32 *pnValue);
    // Reads compressed integer (1, 2 or 4 bytes of format code:CompressedInteger#Format - returns the size
    // in *pcbCompressedValueSize) from the data blob and skips the read data.
    // Returns FALSE if there's not enough data in the blob or the compression is invalid (starts with byte
    // 111? ????), doesn't initialize the value *pnValue nor the size of the compressed value
    // *pcbCompressedValueSize then.
    // Returns TRUE otherwise, fills *pnValue and *pcbCompressedValueSize (with number 1,2 or 4) and moves
    // the memory block behind the read data.
    __checkReturn
    __success(return)
    inline BOOL GetCompressedU(
        __out UINT32 *pnValue,
        __out UINT32 *pcbCompressedValueSize);

    // Reads data of size cbDataSize and skips the data (instead of reading the bytes, returns the data as
    // *pData).
    // Returns FALSE if there's not enough data in the blob, clears *pData then.
    // Returns TRUE otherwise, fills *pData with the "read" data and moves the memory block behind the
    // "read" data.
    __checkReturn
    __success(return)
    inline BOOL GetDataOfSize(
              UINT32    cbDataSize,
        __out DataBlob *pData);

    // Checks if there's at least cbDataSize bytes in the represented memory block.
    // Returns TRUE if there's >= cbDataSize bytes. Returns FALSE otherwise.
    inline BOOL ContainsData(UINT32 cbDataSize) const
        { return cbDataSize <= m_cbSize; }
/*
    // Checks if there's at least cbDataSize1 + cbDataSize2 bytes in the represented memory block (and that
    // the sum doesn't overflow).
    // Returns TRUE if there's >= cbDataSize1 + cbDataSize2 bytes.
    // Returns FALSE otherwise and if cbDataSize1 + cbDataSize2 overflows.
    inline BOOL ContainsData_2Parts(
        UINT32 cbDataSize1,
        UINT32 cbDataSize2) const;
    // Checks if there's valid compressed integer (1, 2 or 4 bytes of format
    // code:DataBlob#CompressedIntegerFormat) in the data blob.
    // Returns:
    //  * 0 ... if there's valid compressed integer.
    //  * 1 ... if there's not enough data in the data blob, but the encoding is correct.
    //  * 2 ... if the integer encoding is invalid (starts with byte 111x xxxx byte), but there are at least
    //          4 bytes in the data blob left.
    //  * 3 ... if there's not enough data in the data blob and the integer encoding is invalid (starts with
    //          111x xxx byte).
    inline int ValidateCompressedU() const;
*/

    // Returns TRUE if the represented memory is empty.
    inline BOOL IsEmpty() const
        { return (m_cbSize == 0); }
    // Gets pointer to the represented data buffer (can be random pointer if size of the data is 0).
    // Note: Should be used exceptionally. Try to use other operations instead.
    inline BYTE *GetDataPointer()
        { return m_pbData; }
    // Gets pointer to the represented data buffer (can be random pointer if size of the data is 0).
    // Note: Should be used exceptionally. Try to use other operations instead.
    inline const BYTE *GetDataPointer() const
        { return m_pbData; }
    // Gets pointer right behind the represented data buffer (can be random pointer if size of the data is
    // 0).
    inline const BYTE *GetDataPointerBehind() const
        { return ((m_cbSize == 0) ? NULL : (m_pbData + m_cbSize)); }
    // Gets the size of represented memory.
    inline UINT32 GetSize() const
        { return m_cbSize; }
    //BOOL SkipBytes(UINT32 cbSize);

public:
    //
    // Operations
    //

    // Truncates the buffer to exact size (cbSize).
    // Returns FALSE if there's less than cbSize data represented.
    // Returns TRUE otherwise and truncates the represented data size to cbSize.
    __checkReturn
    __success(return)
    inline BOOL TruncateToExactSize(UINT32 cbSize);
    // Truncates the buffer by size (cbSize).
    // Returns FALSE if there's less than cbSize data represented.
    // Returns TRUE otherwise and truncates the represented data size by cbSize.
    __checkReturn
    __success(return)
    inline BOOL TruncateBySize(UINT32 cbSize);

#ifdef _DEBUG
    // Returns U1 value at offset (nOffset). Fires an assert if the offset is behind the end of represented
    // data.
    inline BYTE Debug_GetByteAtOffset(UINT32 nOffset) const;
#endif //_DEBUG

public:
    //
    // Setters
    //

    // Writes compressed integer (1, 2 or 4 bytes of format code:CompressedInteger#Format) to the data blob
    // and skips the written data.
    // Returns FALSE if there's not enough data in the blob or the value cannot be encoded as compressed
    // integer (bigger than code:CompressedInteger::const_Max).
    // Returns TRUE on success and moves the memory block behind the written data.
    __checkReturn
    __success(return)
    inline BOOL StoreCompressedU(UINT32 nValue);

    // Writes data from *pSource to the data blob and skips the written data.
    // Returns FALSE if there's not enough data in the blob.
    // Returns TRUE on success and moves memory block behind the written data.
    __checkReturn
    __success(return)
    inline BOOL StoreData(__in const DataBlob *pSource);

private:
    //
    // Helpers
    //

    // Skips cbSize bytes in the represented memory block. The caller is responsible for making sure that
    // the represented memory block contains at least cbSize bytes, otherwise there will be a security
    // issue.
    // Should be used only internally, never call it from outside of this class.
    inline void SkipBytes_InternalInsecure(UINT32 cbSize);

};  // class DataBlob

};  // namespace MetaData

#include "datablob.inl"


text: Project Infinity Readme


text:
/**
 *
 * Click on an element based on given selector.
 *
 * @param {String} selector element to click on. If it matches with more than on DOM-element it automatically clicks on the first element
 *
 * @uses protocol/element, protocol/elementIdClick, protocol/touchClick
 * @type action
 *
 */

var async = require('async'),
    ErrorHandler = require('../utils/ErrorHandler.js');

module.exports = function click (selector) {

    /*!
     * make sure that callback contains chainit callback
     */
    var callback = arguments[arguments.length - 1];

    /*!
     * parameter check
     */
    if(typeof selector !== 'string') {
        return callback(new ErrorHandler.CommandError('number or type of arguments don\'t agree with click command'));
    }

    var self = this,
        response = {};

    if(!this.isMobile) {

        async.waterfall([
            function(cb) {
                self.element(selector, cb);
            },
            function(res, cb) {
                response.element = res;
                self.elementIdClick(res.value.ELEMENT, cb);
            },
            function(res, cb) {
                response.elementIdClick = res;
                cb();
            }
        ], function(err) {

            callback(err, null, response);

        });

    } else {

        async.waterfall([
            function(cb) {
                self.element(selector, cb);
            },
            function(res, cb) {
                response.element = res;
                self.touchClick(res.value.ELEMENT, cb);
            },
            function(res, cb) {
                response.touchClick = res;
                cb();
            }
        ], function(err) {

            callback(err, null, response);

        });

    }

};


text:
/* TEMPLATE GENERATED TESTCASE FILE
Filename: CWE401_Memory_Leak__new_struct_twoIntsStruct_21.cpp
Label Definition File: CWE401_Memory_Leak__new.label.xml
Template File: sources-sinks-21.tmpl.cpp
*/
/*
 * @description
 * CWE: 401 Memory Leak
 * BadSource:  Allocate data using new
 * GoodSource: Allocate data on the stack
 * Sinks:
 *    GoodSink: call delete on data
 *    BadSink : no deallocation of data
 * Flow Variant: 21 Control flow: Flow controlled by value of a static global variable. All functions contained in one file.
 *
 * */

#include "std_testcase.h"

#ifndef _WIN32
#include <wchar.h>
#endif

namespace CWE401_Memory_Leak__new_struct_twoIntsStruct_21
{

#ifndef OMITBAD

/* The static variable below is used to drive control flow in the sink function */
static int badStatic = 0;

static void badSink(struct _twoIntsStruct * data)
{
    if(badStatic)
    {
        /* POTENTIAL FLAW: No deallocation */
        ; /* empty statement needed for some flow variants */
    }
}

void bad()
{
    struct _twoIntsStruct * data;
    data = NULL;
    /* POTENTIAL FLAW: Allocate memory on the heap */
    data = new struct _twoIntsStruct;
    /* Initialize and make use of data */
    data->intOne = 0;
    data->intTwo = 0;
    printStructLine((twoIntsStruct *)data);
    badStatic = 1; /* true */
    badSink(data);
}

#endif /* OMITBAD */

#ifndef OMITGOOD

/* The static variables below are used to drive control flow in the sink functions. */
static int goodB2G1Static = 0;
static int goodB2G2Static = 0;
static int goodG2bStatic = 0;

/* goodB2G1() - use badsource and goodsink by setting the static variable to false instead of true */
static void goodB2G1Sink(struct _twoIntsStruct * data)
{
    if(goodB2G1Static)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        /* FIX: Deallocate memory */
        delete data;
    }
}

static void goodB2G1()
{
    struct _twoIntsStruct * data;
    data = NULL;
    /* POTENTIAL FLAW: Allocate memory on the heap */
    data = new struct _twoIntsStruct;
    /* Initialize and make use of data */
    data->intOne = 0;
    data->intTwo = 0;
    printStructLine((twoIntsStruct *)data);
    goodB2G1Static = 0; /* false */
    goodB2G1Sink(data);
}

/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */
static void goodB2G2Sink(struct _twoIntsStruct * data)
{
    if(goodB2G2Static)
    {
        /* FIX: Deallocate memory */
        delete data;
    }
}

static void goodB2G2()
{
    struct _twoIntsStruct * data;
    data = NULL;
    /* POTENTIAL FLAW: Allocate memory on the heap */
    data = new struct _twoIntsStruct;
    /* Initialize and make use of data */
    data->intOne = 0;
    data->intTwo = 0;
    printStructLine((twoIntsStruct *)data);
    goodB2G2Static = 1; /* true */
    goodB2G2Sink(data);
}

/* goodG2B() - use goodsource and badsink */
static void goodG2BSink(struct _twoIntsStruct * data)
{
    if(goodG2bStatic)
    {
        /* POTENTIAL FLAW: No deallocation */
        ; /* empty statement needed for some flow variants */
    }
}

static void goodG2B()
{
    struct _twoIntsStruct * data;
    data = NULL;
    /* FIX: Use memory allocated on the stack */
    struct _twoIntsStruct dataGoodBuffer;
    data = &dataGoodBuffer;
    /* Initialize and make use of data */
    data->intOne = 0;
    data->intTwo = 0;
    printStructLine((twoIntsStruct *)data);
    goodG2bStatic = 1; /* true */
    goodG2BSink(data);
}

void good()
{
    goodB2G1();
    goodB2G2();
    goodG2B();
}

#endif /* OMITGOOD */

} /* close namespace */

/* Below is the main(). It is only used when building this testcase on
   its own for testing or for building a binary to use in testing binary
   analysis tools. It is not used when compiling all the testcases as one
   application, which is how source code analysis tools are tested. */

#ifdef INCLUDEMAIN

using namespace CWE401_Memory_Leak__new_struct_twoIntsStruct_21; /* so that we can use good and bad easily */

int main(int argc, char * argv[])
{
    /* seed randomness */
    srand( (unsigned)time(NULL) );
#ifndef OMITGOOD
    printLine("Calling good()...");
    good();
    printLine("Finished good()");
#endif /* OMITGOOD */
#ifndef OMITBAD
    printLine("Calling bad()...");
    bad();
    printLine("Finished bad()");
#endif /* OMITBAD */
    return 0;
}

#endif


text:
package ufo.codility.lessons.lesson_3.timeComplexity;

import static org.junit.Assert.*;

import org.junit.Test;

import ufo.BaseTest;
import ufo.codility.lessons.lesson_3.timeComplexity.PermMissingElem;

public class PermMissingElemTest extends BaseTest {

	@Test
	public void test() {
		final PermMissingElem perm = new PermMissingElem();

		assertEquals( 4, perm.solution(new int[] {2,3,1,5}) );
		assertEquals( 1, perm.solution(new int[] {2,3,4,5}) );
		assertEquals( 5, perm.solution(new int[] {2,3,1,4}) );

	}

}


text:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="bc.css">

FireRating in the Cloud and RevitLookup Update

I am currently working intensely at the
Autodesk Cloud Accelerator in Prague.

It is exciting and we are making good progress.

I spent a lot of my time so far enhancing the
FireRating in the Cloud sample
and documenting these improvements.

Here are my topics for today:

FireRating in the Cloud enhancements

RevitLookup update to handle null analytical model

Retrieving all model elements

I glad to report that I found
Mlsná Kavka (Picky Jackdaw in English),
a nice and friendly non-smoking vegetarian restaurant, just around the corner from the Autodesk office:

FireRating in the Cloud Enhancements

My real goal is to switch back and continue work on the new
CompHound component tracker as
fast as possible, in preparation for the upcoming conference presentations at
RTC Europe in Budapest end of October and
Autodesk University in Las Vegas in December.

However, since the
FireRating in the Cloud sample
is more generic and fundamental, I want to clean it up to utter perfection first, before expanding into new areas.

FireRating in the Cloud covers the connection of Revit database and element data to a cloud-hosted external database.

The CompHound component tracker will add a user interface, reports, and a 3D model viewer and navigator to that.

Here is a list of the recent firerating enhancements:

Using RestSharp for Rest API GET

Mongodb Upsert

C# DoorData and Node.js DoorService Classes

DoorData Container Class

REST GET returns a list of deserialised DoorData instances

Passing a DoorData instance to the Put method

Implementing a REST API router DoorService class

RevitLookup Update to Handle Null Analytical Model

In between other things here a user reported a problem with RevitLookup, saying that, "I loaded and ran RevitLookup 2016 'Snoop Current Selection...' today and encountered a rather spectacular error crashing Revit without an error message when a Generic Floor was preselected."

The error can be solved by commenting out the line accessing the analytical model in the Stream method handling a floor element:

  data.Add( new Snoop.Data.String( "Structural usage",
    floor.GetAnalyticalModel().GetAnalyzeAs().ToString() ) );

In Revit Architecture or MEP, the GetAnalyticalModel will return null, causing the call to ToString to fail.

This was actually fixed – more elegantly, I'm glad to say – in
RevitLookup release 2016.0.0.10,
so please do make sure to download and install the latest version if you encounter this situation.

I actually already mentioned this two weeks ago...

Retrieving All Model Elements

Once again, let's revisit the topic of
selecting model elements, raised this time by Dale in the Revit API discussion thread on
traversing all model elements:

Question:
To be clear, "all model elements" could be defined as all objects that exist in the real world: chairs, doors, walls, etc. – component and system families. Graphic elements such as levels, sheets, views, dimensions, annotation, profiles, etc. would not be included. I have been through all The Building Coder samples (and others) many times, and whilst there are lots of examples to filter for a specific category or feature, I have been unable to come up with a solution that provides all model elements as defined above. Your
example from 2009
(2) may be the best,
but given that it is several years old, I have been looking for more contemporary code. Apologies if I am overlooking something obvious; I thought this would be a five-minute job but I have been unable to come up with a simple, solid solution.

Answer:
Does this fit the bill?

  IEnumerable<Element> GetAllModelElements(
    Document doc )
  {
    Options opt = new Options();

    return new FilteredElementCollector( doc )
      .WhereElementIsNotElementType()
      .WhereElementIsViewIndependent()
      .Where<Element>( e
        => null != e.Category
        && null != e.get_Geometry( opt ) );
  }

I added and published this in
The Building Coder samples release 2016.0.120.14.

Please try it out, and let's ensure that we really get something up and running that suits your needs.

Response:
If I ever get to AU again, I owe you a beer! Two maybe. Works perfectly. Thanks again, I hope this is helpful for others as I really struggled to resolve it. Dale


text:
<component name="ProjectDictionaryState">
  <dictionary name="Maurice" />
</component>


text:
cd  ~/workspace/

# PRODUCTION=0 webpack --watch --optimize-minimize --progress
PRODUCTION=0 webpack --watch --progress


text:
layout: post
title: 'Postscript III-V (Berlin), 2016'
category: hahn-huhn
published: true
---

![Tris Vonna-Michell - Postscript III-V (Berlin), 2016]({{site.baseurl}}/assets/img/0318-postscript-iii-v-berlin-2016-iii.jpg)
Installation at T293, Rome, 25 October - 3 December 2016 (photo by Roberto Apa)

![Tris Vonna-Michell - Postscript III-V (Berlin), 2016]({{site.baseurl}}/assets/img/0301-postscript-iii-v-berlin-2016.jpg)
Film still

![Tris Vonna-Michell - Postscript III-V (Berlin), 2016]({{site.baseurl}}/assets/img/0302-postscript-iii-v-berlin-2016.jpg)
Film still


text:
namespace ShapefileSharp
{
    public interface IShapefileRecord
    {
        int RecordNumber { get; }
        IShape Shape { get; }
    }

    public interface IShapefileRecord<T> : IShapefileRecord where T:IShape
    {
        new T Shape { get; }
    }
}


text:
{% extends "base.html" %}
{% load i18n %}

{% block main %}

{% trans "Sprints" %}

{% trans "Backlog overview" %}
{% trans "Sprint overview" %}
{% endblock %}


text:
from django.db.models.signals import pre_save
from django.dispatch import receiver
import django_cas_ng.signals

from webapp.models import TaskGroupAccess, Task, CASUserMeta
from webapp.utils.main import apply_markdown
from webapp.utils.template import short_name
from algoweb.settings import CAS_KEY_FIRST_NAME, CAS_KEY_LAST_NAME, CAS_KEY_EMAIL, \
    CAS_KEY_ADMIN_FLAG, CAS_KEY_ADMIN_FLAG_VALUES

# for static analysis this should exist
def load():
    pass

@receiver(django_cas_ng.signals.cas_user_authenticated)
def cas_user_authenticated(sender, user, created, attributes, ticket, service, **kwargs):
    # update the data in order to reflect what we had received from CAS
    # FIXME temporary hack for the case of too long first names/last names
    user.first_name = short_name(attributes[CAS_KEY_FIRST_NAME], max_subparts=2)[:30]
    user.last_name = short_name(attributes[CAS_KEY_LAST_NAME], max_subparts=2)[:30]
    user.email = attributes[CAS_KEY_EMAIL]

    try:
        cas_user_meta = CASUserMeta.objects.get(user=user)
    except CASUserMeta.DoesNotExist:
        cas_user_meta = CASUserMeta(user=user)

    cas_user_meta.attributes = attributes
    cas_user_meta.save()

    if attributes[CAS_KEY_ADMIN_FLAG] in CAS_KEY_ADMIN_FLAG_VALUES:
        user.is_staff = True

    user.save()

@receiver(pre_save, sender=TaskGroupAccess)
def pre_save_task_group_access(sender, instance, *args, **kwargs):
    if instance.user and instance.provider_id is None:
        try:
            instance.provider_id = instance.user.casusermeta.ext_id
        except CASUserMeta.DoesNotExist:
            pass

@receiver(pre_save, sender=Task)
def increment_version(instance, **kwargs):
    instance.version += 1

@receiver(pre_save, sender=Task)
def generate_markdown(instance, **kwargs):
    instance.description_cache = apply_markdown(instance.description)


text:
require 'codeclimate-test-reporter'
CodeClimate::TestReporter.configure do |config|
  config.logger.level = Logger::WARN
end
CodeClimate::TestReporter.start

# Set up
#-----------------------------------------------------------------------------#

require 'pathname'
ROOT = Pathname.new(File.expand_path('../../', __FILE__))
$LOAD_PATH.unshift((ROOT + 'lib').to_s)
$LOAD_PATH.unshift((ROOT + 'spec').to_s)

require 'bundler/setup'
require 'bacon'
require 'mocha-on-bacon'
require 'pretty_bacon'
require 'cocoapods-core'

# Helpers
#-----------------------------------------------------------------------------#

require 'spec_helper/fixture'
require 'spec_helper/temporary_directory'

def fixture_spec(name)
  file = SpecHelper::Fixture.fixture(name)
  Pod::Specification.from_file(file)
end

def copy_fixture_to_pod(name, pod)
  path = SpecHelper::Fixture.fixture(name)
  FileUtils.cp_r(path, pod.root)
end

# VCR
#--------------------------------------#

require 'vcr'
VCR.configure do |c|
  c.cassette_library_dir = ROOT + 'spec/fixtures/vcr_cassettes'
  c.hook_into :webmock
  c.ignore_hosts 'codeclimate.com'
end

# Silence the output
#--------------------------------------#

module Pod
  module CoreUI
    @output = ''
    @warnings = ''

    class << self
      attr_accessor :output
      attr_accessor :warnings
    end

    def self.puts(message)
      @output << message << "\n"
    end

    def self.print(message)
      @output << message
    end

    def self.warn(message)
      @warnings << message
    end
  end
end

# Configure Bacon
#--------------------------------------#

Bacon.summary_at_exit

module Bacon
  class Context
    include SpecHelper::Fixture

    old_run_requirement = instance_method(:run_requirement)
    define_method(:run_requirement) do |description, spec|
      ::Pod::CoreUI.output = ''
      ::Pod::CoreUI.warnings = ''
      old_run_requirement.bind(self).call(description, spec)
    end
  end
end

Mocha::Configuration.prevent(:stubbing_non_existent_method)