text:
import operator
import six

from ibis.expr.types import TableColumn  # noqa

from ibis.compat import py_string
from ibis.expr.datatypes import HasSchema, Schema
from ibis.expr.rules import value, string, number, integer, boolean, list_of
from ibis.expr.types import (Node, as_value_expr,
                             ValueExpr, ArrayExpr, TableExpr,
                             TableNode, ValueNode, _safe_repr)
import ibis.common as com
import ibis.expr.datatypes as dt
import ibis.expr.rules as rules
import ibis.expr.types as ir
import ibis.util as util

def _arg_getter(i):
    @property
    def arg_accessor(self):
        return self.args[i]
    return arg_accessor

class ValueOperationMeta(type):

    def __new__(cls, name, parents, dct):

        if 'input_type' in dct:
            sig = dct['input_type']
            if not isinstance(sig, rules.TypeSignature):
                dct['input_type'] = sig = rules.signature(sig)

                for i, t in enumerate(sig.types):
                    if t.name is None:
                        continue

                    if t.name not in dct:
                        dct[t.name] = _arg_getter(i)

        return super(ValueOperationMeta, cls).__new__(cls, name, parents, dct)

class ValueOp(six.with_metaclass(ValueOperationMeta, ValueNode)):

    pass

class PhysicalTable(ir.BlockingTableNode, HasSchema):

    pass

class UnboundTable(PhysicalTable):

    def __init__(self, schema, name=None):
        TableNode.__init__(self, [schema, name])
        HasSchema.__init__(self, schema, name=name)

class DatabaseTable(PhysicalTable):

    """

    """

    def __init__(self, name, schema, source):
        self.source = source

        TableNode.__init__(self, [name, schema, source])
        HasSchema.__init__(self, schema, name=name)

    def change_name(self, new_name):
        return type(self)(new_name, self.args[1], self.source)

class SQLQueryResult(ir.BlockingTableNode, HasSchema):

    """
    A table sourced from the result set of a select query
    """

    def __init__(self, query, schema, source):
        self.query = query
        TableNode.__init__(self, [query, schema, source])
        HasSchema.__init__(self, schema)

class TableArrayView(ValueNode):

    """
    (Temporary?) Helper operation class for SQL translation (fully formed table
    subqueries to be viewed as arrays)
    """

    def __init__(self, table):
        if not isinstance(table, TableExpr):
            raise com.ExpressionError('Requires table')

        schema = table.schema()
        if len(schema) > 1:
            raise com.ExpressionError('Table can only have a single column')

        self.table = table
        self.name = schema.names[0]

        Node.__init__(self, [table])

    def to_expr(self):
        ctype = self.table._get_type(self.name)
        klass = ctype.array_type()
        return klass(self, name=self.name)

class UnaryOp(ValueOp):

    input_type = [value]

class Cast(ValueOp):

    input_type = [value, rules.data_type]

    # see #396 for the issue preventing this
    # def resolve_name(self):
    #     return self.args[0].get_name()

    def output_type(self):
        # TODO: error handling for invalid casts
        return rules.shape_like(self.args[0], self.args[1])

class TypeOf(ValueOp):

    input_type = [value]
    output_type = rules.shape_like_arg(0, 'string')

class Negate(UnaryOp):

    input_type = [number]
    output_type = rules.type_of_arg(0)

class IsNull(UnaryOp):

    """
    Returns true if values are null

    Returns
    -------
    isnull : boolean with dimension of caller
    """

    output_type = rules.shape_like_arg(0, 'boolean')

class NotNull(UnaryOp):

    """
    Returns true if values are not null

    Returns
    -------
    notnull : boolean with dimension of caller
    """

    output_type = rules.shape_like_arg(0, 'boolean')

class ZeroIfNull(UnaryOp):

    output_type = rules.type_of_arg(0)

class IfNull(ValueOp):

    """
    Equivalent to (but perhaps implemented differently):

    case().when(expr.notnull(), expr)
          .else_(null_substitute_expr)
    """

    input_type = [value, value(name='ifnull_expr')]
    output_type = rules.type_of_arg(0)

class NullIf(ValueOp):

    """
    Set values to NULL if they equal the null_if_expr
    """

    input_type = [value, value(name='null_if_expr')]
    output_type = rules.type_of_arg(0)

class NullIfZero(ValueOp):

    """
    Set values to NULL if they equal to zero. Commonly used in cases where
    divide-by-zero would produce an overflow or infinity.

    Equivalent to (value == 0).ifelse(ibis.NA, value)

    Returns
    -------
    maybe_nulled : type of caller
    """

    input_type = [number]
    output_type = rules.type_of_arg(0)

def _coalesce_upcast(self):
    # TODO: how much validation is necessary that the call is valid and can
    # succeed?
    first_value = self.args[0]

    if isinstance(first_value, ir.IntegerValue):
        out_type = 'int64'
    elif isinstance(first_value, ir.FloatingValue):
        out_type = 'double'
    else:
        out_type = first_value.type()

    return rules.shape_like_args(self.args, out_type)

class CoalesceLike(ValueOp):

    # According to Impala documentation:
    # Return type: same as the initial argument value, except that integer
    # values are promoted to BIGINT and floating-point values are promoted to
    # DOUBLE; use CAST() when inserting into a smaller numeric column

    input_type = rules.varargs(rules.value)
    output_type = _coalesce_upcast

class Coalesce(CoalesceLike):
    pass

class Greatest(CoalesceLike):
    pass

class Least(CoalesceLike):
    pass

class Abs(UnaryOp):

    """
    Absolute value
    """

    output_type = rules.type_of_arg(0)

def _ceil_floor_output(self):
    arg = self.args[0]
    if isinstance(arg, ir.DecimalValue):
        return arg._factory
    else:
        return rules.shape_like(arg, 'int64')

class Ceil(UnaryOp):

    """
    Round up to the nearest integer value greater than or equal to this value

    Returns
    -------
    ceiled : type depending on input
      Decimal values: yield decimal
      Other numeric values: yield integer (int32)
    """
    input_type = [number]
    output_type = _ceil_floor_output

class Floor(UnaryOp):

    """
    Round down to the nearest integer value less than or equal to this value

    Returns
    -------
    floored : type depending on input
      Decimal values: yield decimal
      Other numeric values: yield integer (int32)
    """

    input_type = [number]
    output_type = _ceil_floor_output

class Round(ValueOp):

    input_type = [value, integer(name='digits', optional=True)]

    def output_type(self):
        arg, digits = self.args
        if isinstance(arg, ir.DecimalValue):
            return arg._factory
        elif digits is None:
            return rules.shape_like(arg, 'int64')
        else:
            return rules.shape_like(arg, 'double')

class BaseConvert(ValueOp):

    input_type = [rules.one_of([integer, string]),
                  integer(name='from_base'),
                  integer(name='to_base')]
    output_type = rules.shape_like_flatargs('string')

class RealUnaryOp(UnaryOp):

    input_type = [number]
    output_type = rules.shape_like_arg(0, 'double')

class Exp(RealUnaryOp):
    pass

class Sign(UnaryOp):

    # This is the Impala output for both integers and double/float
    output_type = rules.shape_like_arg(0, 'float')

class Sqrt(RealUnaryOp):
    pass

class Logarithm(RealUnaryOp):

    # superclass

    input_type = [number(allow_boolean=False)]

class Log(Logarithm):

    input_type = [number(allow_boolean=False),
                  number(name='base', optional=True)]

class Ln(Logarithm):

    """
    Natural logarithm
    """

class Log2(Logarithm):

    """
    Logarithm base 2
    """

class Log10(Logarithm):

    """
    Logarithm base 10
    """

class StringUnaryOp(UnaryOp):

    input_type = [string]
    output_type = rules.shape_like_arg(0, 'string')

class Uppercase(StringUnaryOp):

    """
    Convert string to all uppercase
    """
    pass

class Lowercase(StringUnaryOp):

    """
    Convert string to all lowercase
    """
    pass

class Reverse(StringUnaryOp):
    pass

class Strip(StringUnaryOp):

    """
    Remove whitespace from left and right sides of string
    """
    pass

class LStrip(StringUnaryOp):

    """
    Remove whitespace from left side of string
    """
    pass

class RStrip(StringUnaryOp):
    """
    Remove whitespace from right side of string
    """
    pass

class Capitalize(StringUnaryOp):
    pass

class Substring(ValueOp):

    input_type = [string, integer(name='start'),
                  integer(name='length', optional=True)]
    output_type = rules.shape_like_arg(0, 'string')

class StrRight(ValueOp):

    input_type = [string, integer(name='nchars')]
    output_type = rules.shape_like_arg(0, 'string')

class Repeat(ValueOp):

    input_type = [string, integer(name='times')]
    output_type = rules.shape_like_arg(0, 'string')

class StringFind(ValueOp):

    input_type = [string, string(name='substr'),
                  integer(name='start', optional=True, default=None),
                  integer(name='end', optional=True, default=None)]
    output_type = rules.shape_like_arg(0, 'int64')

class Translate(ValueOp):

    input_type = [string, string(name='from_str'), string(name='to_str')]
    output_type = rules.shape_like_arg(0, 'string')

class LPad(ValueOp):

    input_type = [string, integer(name='length'),
                  string(name='pad', optional=True)]
    output_type = rules.shape_like_arg(0, 'string')

class RPad(ValueOp):

    input_type = [string, integer(name='length'),
                  string(name='pad', optional=True)]
    output_type = rules.shape_like_arg(0, 'string')

class FindInSet(ValueOp):

    input_type = [string(name='needle'), list_of(string, min_length=1)]
    output_type = rules.shape_like_arg(0, 'int64')

class StringJoin(ValueOp):

    input_type = [string(name='sep'), list_of(string, min_length=1)]
    output_type = rules.shape_like_flatargs('string')

class BooleanValueOp(ValueOp):
    pass

class FuzzySearch(BooleanValueOp):

    input_type = [string, string(name='pattern')]
    output_type = rules.shape_like_arg(0, 'boolean')

class StringSQLLike(FuzzySearch):
    pass

class RegexSearch(FuzzySearch):
    pass

class RegexExtract(ValueOp):

    input_type = [string, string(name='pattern'), integer(name='index')]
    output_type = rules.shape_like_arg(0, 'string')

class RegexReplace(ValueOp):

    input_type = [string, string(name='pattern'), string(name='replacement')]
    output_type = rules.shape_like_arg(0, 'string')

class StringReplace(ValueOp):

    input_type = [string, string(name='pattern'), string(name='replacement')]
    output_type = rules.shape_like_arg(0, 'string')

class ParseURL(ValueOp):

    input_type = [string, rules.string_options(['PROTOCOL', 'HOST', 'PATH',
                                                'REF', 'AUTHORITY', 'FILE',
                                                'USERINFO', 'QUERY'],
                                               name='extract'),
                  string(name='key', optional=True)]
    output_type = rules.shape_like_arg(0, 'string')

class StringLength(UnaryOp):

    """
    Compute length of strings

    Returns
    -------
    length : int32
    """

    output_type = rules.shape_like_arg(0, 'int32')

class StringAscii(UnaryOp):

    output_type = rules.shape_like_arg(0, 'int32')

class BinaryOp(ValueOp):

    """
    A binary operation

    """
    # Casting rules for type promotions (for resolving the output type) may
    # depend in some cases on the target backend.
    #
    # TODO: how will overflows be handled? Can we provide anything useful in
    # Ibis to help the user avoid them?

    input_type = [rules.value(name='left'), rules.value(name='right')]

    def __init__(self, left, right):
        left, right = self._maybe_cast_args(left, right)
        ValueOp.__init__(self, left, right)

    def _maybe_cast_args(self, left, right):
        return left, right

    def output_type(self):
        raise NotImplementedError

# ----------------------------------------------------------------------

class Reduction(ValueOp):

    input_type = [rules.array, boolean(name='where', optional=True)]
    _reduction = True

def is_reduction(expr):
    # Aggregations yield typed scalar expressions, since the result of an
    # aggregation is a single value. When creating an table expression
    # containing a GROUP BY equivalent, we need to be able to easily check
    # that we are looking at the result of an aggregation.
    #
    # As an example, the expression we are looking at might be something
    # like: foo.sum().log10() + bar.sum().log10()
    #
    # We examine the operator DAG in the expression to determine if there
    # are aggregations present.
    #
    # A bound aggregation referencing a separate table is a "false
    # aggregation" in a GROUP BY-type expression and should be treated a
    # literal, and must be computed as a separate query and stored in a
    # temporary variable (or joined, for bound aggregations with keys)
    def has_reduction(op):
        if getattr(op, '_reduction', False):
            return True

        for arg in op.args:
            if isinstance(arg, ir.ScalarExpr) and has_reduction(arg.op()):
                return True

        return False

    return has_reduction(expr.op() if isinstance(expr, ir.Expr) else expr)

class Count(Reduction):
    # TODO: count(col) takes down Impala, must always do count(*) in generated
    # SQL

    input_type = [rules.collection, boolean(name='where', optional=True)]

    # TODO: counts are actually table-level operations. Let's address
    # during the SQL generation exercise

    def output_type(self):
        return ir.Int64Scalar

def _sum_output_type(self):
    arg = self.args[0]
    if isinstance(arg, (ir.IntegerValue, ir.BooleanValue)):
        t = 'int64'
    elif isinstance(arg, ir.FloatingValue):
        t = 'double'
    elif isinstance(arg, ir.DecimalValue):
        t = dt.Decimal(arg._precision, 38)
    else:
        raise TypeError(arg)
    return t

def _mean_output_type(self):
    arg = self.args[0]
    if isinstance(arg, ir.DecimalValue):
        t = dt.Decimal(arg._precision, 38)
    elif isinstance(arg, ir.NumericValue):
        t = 'double'
    else:
        raise NotImplementedError
    return t

class Sum(Reduction):

    output_type = rules.scalar_output(_sum_output_type)

class Mean(Reduction):

    output_type = rules.scalar_output(_mean_output_type)

class VarianceBase(Reduction):

    input_type = [rules.array, boolean(name='where', optional=True),
                  rules.string_options(['sample', 'pop'],
                                       name='how', optional=True)]
    output_type = rules.scalar_output(_mean_output_type)

class StandardDev(VarianceBase):
    pass

class Variance(VarianceBase):
    pass

def _decimal_scalar_ctor(precision, scale):
    out_type = dt.Decimal(precision, scale)
    return ir.DecimalScalar._make_constructor(out_type)

class StdDeviation(Reduction):
    pass

def _min_max_output_rule(self):
    arg = self.args[0]
    if isinstance(arg, ir.DecimalValue):
        t = dt.Decimal(arg._precision, 38)
    else:
        t = arg.type()

    return t

class Max(Reduction):

    output_type = rules.scalar_output(_min_max_output_rule)

class Min(Reduction):

    output_type = rules.scalar_output(_min_max_output_rule)

class HLLCardinality(Reduction):

    """
    Approximate number of unique values using HyperLogLog algorithm. Impala
    offers the NDV built-in function for this.
    """

    def output_type(self):
        # Impala 2.0 and higher returns a DOUBLE
        return ir.DoubleScalar

class GroupConcat(Reduction):

    input_type = [rules.array, string(name='sep', default=',')]
    # boolean(name='where', optional=True)]

    def output_type(self):
        return ir.StringScalar

class CMSMedian(Reduction):

    """
    Compute the approximate median of a set of comparable values using the
    Count-Min-Sketch algorithm. Exposed in Impala using APPX_MEDIAN.
    """

    def output_type(self):
        # Scalar but type of caller
        return self.args[0].type().scalar_type()

# ----------------------------------------------------------------------
# Analytic functions

class AnalyticOp(ValueOp):
    pass

class WindowOp(ValueOp):

    output_type = rules.type_of_arg(0)

    def __init__(self, expr, window):
        from ibis.expr.window import propagate_down_window
        if not is_analytic(expr):
            raise com.IbisInputError('Expression does not contain a valid '
                                     'window operation')

        table = ir.find_base_table(expr)
        if table is not None:
            window = window.bind(table)

        expr = propagate_down_window(expr, window)

        ValueOp.__init__(self, expr, window)

    def over(self, window):
        existing_window = self.args[1]
        new_window = existing_window.combine(window)
        return WindowOp(self.args[0], new_window)

def is_analytic(expr, exclude_windows=False):
    def _is_analytic(op):
        if isinstance(op, (Reduction, AnalyticOp)):
            return True
        elif isinstance(op, WindowOp) and exclude_windows:
            return False

        for arg in op.args:
            if isinstance(arg, ir.Expr) and _is_analytic(arg.op()):
                return True

        return False

    return _is_analytic(expr.op())

class ShiftBase(AnalyticOp):

    input_type = [rules.array, rules.integer(name='offset', optional=True),
                  rules.value(name='default', optional=True)]
    output_type = rules.type_of_arg(0)

class Lag(ShiftBase):
    pass

class Lead(ShiftBase):
    pass

class RankBase(AnalyticOp):

    def output_type(self):
        return ir.Int64Array

class MinRank(RankBase):

    """
    Compute position of first element within each equal-value group in sorted
    order.

    Examples
    --------
    values   ranks
    1        0
    1        0
    2        2
    2        2
    2        2
    3        5

    Returns
    -------
    ranks : Int64Array, starting from 0
    """

    # Equivalent to SQL RANK()
    input_type = [rules.array]

class DenseRank(RankBase):

    """
    Compute position of first element within each equal-value group in sorted
    order, ignoring duplicate values.

    Examples
    --------
    values   ranks
    1        0
    1        0
    2        1
    2        1
    2        1
    3        2

    Returns
    -------
    ranks : Int64Array, starting from 0
    """

    # Equivalent to SQL DENSE_RANK()
    input_type = [rules.array]

class RowNumber(RankBase):

    """
    Compute row number starting from 0 after sorting by column expression

    Examples
    --------
    w = window(order_by=values)
    row_number().over(w)

    values   number
    1        0
    1        1
    2        2
    2        3
    2        4
    3        5

    Returns
    -------
    row_number : Int64Array, starting from 0
    """

    # Equivalent to SQL ROW_NUMBER()
    pass

class CumulativeOp(AnalyticOp):

    input_type = [rules.array]

class CumulativeSum(CumulativeOp):

    """
    Cumulative sum. Requires an order window.
    """

    output_type = rules.array_output(_sum_output_type)

class CumulativeMean(CumulativeOp):

    """
    Cumulative mean. Requires an order window.
    """

    output_type = rules.array_output(_mean_output_type)

class CumulativeMax(CumulativeOp):

    """
    Cumulative max. Requires an order window.
    """

    output_type = rules.array_output(_min_max_output_rule)

class CumulativeMin(CumulativeOp):

    """
    Cumulative min. Requires an order window.
    """

    output_type = rules.array_output(_min_max_output_rule)

class PercentRank(AnalyticOp):
    pass

class NTile(AnalyticOp):
    pass

class FirstValue(AnalyticOp):

    input_type = [rules.array]
    output_type = rules.type_of_arg(0)

class LastValue(AnalyticOp):

    input_type = [rules.array]
    output_type = rules.type_of_arg(0)

class NthValue(AnalyticOp):

    input_type = [rules.array, rules.integer]
    output_type = rules.type_of_arg(0)

class SmallestValue(AnalyticOp):
    pass

class NthLargestValue(AnalyticOp):
    pass

class LargestValue(AnalyticOp):
    pass

# ----------------------------------------------------------------------
# Distinct stuff

class Distinct(ir.BlockingTableNode, HasSchema):

    """
    Distinct is a table-level unique-ing operation.

    In SQL, you might have:

    SELECT DISTINCT foo
    FROM table

    SELECT DISTINCT foo, bar
    FROM table
    """

    def __init__(self, table):
        self.table = table

        ir.BlockingTableNode.__init__(self, [table])
        schema = self.table.schema()
        HasSchema.__init__(self, schema)

class DistinctArray(ValueNode):

    """
    COUNT(DISTINCT ...) is really just syntactic suger, but we provide a
    distinct().count() nicety for users nonetheless.

    For all intents and purposes, like Distinct, but can be distinguished later
    for evaluation if the result should be array-like versus table-like. Also
    for calling count()
    """

    def __init__(self, arg):
        self.arg = arg
        ValueNode.__init__(self, arg)

    def output_type(self):
        return type(self.arg)

    def count(self):
        """
        Only valid if the distinct contains a single column
        """
        return CountDistinct(self.arg)

class CountDistinct(Reduction):

    input_type = [rules.array]

    def output_type(self):
        return ir.Int64Scalar

# ---------------------------------------------------------------------
# Boolean reductions and semi/anti join support

class Any(ValueOp):

    # Depending on the kind of input boolean array, the result might either be
    # array-like (an existence-type predicate) or scalar (a reduction)

    input_type = [rules.array(boolean)]

    @property
    def _reduction(self):
        roots = self.args[0]._root_tables()
        return len(roots) < 2

    def output_type(self):
        return ir.BooleanScalar if self._reduction else ir.BooleanArray

    def negate(self):
        return NotAny(self.args[0])

class All(ValueOp):

    input_type = [rules.array(boolean)]
    _reduction = True

    def output_type(self):
        return ir.BooleanScalar

    def negate(self):
        return NotAll(self.args[0])

class NotAny(Any):

    def negate(self):
        return Any(self.args[0])

class NotAll(All):

    def negate(self):
        return All(self.args[0])

class CumulativeAny(CumulativeOp):

    """
    Cumulative any
    """

    output_type = rules.array_output(lambda self: 'boolean')

class CumulativeAll(CumulativeOp):

    """
    Cumulative all
    """

    output_type = rules.array_output(lambda self: 'boolean')

# ---------------------------------------------------------------------

class SimpleCaseBuilder(object):

    def __init__(self, expr, cases=None, results=None, default=None):
        self.base = expr
        self.cases = cases or []
        self.results = results or []
        self.default = default

    def when(self, case_expr, result_expr):
        """
        Add a new case-result pair.

        Parameters
        ----------
        case : Expr
          Expression to equality-compare with base expression. Must be
          comparable with the base.
        result : Expr
          Value when the case predicate evaluates to true.

        Returns
        -------
        builder : CaseBuilder
        """
        case_expr = as_value_expr(case_expr)
        result_expr = as_value_expr(result_expr)

        if not self.base._can_compare(case_expr):
            raise TypeError('Base expression and passed case are not '
                            'comparable')

        cases = list(self.cases)
        cases.append(case_expr)

        results = list(self.results)
        results.append(result_expr)

        # Maintain immutability
        return SimpleCaseBuilder(self.base, cases=cases, results=results,
                                 default=self.default)

    def else_(self, result_expr):
        """
        Specify

        Returns
        -------
        builder : CaseBuilder
        """
        result_expr = as_value_expr(result_expr)

        # Maintain immutability
        return SimpleCaseBuilder(self.base, cases=list(self.cases),
                                 results=list(self.results),
                                 default=result_expr)

    def end(self):
        if self.default is None:
            default = ir.null()
        else:
            default = self.default

        op = SimpleCase(self.base, self.cases, self.results, default)
        return op.to_expr()

class SearchedCaseBuilder(object):

    def __init__(self, cases=None, results=None, default=None):
        self.cases = cases or []
        self.results = results or []
        self.default = default

    def when(self, case_expr, result_expr):
        """
        Add a new case-result pair.

        Parameters
        ----------
        case : Expr
          Expression to equality-compare with base expression. Must be
          comparable with the base.
        result : Expr
          Value when the case predicate evaluates to true.

        Returns
        -------
        builder : CaseBuilder
        """
        case_expr = as_value_expr(case_expr)
        result_expr = as_value_expr(result_expr)

        if not isinstance(case_expr, ir.BooleanValue):
            raise TypeError(case_expr)

        cases = list(self.cases)
        cases.append(case_expr)

        results = list(self.results)
        results.append(result_expr)

        # Maintain immutability
        return SearchedCaseBuilder(cases=cases, results=results,
                                   default=self.default)

    def else_(self, result_expr):
        """
        Specify

        Returns
        -------
        builder : CaseBuilder
        """
        result_expr = as_value_expr(result_expr)

        # Maintain immutability
        return SearchedCaseBuilder(cases=list(self.cases),
                                   results=list(self.results),
                                   default=result_expr)

    def end(self):
        if self.default is None:
            default = ir.null()
        else:
            default = self.default

        op = SearchedCase(self.cases, self.results, default)
        return op.to_expr()

class SimpleCase(ValueOp):

    input_type = [value(name='base'),
                  list_of(value, name='cases'),
                  list_of(value, name='results'),
                  value(name='default')]

    def __init__(self, base, cases, results, default):
        assert len(cases) == len(results)
        ValueOp.__init__(self, base, cases, results, default)

    def root_tables(self):
        base, cases, results, default = self.args
        all_exprs = [base] + cases + results
        if default is not None:
            all_exprs.append(default)
        return ir.distinct_roots(*all_exprs)

    def output_type(self):
        base, cases, results, default = self.args
        out_exprs = results + [default]
        typename = rules.highest_precedence_type(out_exprs)
        return rules.shape_like(base, typename)

class SearchedCase(ValueOp):

    input_type = [list_of(boolean, name='cases'),
                  list_of(value, name='results'),
                  value(name='default')]

    def __init__(self, cases, results, default):
        assert len(cases) == len(results)
        ValueOp.__init__(self, cases, results, default)

    def root_tables(self):
        cases, results, default = self.args
        all_exprs = cases + results
        if default is not None:
            all_exprs.append(default)
        return ir.distinct_roots(*all_exprs)

    def output_type(self):
        cases, results, default = self.args
        out_exprs = results + [default]
        typename = rules.highest_precedence_type(out_exprs)
        return rules.shape_like_args(cases, typename)

class Where(ValueOp):

    """
    Ternary case expression, equivalent to

    bool_expr.case()
             .when(True, true_expr)
             .else_(false_or_null_expr)
    """

    input_type = [boolean(name='bool_expr'),
                  value(name='true_expr'), value(name='false_null_expr')]

    def output_type(self):
        return rules.shape_like(self.args[0], self.args[1].type())

class Join(TableNode):

    def __init__(self, left, right, predicates):
        if not rules.is_table(left):
            raise TypeError('Can only join table expressions, got %s for '
                            'left table' % type(left))

        if not rules.is_table(right):
            raise TypeError('Can only join table expressions, got %s for '
                            'right table' % type(left))

        (self.left,
         self.right,
         self.predicates) = self._make_distinct(left, right, predicates)

        # Validate join predicates. Each predicate must be valid jointly when
        # considering the roots of each input table
        from ibis.expr.analysis import CommonSubexpr
        validator = CommonSubexpr([self.left, self.right])
        validator.validate_all(self.predicates)

        Node.__init__(self, [self.left, self.right, self.predicates])

    def _make_distinct(self, left, right, predicates):
        # see GH #667

        # If left and right table have a common parent expression (e.g. they
        # have different filters), must add a self-reference and make the
        # appropriate substitution in the join predicates

        if left.equals(right):
            right = right.view()

        predicates = self._clean_predicates(left, right, predicates)
        return left, right, predicates

    def _clean_predicates(self, left, right, predicates):
        import ibis.expr.analysis as L

        result = []

        if not isinstance(predicates, (list, tuple)):
            predicates = [predicates]

        for pred in predicates:
            if isinstance(pred, tuple):
                if len(pred) != 2:
                    raise com.ExpressionError('Join key tuple must be '
                                              'length 2')
                lk, rk = pred
                lk = left._ensure_expr(lk)
                rk = right._ensure_expr(rk)
                pred = lk == rk
            else:
                # pred = L.substitute_parents(pred, past_projection=False)
                pass

            if not isinstance(pred, ir.BooleanArray):
                raise com.ExpressionError('Join predicate must be comparison')

            preds = L.unwrap_ands(pred)
            result.extend(preds)

        return result

    def _get_schema(self):
        # For joins retaining both table schemas, merge them together here
        left = self.left
        right = self.right

        if not left._is_materialized():
            left = left.materialize()

        if not right._is_materialized():
            right = right.materialize()

        sleft = left.schema()
        sright = right.schema()

        overlap = set(sleft.names) & set(sright.names)
        if overlap:
            raise com.RelationError('Joined tables have overlapping names: %s'
                                    % str(list(overlap)))

        return sleft.append(sright)

    def has_schema(self):
        return False

    def root_tables(self):
        if util.all_of([self.left.op(), self.right.op()],
                       (Join, Projection)):
            # Unraveling is not possible
            return [self.left.op(), self.right.op()]
        else:
            return ir.distinct_roots(self.left, self.right)

class InnerJoin(Join):
    pass

class LeftJoin(Join):
    pass

class RightJoin(Join):
    pass

class OuterJoin(Join):
    pass

class LeftSemiJoin(Join):

    """

    """

    def _get_schema(self):
        return self.left.schema()

class LeftAntiJoin(Join):

    """

    """

    def _get_schema(self):
        return self.left.schema()

class MaterializedJoin(ir.BlockingTableNode, HasSchema):

    def __init__(self, join_expr):
        assert isinstance(join_expr.op(), Join)
        self.join = join_expr

        TableNode.__init__(self, [join_expr])
        schema = self.join.op()._get_schema()
        HasSchema.__init__(self, schema)

    def root_tables(self):
        return self.join._root_tables()

class CrossJoin(InnerJoin):

    """
    Some databases have a CROSS JOIN operator, that may be preferential to use
    over an INNER JOIN with no predicates.
    """

    def __init__(self, *args, **kwargs):
        if 'prefixes' in kwargs:
            raise NotImplementedError

        if len(args) < 2:
            raise com.IbisInputError('Must pass at least 2 tables')

        left = args[0]
        right = args[1]
        for t in args[2:]:
            right = right.cross_join(t)
        InnerJoin.__init__(self, left, right, [])

class Union(ir.BlockingTableNode, HasSchema):

    def __init__(self, left, right, distinct=False):
        self.left = left
        self.right = right
        self.distinct = distinct

        TableNode.__init__(self, [left, right, distinct])
        self._validate()
        HasSchema.__init__(self, self.left.schema())

    def _validate(self):
        if not self.left.schema().equals(self.right.schema()):
            raise com.RelationError('Table schemas must be equal '
                                    'to form union')

class Filter(TableNode):

    _arg_names = ['table', 'predicates']

    def __init__(self, table_expr, predicates):
        self.table = table_expr
        self.predicates = predicates

        TableNode.__init__(self, [table_expr, predicates])
        self._validate()

    def _validate(self):
        from ibis.expr.analysis import FilterValidator
        validator = FilterValidator([self.table])
        validator.validate_all(self.predicates)

    def get_schema(self):
        return self.table.schema()

    def has_schema(self):
        return self.table.op().has_schema()

    def root_tables(self):
        return self.table._root_tables()

class Limit(ir.BlockingTableNode):

    _arg_names = [None, 'n', 'offset']

    def __init__(self, table, n, offset=0):
        self.table = table
        self.n = n
        self.offset = offset
        TableNode.__init__(self, [table, n, offset])

    def get_schema(self):
        return self.table.schema()

    def has_schema(self):
        return self.table.op().has_schema()

    def root_tables(self):
        return [self]

# --------------------------------------------------------------------
# Sorting

class SortBy(TableNode):

    # Q: Will SortBy always require a materialized schema?

    def __init__(self, table_expr, sort_keys):
        self.table = table_expr
        self.keys = [to_sort_key(self.table, k)
                     for k in util.promote_list(sort_keys)]

        TableNode.__init__(self, [self.table, self.keys])

    def get_schema(self):
        return self.table.schema()

    def has_schema(self):
        return self.table.op().has_schema()

    def root_tables(self):
        tables = self.table._root_tables()
        return tables

def to_sort_key(table, key):
    if isinstance(key, DeferredSortKey):
        key = key.resolve(table)

    if isinstance(key, ir.SortExpr):
        return key

    if isinstance(key, (tuple, list)):
        key, sort_order = key
    else:
        sort_order = True

    if not isinstance(key, ir.Expr):
        key = table._ensure_expr(key)
        if isinstance(key, (ir.SortExpr, DeferredSortKey)):
            return to_sort_key(table, key)

    if isinstance(sort_order, py_string):
        if sort_order.lower() in ('desc', 'descending'):
            sort_order = False
        elif not isinstance(sort_order, bool):
            sort_order = bool(sort_order)

    return SortKey(key, ascending=sort_order).to_expr()

class SortKey(ir.Node):

    _arg_names = ['by', 'ascending']

    def __init__(self, expr, ascending=True):
        if not rules.is_array(expr):
            raise com.ExpressionError('Must be an array/column expression')

        self.expr = expr
        self.ascending = ascending

        ir.Node.__init__(self, [self.expr, self.ascending])

    def __repr__(self):
        # Temporary
        rows = ['Sort key:',
                '  ascending: {0!s}'.format(self.ascending),
                util.indent(_safe_repr(self.expr), 2)]
        return '\n'.join(rows)

    def to_expr(self):
        return ir.SortExpr(self)

    def equals(self, other):
        return (isinstance(other, SortKey) and
                self.expr.equals(other.expr) and
                self.ascending == other.ascending)

class DeferredSortKey(object):

    def __init__(self, what, ascending=True):
        self.what = what
        self.ascending = ascending

    def resolve(self, parent):
        what = parent._ensure_expr(self.what)
        return SortKey(what, ascending=self.ascending).to_expr()

class SelfReference(ir.BlockingTableNode, HasSchema):

    def __init__(self, table_expr):
        self.table = table_expr
        TableNode.__init__(self, [table_expr])
        HasSchema.__init__(self, table_expr.schema())

    def root_tables(self):
        # The dependencies of this operation are not walked, which makes the
        # table expression holding this relationally distinct from other
        # expressions, so things like self-joins are possible
        return [self]

class Projection(ir.BlockingTableNode, HasSchema):

    _arg_names = ['table', 'selections']

    def __init__(self, table_expr, proj_exprs):
        from ibis.expr.analysis import ExprValidator as Validator

        # Need to validate that the column expressions are compatible with the
        # input table; this means they must either be scalar expressions or
        # array expressions originating from the same root table expression
        validator = Validator([table_expr])

        # Resolve schema and initialize
        types = []
        names = []
        clean_exprs = []
        for expr in proj_exprs:
            if isinstance(expr, py_string):
                expr = table_expr[expr]

            validator.assert_valid(expr)
            if isinstance(expr, ValueExpr):
                name = expr.get_name()
                names.append(name)
                types.append(expr.type())
            elif rules.is_table(expr):
                schema = expr.schema()
                names.extend(schema.names)
                types.extend(schema.types)
            else:
                raise NotImplementedError

            clean_exprs.append(expr)

        # validate uniqueness
        schema = Schema(names, types)

        HasSchema.__init__(self, schema)
        Node.__init__(self, [table_expr] + [clean_exprs])

        self.table = table_expr
        self.selections = clean_exprs

    def substitute_table(self, table_expr):
        return Projection(table_expr, self.selections)

    def root_tables(self):
        return [self]

    def is_ancestor(self, other):
        if isinstance(other, ir.Expr):
            other = other.op()

        if self.equals(other):
            return True

        table = self.table
        exist_layers = False
        while not isinstance(table.op(), (ir.BlockingTableNode, Join)):
            table = table.op().table
            exist_layers = True

        if exist_layers:
            reboxed = Projection(table, self.selections)
            return reboxed.is_ancestor(other)
        else:
            return False

class Aggregation(ir.BlockingTableNode, HasSchema):

    """
    agg_exprs : per-group scalar aggregates
    by : group expressions
    having : post-aggregation predicate

    TODO: not putting this in the aggregate operation yet
    where : pre-aggregation predicate
    """

    _arg_names = ['table', 'metrics', 'by', 'having']

    def __init__(self, table, agg_exprs, by=None, having=None):
        # For tables, like joins, that are not materialized
        self.table = table

        self.agg_exprs = self._rewrite_exprs(agg_exprs)

        by = by or []
        self.by = self.table._resolve(by)
        self.by = self._rewrite_exprs(self.by)

        self.having = having or []
        self.having = self._rewrite_exprs(self.having)
        self._validate()

        TableNode.__init__(self, [table, self.agg_exprs, self.by, self.having])

        schema = self._result_schema()
        HasSchema.__init__(self, schema)

    def _rewrite_exprs(self, what):
        from ibis.expr.analysis import substitute_parents
        what = util.promote_list(what)

        all_exprs = []
        for expr in what:
            if isinstance(expr, ir.ExprList):
                all_exprs.extend(expr.exprs())
            else:
                bound_expr = ir.bind_expr(self.table, expr)
                all_exprs.append(bound_expr)

        return [substitute_parents(x, past_projection=False)
                for x in all_exprs]

    def substitute_table(self, table_expr):
        return Aggregation(table_expr, self.agg_exprs, by=self.by,
                           having=self.having)

    def _validate(self):
        # All aggregates are valid
        for expr in self.agg_exprs:
            if not rules.is_scalar(expr) or not is_reduction(expr):
                raise TypeError('Passed a non-aggregate expression: %s' %
                                _safe_repr(expr))

        for expr in self.having:
            if not isinstance(expr, ir.BooleanScalar):
                raise com.ExpressionError('Having clause must be boolean '
                                          'expression, was: {0!s}'
                                          .format(_safe_repr(expr)))

        # All non-scalar refs originate from the input table
        all_exprs = self.agg_exprs + self.by + self.having
        self.table._assert_valid(all_exprs)

    def _result_schema(self):
        names = []
        types = []

        # All exprs must be named

        for e in self.by + self.agg_exprs:
            names.append(e.get_name())
            types.append(e.type())

        return Schema(names, types)

class Add(BinaryOp):

    def output_type(self):
        helper = rules.BinaryPromoter(self.left, self.right, operator.add)
        return helper.get_result()

class Multiply(BinaryOp):

    def output_type(self):
        helper = rules.BinaryPromoter(self.left, self.right, operator.mul)
        return helper.get_result()

class Power(BinaryOp):

    def output_type(self):
        return rules.PowerPromoter(self.left, self.right).get_result()

class Subtract(BinaryOp):

    def output_type(self):
        helper = rules.BinaryPromoter(self.left, self.right, operator.sub)
        return helper.get_result()

class Divide(BinaryOp):

    def output_type(self):
        if not util.all_of(self.args, ir.NumericValue):
            raise TypeError('One argument was non-numeric')

        return rules.shape_like_args(self.args, 'double')

class LogicalBinaryOp(BinaryOp):

    def output_type(self):
        if not util.all_of(self.args, ir.BooleanValue):
            raise TypeError('Only valid with boolean data')
        return rules.shape_like_args(self.args, 'boolean')

class Modulus(BinaryOp):

    def output_type(self):
        helper = rules.BinaryPromoter(self.left, self.right,
                                      operator.mod)
        return helper.get_result()

class And(LogicalBinaryOp):
    pass

class Or(LogicalBinaryOp):
    pass

class Xor(LogicalBinaryOp):
    pass

class Comparison(BinaryOp, BooleanValueOp):

    def _maybe_cast_args(self, left, right):
        if left._can_implicit_cast(right):
            return left, left._implicit_cast(right)

        if right._can_implicit_cast(left):
            return right, right._implicit_cast(left)

        return left, right

    def output_type(self):
        self._assert_can_compare()
        return rules.shape_like_args(self.args, 'boolean')

    def _assert_can_compare(self):
        if not self.left._can_compare(self.right):
            raise TypeError('Cannot compare argument types')

class Equals(Comparison):
    pass

class NotEquals(Comparison):
    pass

class GreaterEqual(Comparison):
    pass

class Greater(Comparison):
    pass

class LessEqual(Comparison):
    pass

class Less(Comparison):
    pass

class Between(BooleanValueOp):

    input_type = [rules.value, rules.value(name='lower_bound'),
                  rules.value(name='upper_bound')]

    def output_type(self):
        self._assert_can_compare()
        return rules.shape_like_args(self.args, 'boolean')

    def _assert_can_compare(self):
        expr, lower, upper = self.args
        if (not expr._can_compare(lower) or not expr._can_compare(upper)):
            raise TypeError('Arguments are not comparable')

class Contains(BooleanValueOp):

    def __init__(self, value, options):
        self.value = as_value_expr(value)
        self.options = as_value_expr(options)
        BooleanValueOp.__init__(self, self.value, self.options)

    def output_type(self):
        all_args = [self.value]

        options = self.options.op()
        if isinstance(options, ir.ValueList):
            all_args += options.values
        elif isinstance(self.options, ArrayExpr):
            all_args += [self.options]
        else:
            raise TypeError(type(options))

        return rules.shape_like_args(all_args, 'boolean')

class NotContains(Contains):
    pass

class ReplaceValues(ValueNode):

    """
    Apply a multi-value replacement on a particular column. As an example from
    SQL, given DAYOFWEEK(timestamp_col), replace 1 through 5 to "WEEKDAY" and 6
    and 7 to "WEEKEND"
    """
    pass

class TopKExpr(ir.AnalyticExpr):

    def type(self):
        return 'topk'

    def _table_getitem(self):
        return self.to_filter()

    def to_filter(self):
        return SummaryFilter(self).to_expr()

    def to_aggregation(self, metric_name=None, parent_table=None,
                       backup_metric_name=None):
        """
        Convert the TopK operation to a table aggregation
        """
        op = self.op()

        arg_table = ir.find_base_table(op.arg)

        by = op.by
        if not isinstance(by, ir.Expr):
            by = by(arg_table)
            by_table = arg_table
        else:
            by_table = ir.find_base_table(op.by)

        if metric_name is None:
            if by.get_name() == op.arg.get_name():
                by = by.name(backup_metric_name)
        else:
            by = by.name(metric_name)

        if arg_table.equals(by_table):
            agg = arg_table.aggregate(by, by=[op.arg])
        elif parent_table is not None:
            agg = parent_table.aggregate(by, by=[op.arg])
        else:
            raise com.IbisError('Cross-table TopK; must provide a parent '
                                'joined table')

        return agg.sort_by([(by.get_name(), False)]).limit(op.k)

class SummaryFilter(ValueNode):

    def __init__(self, expr):
        ValueNode.__init__(self, expr)

    def output_type(self):
        return ir.BooleanArray

class TopK(ValueNode):

    # Substitutions under TopK are not allowed
    blocking = True

    def __init__(self, arg, k, by=None):
        if by is None:
            by = arg.count()

        if not isinstance(arg, ArrayExpr):
            raise TypeError(arg)

        if not isinstance(k, int) or k < 0:
            raise ValueError('k must be positive integer, was: {0}'.format(k))

        self.arg = arg
        self.k = k
        self.by = by

        Node.__init__(self, [arg, k, by])

    def output_type(self):
        return TopKExpr

class Constant(ValueOp):

    def __init__(self):
        ValueOp.__init__(self, [])

class TimestampNow(Constant):

    def output_type(self):
        return ir.TimestampScalar

class E(Constant):

    def output_type(self):
        return ir.DoubleScalar

class TimestampUnaryOp(UnaryOp):

    input_type = [rules.timestamp]

_truncate_units = [
    'Y', 'Q', 'M', 'D', 'J', 'W', 'H', 'MI'
]

_truncate_unit_aliases = {
    # year
    'YYYY': 'Y',
    'SYYYY': 'Y',
    'YEAR': 'Y',
    'YYY': 'Y',
    'YY': 'Y',

    # month
    'MONTH': 'M',
    'MON': 'M',

    # week
    'WW': 'W',

    # day of month

    # starting day of week

    # hour
    'HOUR': 'H',
    'HH24': 'H',

    # minute
    'MINUTE': 'MI',

    # second

    # millisecond

    # microsecond
}

def _truncate_unit_validate(unit):
    orig_unit = unit
    unit = unit.upper()

    # TODO: truncate autocompleter

    unit = _truncate_unit_aliases.get(unit, unit)
    valid_units = set(_truncate_units)

    if unit not in valid_units:
        raise com.IbisInputError('Passed unit {0} was not one of'
                                 ' {1}'.format(orig_unit,
                                               repr(valid_units)))

    return unit

class Truncate(ValueOp):

    input_type = [
        rules.timestamp,
        rules.string_options(_truncate_units, name='unit',
                             validator=_truncate_unit_validate)]
    output_type = rules.shape_like_arg(0, 'timestamp')

class Strftime(ValueOp):

    input_type = [rules.timestamp, rules.string(name='format_str')]
    output_type = rules.shape_like_arg(0, 'string')

class ExtractTimestampField(TimestampUnaryOp):

    output_type = rules.shape_like_arg(0, 'int32')

class ExtractYear(ExtractTimestampField):
    pass

class ExtractMonth(ExtractTimestampField):
    pass

class ExtractDay(ExtractTimestampField):
    pass

class ExtractHour(ExtractTimestampField):
    pass

class ExtractMinute(ExtractTimestampField):
    pass

class ExtractSecond(ExtractTimestampField):
    pass

class ExtractMillisecond(ExtractTimestampField):
    pass

class TimestampFromUNIX(ValueOp):

    input_type = [value, rules.string_options(['s', 'ms', 'us'], name='unit')]
    output_type = rules.shape_like_arg(0, 'timestamp')

class DecimalUnaryOp(UnaryOp):

    input_type = [rules.decimal]

class DecimalPrecision(DecimalUnaryOp):

    output_type = rules.shape_like_arg(0, 'int32')

class DecimalScale(UnaryOp):

    output_type = rules.shape_like_arg(0, 'int32')

class Hash(ValueOp):

    input_type = [value, rules.string_options(['fnv'], name='how')]
    output_type = rules.shape_like_arg(0, 'int64')

class TimestampDelta(ValueOp):

    input_type = [rules.timestamp, rules.timedelta(name='offset')]
    output_type = rules.shape_like_arg(0, 'timestamp')


text:
title: FL0005
category: how-to
hide_menu: true
---

# PatternMatchOrClausesOnNewLine (FL0005)

## Cause

All pattern match "or" clauses should be on their own line.

## Rationale

Readability.

## How To Fix

Place each pattern match "or" clause on its own line.

## Rule Settings

    {
        "patternMatchOrClausesOnNewLine": {
            "enabled": false
        }
    }

redpajama_set_name: RedPajamaGithub


text:
/**
* This is an (only) slightly extended version of Dave Herman's
* pattern-match module.
*
*    https://github.com/dherman/pattern-match
*
* The match dialect provides some syntax sugar on top of the library e.g.
* the "match type" syntax i.e. "var::type", used for function argument
* pattern matching as well as the more explicit "match" statement which
* follows the pattern-match library's api more closely.
*
* Though no code was used, additional inspiration for these features
* comes from Nate Faubion's very nice "sparkler" library for sweet.js:
*
*   https://github.com/natefaubion/sparkler
*
* The "extensions" to pattern-match here are simply defining predicates
* for matching sugarlisp's s-expression types: lists, atoms, symbols, etc.
* Doing so is allowed for in the pattern-match library (you can easily
* do the same to add predicates for your own types if you like):
*
*    https://github.com/dherman/pattern-match#custom-patterns
*
* Note when using these features to match lispy forms for generating code,
* be sure to use the "sl" versions i.e. match.slstring not match.string,
* match.slnumber not match.number.  The ones with "sl" may be useful in
* other code, just not when matching forms generated by the sugarlisp
* reader.
*
* Note that currently the code generated by sugarlisp simply assumes this
* module has been required and assigned to "match" and will give a
* run-time error if the pattern matching features are used without
* doing so.  Make sure that you require this extended version of the
* library as follows (note the "sugarlisp-match/" gets you this
* version not Dave Herman's original):
*
*    var match = require('sugarlisp-match/pattern-match');
*
*/

var match = require('pattern-match');
var sl = require('sugarlisp-core/sl-types');

match.sllist = Array.isArray;

match.slatom = function(form) {
  return sl.isAtom(form);
};

match.slsymbol = function(form) {
  return sl.typeOf(form) === 'symbol';
};

match.slstring = function(form) {
  return sl.typeOf(form) === 'string';
};

match.slnumber = function(form) {
  return sl.typeOf(form) === 'number';
};

match.slboolean = function(form) {
  return sl.typeOf(form) === 'boolean';
};

match.slnull = function(form) {
  return sl.typeOf(form) === 'null';
};

// sldefault is available as an alternative to match.any
// it really just makes the lispy form look closer to the
// match statement's "default" keyword
match.sldefault = match.any;

// rest is mainly behind the scenes e.g. when you do ...rest
match.slrest = match.any;

module.exports = match;


text:
/**************************************************************************
 *
 * GLOBAL DEFINITIONS
 *
 **************************************************************************/

@font-face {
  font-family: 'Glacial Indifference';
  src: url('/fonts/GlacialIndifference-Italic.eot');
  src: local('Glacial Indifference Italic'), local('GlacialIndifference-Italic'),
    url('/fonts/GlacialIndifference-Italic.eot?#iefix') format('embedded-opentype'),
    url('/fonts/GlacialIndifference-Italic.woff') format('woff'),
    url('/fonts/GlacialIndifference-Italic.ttf') format('truetype'),
    url('/fonts/GlacialIndifference-Italic.svg#GlacialIndifference-Italic') format('svg');
  font-weight: normal;
  font-style: italic;
}

@font-face {
  font-family: 'Glacial Indifference';
  src: url('/fonts/GlacialIndifference-Regular.eot');
  src: local('Glacial Indifference Regular'), local('GlacialIndifference-Regular'),
    url('/fonts/GlacialIndifference-Regular.eot?#iefix') format('embedded-opentype'),
    url('/fonts/GlacialIndifference-Regular.woff') format('woff'),
    url('/fonts/GlacialIndifference-Regular.ttf') format('truetype'),
    url('/fonts/GlacialIndifference-Regular.svg#GlacialIndifference-Regular') format('svg');
  font-weight: normal;
  font-style: normal;
}

@font-face {
  font-family: 'Glacial Indifference';
  src: url('/fonts/GlacialIndifference-Bold.eot');
  src: local('Glacial Indifference-Bold'), local('GlacialIndifference-Bold'),
    url('/fonts/GlacialIndifference-Bold.eot?#iefix') format('embedded-opentype'),
    url('/fonts/GlacialIndifference-Bold.woff') format('woff'),
    url('/fonts/GlacialIndifference-Bold.ttf') format('truetype'),
    url('/fonts/GlacialIndifference-Bold.svg#GlacialIndifference-Bold') format('svg');
  font-weight: bold;
  font-style: normal;
}

* {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -ms-box-sizing: border-box;
  box-sizing: border-box;
}

body {
  font-family: 'Glacial Indifference', "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif !important;
}

h1, h2, h3, h4, h5, h6{
  letter-spacing: 0;
}

p{
  text-align: left;
  font-size: 2rem;
  max-width: 50em;
  margin: 0 auto;
}

a,
a:visited{
  color: #00bab3;
}

a:hover,
a:focus{
  color: #00bab3;
  text-decoration: none;
}

.separator{
  height: 2px;
  width: 8rem;
  margin: 2em auto;
  background-color: currentColor;
}

.background-snic-grey{
  background: #373636 !important;
  color: white;
}

.background-snic-blue{
  background: #00bab3 !important;
  color: white;
}

.background-gold{
  background: #eee8aa !important;
}

.background-silver{
  background: #d3d3d3 !important;
}

.background-snic-blue a,
.background-snic-blue a:visited{
  color: white;
  opacity: 0.8;
}

.background-snic-blue a:hover,
.background-snic-blue a:focus{
  color: white;
  opacity: 1;
  text-decoration: none;
}

.text-center {
  text-align: center;
}

.text-left {
  text-align: left;
}

.margin-vert {
  margin-top: 1em;
  margin-bottom: 1em;
}

.checkbox label{
  font-weight: normal;
  font-size: 1.75rem;
  margin-bottom: 2vh;
}

.checkbox label > input {
  margin-right: 0.5em;
}

/**************************************************************************
 *
 * COMPONENT SPECIFIC DEFINITIONS
 *
 **************************************************************************/

/***********************************
 *  Navbar
 ***********************************/
.navbar {
  position: fixed;
  top: 0;
  width: 100%;
  padding: 0 10px;

  background-color: rgba(0, 186, 179, 0.9);
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1);

  font-size: 2rem;
  line-height: 50px;

  z-index: 100000000;
  /*overflow: hidden; */
}

.navbar .dropdown,
.navbar a,
.navbar a:visited{
  width: 100%;
  display: inline-block;
  opacity: 1;
}
.navbar .dropdown .dropdown-toggle {
  width: 100%;
  padding: 0px 10px;
  border: none;
  text-align: left;
}

.navbar a:hover,
.navbar a:focus{
  opacity: 0.8;
}

.navbar .logonav{
  display: inline-block;
}

.navbar .logonav img{
  position: relative;
  top: -3px;
  height: 30px;
  vertical-align: middle;
}

.navbar button.toggle{
  display: inline-block;
  height: 50px;
  padding: 0 5px;
  margin: 0;
  float: right;
  border: none;
  outline: none;
  font-size: inherit;
  line-height: 50px;
  color: white;
}

.navbar .pages.collapse{
  display: none;
  margin: 0 -10px;
  padding: 0;
  list-style: none;
  color: white;
}

.navbar .pages.collapse.open{
  display: block;
}
.navbar .pages li{
  display: block;
  margin: 0;
}

/* Links inside the navbar */

.navbar .pages a,
.navbar .pages a:visited {
  padding: 10px 10px;
  width: 100%;
  color: white;
  text-decoration: none;
}

.navbar .pages.collapse .dropdown a {
  color:black;
  display:block;
}

.dropdown-menu {
  width:100%;
}

@media (min-width: 800px) {
  .navbar .dropdown .dropdown-toggle {
    width: auto;
  }

  .navbar .collapse{
    display: inline-block
  }

  .navbar button.toggle{
    display: none;
  }

  .navbar .pages.collapse{
    display: inline-block;
    margin: 0;
    padding: 0;
    list-style: none;
    float: right;
  }

  .navbar .pages li{
    display: inline-block;
  }

  .navbar .pages a {
    width: auto;
    padding: 0 10px;
  }

  .navbar .pages.collapse .dropdown a {
    color:black;
    padding: 5px;
  }

  .navbar .pages li .dropdown li{
    display: block;
    text-align: left
  }

  .navbar .pages li .dropdown li a{
    text-align: right;
  }

  .dropdown-menu {
    min-width: 100px !important;
  }
}

/*
 * Navicon
 */

.navicon-button {
    display: inline-block;
    position: relative;
    transition: 0.125s;
    cursor: pointer;
    user-select: none;
}

.navicon-button:active,
.navicon-button:focus{
    outline: none;
}

.navicon-button .navicon:before, .navicon-button .navicon:after {
    transition: 0.25s;
}
.navicon-button:hover {
    transition: 0.5s;
    opacity: 1;
}
.navicon-button:hover .navicon:before, .navicon-button:hover .navicon:after {
    transition: 0.25s;
}
.navicon-button:hover .navicon:before {
    top: .40em;
}
.navicon-button:hover .navicon:after {
    top: -.40em;
}

.navicon {
    display: inline-block;
    position: relative;
    top: -.09em;
    width: 1.1em;
    height: .15em;
    background: currentColor;
    transition: 0.5s;
    vertical-align: middle;
    border-radius: .03em;
}

.navicon:before,
.navicon:after {
    display: block;
    content: "";
    height: .15em;
    width: 1.1em;
    background: currentColor;
    position: absolute;
    z-index: 0;
    transition: 0.5s 0.25s;
    border-radius: .03em;
}

.navicon:before {
    top: .30em;
}
.navicon:after {
    top: -.30em;
}

.navicon-button[aria-expanded=true]:not(.steps) .navicon:before,
.navicon-button[aria-expanded=true]:not(.steps) .navicon:after,
.navicon-button.open:not(.steps) .navicon:before,
.navicon-button.open:not(.steps) .navicon:after {
    top: 0 !important;
}

.navicon-button[aria-expanded=true] .navicon:before,
.navicon-button[aria-expanded=true] .navicon:after,
.navicon-button.open .navicon:before,
.navicon-button.open .navicon:after {
    transition: 0.5s;
}

/* times sign */
.navicon-button[aria-expanded=true] .navicon.navicon-times,
.navicon-button.open .navicon.navicon-times{
  background: transparent;
}

.navicon-button[aria-expanded=true] .navicon.navicon-times:before,
.navicon-button.open .navicon.navicon-times:before{
  transform: rotate(-45deg);
}

.navicon-button[aria-expanded=true] .navicon.navicon-times:after,
.navicon-button.open .navicon.navicon-times:after{
  transform: rotate(45deg);
}

/********************
 * Header
 ********************/
header.text h2 {
  position: relative;
  min-height: 5vh;

  padding: 4em 2em 2em 2em;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  background: rgba(0, 186, 179, 0.7);
  color: white;
  opacity: .9;

  margin-bottom: 1em;

}

header.hero{
  position: relative;
  min-height: 80vh;

  padding: 8em 2em;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;

  color: white;
  opacity: .9;
  margin-bottom: 1em;
}

header.hero::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  background: rgba(0, 186, 179, 0.7);
}

header.hero .logo{
  max-width: 80%;
  width: 20em;
}

header.hero p {
  color: white;
  max-width: 30em;
  font-size: 2rem;
  text-align: center;
}

header.hero h2{
  font-size: 5rem;
}

@media (min-width: 400px) {
  header.hero p{
    font-size: 2.5rem;
  }
}

/* Larger than desktop */
@media (min-width: 1000px) {
  header.hero p{
    font-size: 3rem;
  }
}

/* Larger than Desktop HD */
@media (min-width: 1200px) {
  header.hero p{
    font-size: 3.6rem;
  }
}

/******************
 * sections
 ******************/

section h1,
section h2,
section h3,
section h4,
section h5,
section h6{
  text-align: center;
}

section.slanted{
  transform: skewY(3deg);
  margin-top: -2px;
}

section.slanted .content{
  transform: skewY(-3deg);
  padding: 5rem 15px;
  overflow: auto;
}

section.slanted.twocolumn{
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-content: stretch;
  background-color: white;
}

section.slanted.twocolumn .subpage{
  flex-grow: 0;
  flex-shrink: 0;
  flex-basis: 100%;
}

section.slanted.twocolumn .subpage.image{
  background-size: cover;
  order: -1;
  height: 50vw;
  margin-bottom: -1px;
}

section.slanted.twocolumn .content{
  max-width: 45em;
  margin: 0 auto;
}

section.intro p {
  text-align: left;
  padding-bottom: 10px;
}

section.quote{
  background-color: #373636;
  text-align: center;
  color: white;
}

section.quote .content{
  font-size: 2rem;
}

section.quote .person{
  font-size: 80%;
  color: #00bab3;
}

@media (min-width: 400px) {
  section.quote .content{
    font-size: 2.5rem;
  }
}

/* Larger than phablet */
@media (min-width: 550px) {
  section.slanted.twocolumn .subpage.image{
    height: 75vw;
  }
}

/* Larger than tablet */
@media (min-width: 750px) {
  section.slanted .content{
    padding: 10rem 15px;
  }

  section.slanted.twocolumn{
    flex-wrap: wrap;
  }

  section.slanted.twocolumn .subpage{
    flex-grow: 1;
    flex-basis: 40%;
    transition: flex-basis 0.2s ease-out;
  }

  section.slanted.twocolumn .subpage:not(.image){
    flex-basis: 60%;
  }

  section.slanted.twocolumn .subpage.image{
    height: auto;
    order: unset;
    margin-bottom: 0;
  }
}

/* Larger than desktop */
@media (min-width: 1000px) {
  section.quote .content{
    font-size: 3rem;
  }

  section.slanted.twocolumn .subpage,
  section.slanted.twocolumn .subpage:not(.image){
    flex-basis: 50%;
  }
}

/* Larger than Desktop HD */
@media (min-width: 1200px) {
  section.quote .content{
    font-size: 3.6rem;
  }
}

/****************************
 * Button
 ****************************/
 .button.button-primary,
button.button-primary,
input[type="submit"].button-primary,
input[type="reset"].button-primary,
input[type="button"].button-primary
{
  color: #00bab3;
  background-color: #FFF;
  border-color: #00bab3;
}

.button.button-primary:hover,
button.button-primary:hover,
input[type="submit"].button-primary:hover,
input[type="reset"].button-primary:hover,
input[type="button"].button-primary:hover,
.button.button-primary:focus,
button.button-primary:focus,
input[type="submit"].button-primary:focus,
input[type="reset"].button-primary:focus,
input[type="button"].button-primary:focus
{
  color: #FFF;
  background-color: #00bab3;
  border-color: #00bab3;
}

/****************************
 * Footer
 ****************************/

footer {
  width: 100%;
  background-color: #373636;
  padding: 5vh 10%;
}

footer .sponsor {
  color: white;
  width: 90%;
  display: flex;
  justify-content: space-evenly;
  flex-wrap: wrap;
  align-items: stretch;
  margin:-10px auto;
}

.sponsor a {
  height: 100px;
  display: inline-flex;
  margin: 10px;
  padding: 10px;
  flex-grow: 1;
  flex-basis: calc(100% - 20px);
  text-align: center;
  background-color: white;
  align-items: center;
  justify-content: center;
}

.sponsor a img {
  max-width: 100%;
  max-height: 100%;
}

.sponsor a.gold,
.sponsor a.nedap {
  flex-grow: 2;
  flex-basis: 100%;
  margin: 15px;
  max-width: 100%;
}

.sponsor a.nedap {
  background-color: transparent;
}

@media (min-width: 750px) {
  footer .sponsor {
    width: 75%;
  }

  .sponsor a {
    height: 150px;
    flex-basis: calc(50% - 20px);
  }

  .sponsor a.gold {
    flex-grow: 2;
    flex-basis: 100%;
    margin: 15px 75px;
    max-width: 80%;
  }
}

@media (min-width: 1200px) {
  footer .sponsor {
    width: 50%;
  }
}

footer a,
footer a:visited{
  color: white;
  text-align: center;
  margin: 0 1vw;
  display: inline-block;
}

footer a:hover,
footer a:focus{
  color:#00bab3;
}

.foot{
  overflow: hidden;
  width: 100%; /* Full width */
  margin-top: 30px;
  color: white;
  text-align: center;
}

.banner{
  width: 60vw;
  height: 20vh;
  display: block;
  background-image: url('/images/Banner.jpg');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  margin: auto;
}

@media (min-width: 750px) {

  .banner{
    /*width: 80vw;*/
    height: 20vh;
  }
}

/**************************************************************************
 *
 * PAGE SPECIFIC DEFINITIONS
 *
 **************************************************************************/

/****************************
 * Index
 ****************************/

header.hero.index{
   background-image: url('/images/foto1.jpg');
}

section#speakers .subpage.image{
  background-image: url('/images/Foto-Spreker.jpg');
  background-position: center 80%;
}

section#location .subpage.image{
  background-image: url('/images/Foto-Spiegel.jpg');
  background-position: center 30%;
}

section#snic .subpage.image{
  background-image: url('/images/foto_kijken.jpg');
  background-position: right 20%;
}

.video{
  position: relative;
  min-height: 70vh;

  padding: 8em 2em;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  background-image: url('/images/fotozaal.jpg');
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;

  color: white;
  opacity: .9;
}

.video::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  background: rgba(0, 186, 179, 0.7);
}

.youtube{
  text-align: center;
  width: 100%;
  position: relative;
  color: white;
}

.youtube a,
.youtube a:visited,
.youtube a:hover,
.youtube a:focus{
  color: white;
}

.youtube a:hover,
.youtube a:focus{
  opacity: 0.8;
}

/****************************
 * Speakers
 ****************************/
header.hero.speakers{
  background-image: url('/images/Foto-Spreker2.jpg');
}

.timetable {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.timetable .time {
  flex: 1 0 50px;
  flex-grow: 2;
  padding: 10px;
  margin-left: 10px;
  margin-top: 10px;
}

.timetable .session {
  text-align: center;
  flex: 1 0 300px;
  box-sizing: border-box;
  color: #171e42;
  padding: 10px;
  margin: 1em 0em;
  width: 80vw;
}

.timetable .session .shorten {
  padding-bottom: 10px;
}

.timetable img {
  max-width: 100%;
  display: block;
  margin: 0 auto;
  padding-bottom: 20px
}

.timetable .session p {
  text-align: justify;
  text-align-last: center;
}

.timetable .session::after {
  font-family: FontAwesome;
  content: "\f068";
}

.timetable .session:last-of-type:after {
  content: "";
}

@media(min-width: 600px) {
  .timetable img {
    max-width: 400px;
  }

  .timetable .session::after {
    content: none;
  }
}

@media(min-width: 1500px){
  .timetable {
    margin: 10px 10vw;
  }

  .timetable .session {
    width: 30vw;
    margin: 0px;
  }

  .timetable img.nick {
    margin-top: 45px;
  }

  .timetable h5.david {
    margin-top: 65px;
  }
}

/****************************
 * Panel
 ****************************/
section.panel h3 {
  flex-basis: 100%;
  margin-top: 20px;
}

section.panel .speaker p {
  margin-bottom:20px;
}

section.panel .speaker {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  margin: 0 auto;
  max-width: 900px;
}
section.panel .photo {
  margin: 0 auto;
}

section.panel .photo img {
  max-width: 100%;
  display: block;
}

@media(min-width: 900px){
  section.panel .content .speaker p {
    max-width: 650px;
    flex-grow: 1;
    margin-top: auto;
    margin-bottom: auto;
  }

  section.panel .photo {
    max-width: 200px;
    flex-grow: 1;
  }

  section.panel .speaker:nth-child(odd) {
    flex-direction: row;
  }

  section.panel .speaker:nth-child(even) {
    flex-direction: row-reverse;
  }
}
/****************************
 * Partners
 ****************************/
header.hero.partners{
  background-image: url('/images/Foto-Sponsor.jpg');
}

.box{
  position: relative;
  max-width: 20em;
  margin: 0 auto 25px;
}

.box a{
  opacity: 1;
}

.box a:hover{
  opacity: 0.7;
}

.box img{
  width: 100%;
}

#platinum .box{
  max-width: 40em;
  margin: 0 auto 50px;
}

#gold .box{
  max-width: 25em;
}

#gold.slanted.background-gold .row {
  margin-bottom: 40px;
}

/****************************
 * Organisation
 ****************************/
.committee-profile .name{
  margin: 0;
}

.committee-profile .function{
  text-align: center;
  font-size: 3rem;
}

header.hero.organisation{
  background-image: url('/images/SNiC-14.jpg');
  background-position: center 40%;
}

section#mimi .subpage.image{
  background-image: url('/images/SNiC-12.jpg');
  background-position: center 20%;
  min-height: 300px;
}

section#guussieboy .subpage.image{
  background-image: url('/images/SNiC-10.jpg');
  background-position: center 20%;
  min-height: 300px;
}

section#entn .subpage.image{
  background-image: url('/images/SNiC-7.jpg');
  background-position: center 20%;
  min-height: 300px;
}

section#harm .subpage.image{
  background-image: url('/images/SNiC-8.jpg');
  background-position: center 20%;
  min-height: 300px;
}

section#marty .subpage.image{
  background-image: url('/images/SNiC-11.jpg');
  background-position: center 20%;
  min-height: 300px;
}

section#renac .subpage.image{
  background-image: url('/images/SNiC-6.jpg');
  background-position: center 20%;
  min-height: 300px;
}

section#xabi .subpage.image{
  background-image: url('/images/SNiC-9.jpg');
  background-position: center 20%;
  min-height: 300px;
}

@media (min-width: 550px) {

  section#mimi .subpage.image,
  section#guussieboy .subpage.image,
  section#entn .subpage.image,
  section#harm .subpage.image,
  section#marty .subpage.image,
  section#renac .subpage.image,
  section#xabi .subpage.image{
    min-height: initial
  }
}

@media (min-width: 400px) {
  section#mimi .subpage.image,
  section#guussieboy .subpage.image,
  section#entn .subpage.image,
  section#harm .subpage.image,
  section#marty .subpage.image,
  section#renac .subpage.image,
  section#xabi .subpage.image{
    min-height: 420px;
  }
}

/****************************
 * Location
 ****************************/

header.hero.location{
  background-image: url('/images/Foto-Spiegel.jpg');
}

#map{
  height:70vh;
  border-top: 3px solid #00bab3;
}

#map .gm-style {
  font-family: 'Glacial Indifference', "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif !important;
}

#map #content,
#map #content p{
  text-align: center;
}

#map #content h1{
  font-size: 2em;
  margin-bottom: 0;
}

#map #content .separator {
  margin: 1em auto;
}

/****************************
 * Login
 ****************************/

header.hero.login{
  min-height: 0;
  background-image: url('/images/23369577356_2d8183a751_o.jpg');
  background-position: center 90%;
}

.form {
  max-width: 40em;
  margin: 0 auto;
}

.form-group {
  padding-bottom: 10px;
}

.form-control {
  width: 100%;
}

.form.form-signin {
  max-width: 25em;
}

.form.form-signin .row {
  margin: 10px;
}

.login-separator{
  text-align:center;
  margin-bottom: 1rem;
}

.login-separator:before,
.login-separator:after {
  width: 15%;
  height: 1px;
  background: #adadad;
  display: inline-block;
  vertical-align: middle;
  margin: 0 10px;
  content: '';
}

/****************************
 * Register
 ****************************/
header.hero.register{
  min-height: 0;
  background-image: url('/images/23369577356_2d8183a751_o.jpg');
  background-position: center 90%;
}

.form-register {
  max-width: 40em;
  margin: 0 auto;
  padding: 10px;
}

.register p {
  margin: 10px auto;
  padding: 10px;
  text-align: left;
}

/****************************
 * Profile
 ****************************/

section.profile {
  margin:10px;
}

.interests {
  display: flex;
  flex-wrap: wrap;
  margin-left: -10px;
  margin-top: -10px;
}
.interests .interest {
  flex: 1 0 200px;
  box-sizing: border-box;
  color: #171e42;
  padding: 10px;
  margin-left: 10px;
  margin-top: 10px;
}

@media (min-width: 410px) {
  .interests .interest {
    max-width: calc(50% - 10px);
  }
}

/****************************
 * Users
 ****************************/

.buses.table {
  max-width: 50em;
  margin: auto;
  width:100%;
  margin-bottom: 20px;
}

/****************************
 * Users
 ****************************/

.section.users {
  overflow:auto;
}

.button-users {
  padding: 0px;
  width: 100%;
}

.users.table {
  margin: 0 0 2em 0;
  width: 100%;
}

/****************************
 * Diet
 ****************************/

#diet-table {
  float: none;
}

.diet.table {
  margin: 0 0 2em 0;
  width: 100%;
}

.diet.table thead th {
  padding: 10px 0px 10px 0px;
  width:20%;
}

.diet.table thead th .checkbox {
  padding: 10px 0px 10px 0px;
  width: 10%;
  text-align: center;
}

/****************************
 * Aanwezig
 ****************************/

#aanwezig-table {
  float: none;
}

table.aanwezig {
  width:100%;

}

/****************************
 * Participate
 ****************************/

ul.associations {
  list-style: none;
  padding-left: 0;
  margin: 1rem auto;
  text-align: center;
}

section.intro p.participate {
  text-align: center
}

/****************************
 * Connect better
 ****************************/
.connectbetter p {
  padding: 10px;
}

/****************************
 * Nedap Bedrijfsprofiel
 ****************************/

/*
 * Hero image on small devices. quote above image
 */
@media(max-width: 800px){

  header.hero.nedap{
    min-height: 0;
    background-image: url('/images/bedrijven/nedap/andre.jpg');
    background-color: #373636;
    display:block;
    background-size: contain;
    background-position: 50% 100%;
    opacity: 1;
    padding:0px;
    padding-bottom: calc(49% + 1em)
  }

  .hero-nedap-text{
    width: 100%;
    padding: 65px 0px 20px 0px;
  }

  h2.nedap,
  p.nedap {
    text-align: center;
  }
}

/*
 *Hero image on larger devices. Quote inside the image
 */
@media (min-width: 800px) {
  header.hero.nedap{
    background-image: url('/images/bedrijven/nedap/andre.jpg');
    background-position: 100% 100%;
    min-height: 80vh;
    opacity: 1;
  }

  h2.nedap,
  .separator.nedap,
  p.nedap {
    text-align: center;
    color: black !important;
  }
}
section#flock .subpage.image{
  background-image: url('/images/bedrijven/nedap/flock.jpg');
  background-position: center 80%;
}

section#paris .subpage.image{
  background-image: url('/images/bedrijven/nedap/paris.jpg');
  background-position: center 80%;
}

.background-nedap-orange{
  background: #FF8700 !important;
  color: white;
}

.background-nedap-grey{
  background: #69696E !important;
  color: white;
}

/****************************
 * Achmea Bedrijfsprofiel
 ****************************/

header.hero.achmea{
  background-image: url('/images/Hero_Achmea.jpg');
  min-height: 50vh;
}

/****************************
 * KPMG Bedrijfsprofiel
 ****************************/

header.hero.kpmg {
  background-image: url('/images/Hero_KPMG.jpg');
  min-height: 50vh;
}

/****************************
 * Topicus Bedrijfsprofiel
 ****************************/

header.hero.topicus {
  background-image: url('/images/Hero_Topicus.jpg');
  min-height: 50vh;
}

/****************************
 * One-off elements
 ****************************/

.privacy {
  font-size: 1.5em;
  text-align: center;
  padding: 10px;
}

.alert-dismissable .close, .alert-dismissible .close {
  float:right;
}

article + .readmore-js-toggle { padding-bottom: 1.5em; border-bottom: 1px solid #999; font-weight: bold;}


text:
package io.fabric8.kubernetes.examples;

import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext;
import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
import io.fabric8.kubernetes.client.informers.SharedIndexInformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/**
 * You would need to have Dummy CRD installed. See test-crd.yaml in resources/ folder.
 *
 * Run this sample using this command:
 *
 *   mvn exec:java -Dexec.mainClass="io.fabric8.kubernetes.examples.DynamicSharedIndexInformerExample"
 *
 *
 */
public class DynamicSharedIndexInformerExample {
  private static final Logger logger = LoggerFactory.getLogger(DynamicSharedIndexInformerExample.class.getSimpleName());

  public static void main(String[] args) {
    ResourceDefinitionContext context = new ResourceDefinitionContext.Builder()
        .withGroup("demo.fabric8.io")
        .withVersion("v1")
        .withPlural("dummies")
        .withKind("Dummy")
        .withNamespaced(true)
        .build();

    try (KubernetesClient client = new KubernetesClientBuilder().build();
        SharedIndexInformer<GenericKubernetesResource> informer = client.genericKubernetesResources(context).inAnyNamespace()
            .runnableInformer(60 * 1000L);) {
      informer.addEventHandler(new ResourceEventHandler<GenericKubernetesResource>() {
        @Override
        public void onAdd(GenericKubernetesResource genericKubernetesResource) {
          logger.info("ADD {}/{}", genericKubernetesResource.getMetadata().getNamespace(),
              genericKubernetesResource.getMetadata().getName());
        }

        @Override
        public void onUpdate(GenericKubernetesResource genericKubernetesResource, GenericKubernetesResource t1) {
          logger.info("UPDATE {}/{}", genericKubernetesResource.getMetadata().getNamespace(),
              genericKubernetesResource.getMetadata().getName());
        }

        @Override
        public void onDelete(GenericKubernetesResource genericKubernetesResource, boolean b) {
          logger.info("DELETE {}/{}", genericKubernetesResource.getMetadata().getNamespace(),
              genericKubernetesResource.getMetadata().getName());
        }
      });

      TimeUnit.MINUTES.sleep(10);
    } catch (InterruptedException interruptedException) {
      Thread.currentThread().interrupt();
      logger.error("interrupted: {}", interruptedException.getMessage());
    }
  }
}


text:
package org.labrad

import io.netty.channel.EventLoopGroup
import java.io.File
import org.labrad.data._
import org.labrad.util.Logging
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}

class ServerConnection(
  val name: String,
  val doc: String,
  val host: String,
  val port: Int,
  val credential: Credential,
  val tls: TlsMode = TlsMode.STARTTLS,
  val tlsCerts: Map[String, File] = Map(),
  handler: Packet => Future[Packet],
  val workerGroup: EventLoopGroup = Connection.defaultWorkerGroup
)(
  implicit val executionContext: ExecutionContext = ExecutionContext.global
) extends Connection with Logging {

  protected def loginData = Cluster(
    UInt(Client.PROTOCOL_VERSION),
    Str(name),
    Str(doc.stripMargin),
    Str("")
  )

  override protected def handleRequest(packet: Packet): Unit = {
    handler(packet).onComplete {
      case Success(response) => sendPacket(response)
      case Failure(e) => // should not happen
    }
  }
}


text:
import sys,subprocess,time,os.path as osp,os

def yes_or_no(question):
    assert isinstance(question,str) or isinstance(question,unicode)
    while True:
        sys.stderr.write(question + " (y/n): ")
        yn = raw_input()
        if yn=='y': return True
        elif yn=='n': return False

def mkdirp(d):
    d = osp.expandvars(d)
    if not osp.exists(d):
        os.makedirs(d)

color2num = dict(
    gray=30,
    red=31,
    green=32,
    yellow=33,
    blue=34,
    magenta=35,
    cyan=36,
    white=37,
    crimson=38
)

def colorize(string, color, bold=False, highlight = False):
    attr = []
    num = color2num[color]
    if highlight: num += 10
    attr.append(str(num))
    if bold: attr.append('1')
    return '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string)

def call_and_print(cmd,color='green',check=True):
    print colorize(cmd, color, bold=True)
    if check: subprocess.check_call(cmd, shell=True)
    else: return subprocess.call(cmd, shell=True)

def check_output_and_print(cmd,color='green'):
    print colorize(cmd, color, bold=True)
    return subprocess.check_output(cmd, shell=True)

def Popen_and_print(cmd, color='green', **kw):
    print colorize(cmd, color, bold=True)
    return subprocess.Popen(cmd, shell=True, **kw)

def maybe_call_and_print(cmd, dry, **kwargs):
    if dry:
        print colorize("(dry) " + cmd,'green')
    else:
        call_and_print(cmd,**kwargs)

MESSAGE_DEPTH = 0
class Message(object):
    def __init__(self, msg):
        self.msg = msg
    def __enter__(self):
        global MESSAGE_DEPTH #pylint: disable=W0603
        print colorize('\t'*MESSAGE_DEPTH + '=: ' + self.msg,'magenta')
        self.tstart = time.time()
        MESSAGE_DEPTH += 1
    def __exit__(self, etype, *args):
        global MESSAGE_DEPTH #pylint: disable=W0603
        MESSAGE_DEPTH -= 1
        maybe_exc = "" if etype is None else " (with exception)"
        print colorize('\t'*MESSAGE_DEPTH + "done%s in %.3f seconds"%(maybe_exc, time.time() - self.tstart), 'magenta')

class Timers(object):
    def __init__(self):
        self.key2tc = {}

    def wrap(self,fn,key):
        assert key not in self.key2tc
        self.key2tc[key] = (0,0)
        def timedfn(*args):
            tstart = time.time()
            out = fn(*args)
            (told,cold) = self.key2tc[key]
            dt = time.time() - tstart
            self.key2tc[key] = (told+dt, cold+1)
            return out
        return timedfn

    def stopwatch(self, key):
        if key not in self.key2tc:
            self.key2tc[key]=(0,0)
        class ScopedTimer(object):
            def __enter__(self):
                self.tstart = time.time()
            def __exit__(self1,*_args): #pylint: disable=E0213
                told,cold = self.key2tc[key]
                dt = time.time()-self1.tstart
                self.key2tc[key] = (told + dt, cold + 1)
        return ScopedTimer()

    def disp(self, s="elapsed time"):
        header = "******** %s ********"%s
        print header
        rows = [(key, t, c, t/c) for (key,(t,c)) in self.key2tc.items() if c>0]
        from tabulate import tabulate
        print tabulate(rows, headers=["desc","total","count","per"])

class InDir(object):
    """
    Enter directory when scope is entered
    Leave it when scope is exited
    """
    def __init__(self,pth):
        self.pth = pth
    def __enter__(self):
        self.curpth = os.getcwd()
        os.chdir(self.pth)
    def __exit__(self,*_):
        os.chdir(self.curpth)

def dict_as_table(d):
    from tabulate import tabulate
    def fmt(v):
        s = str(v)
        if len(s) > 20:
            s = s[:17]+"..."
        return s
    return tabulate([(k,fmt(v)) for (k,v) in sorted(d.items())])


text:
unless node['platform'] == 'debian'
  Chef::Log.warn 'recipe[debian::default] included in non-Debian platform. Skipping.'
  return
end

template '/etc/apt/sources.list' do
  owner 'root'
  group 'root'
  mode 00644
  notifies :run, 'execute[apt-get update]', :immediately
end

include_recipe 'apt'

%w[
  backports
  backports_sloppy
  security
  stable_lts
  stable_proposed_updates
  stable_updates
  testing unstable
].each do |repo|
  include_recipe "debian::#{repo}" if node['debian'][repo]
end


text:
<?php
$form = $this->beginWidget('bootstrap.widgets.TbActiveForm', array(
    'id' => 'ad-form',
    'htmlOptions' => array('enctype' => 'multipart/form-data'),
    'enableAjaxValidation' => false,
));
?>

Fields with * are required.

<?php echo $form->errorSummary($model); ?>
<?php echo $form->textFieldControlGroup($model, 'title', array('class' => 'span5')); ?>

        图片*

            <?php $this->widget('ext.elfinder.ServerFileInput', array(
                'model' => $model,
                'attribute' => 'pic',
                'filebrowserBrowseUrl' => Yii::app()->createUrl('mall/elfinder/view'),
            )); ?>

<?php echo $form->textFieldControlGroup($model, 'url', array('class' => 'span5')); ?>
<?php
$data = Theme::model()->findAll();
$list = CHtml::listData($data, 'theme', 'name');
echo $form->dropDownListControlGroup($model, 'theme', $list); ?>
<?php echo $form->textAreaControlGroup($model, 'content', array('class' => 'span8', 'rows' => 5)); ?>
<?php echo $form->textFieldControlGroup($model, 'sort_order'); ?>

<?php echo TbHtml::formActions(array(
    TbHtml::submitButton('Submit', array('color' => TbHtml::BUTTON_COLOR_PRIMARY)),
    TbHtml::resetButton('Reset'),
)); ?>

<?php $this->endWidget(); ?>


text:
package jodd.madvoc;

import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class OneTwoActionTest {

	@BeforeClass
	public static void beforeClass() {
		MadvocSuite.startTomcat();
	}

	@AfterClass
	public static void afterClass() {
		MadvocSuite.stopTomcat();
	}

	@Test
	public void testOneRedirectAction() {
		HttpResponse response = HttpRequest.get("localhost:8080/oneRedirect.html").send();
		assertNull(response.bodyText());
		assertEquals(302, response.statusCode());

		String redirectLocation = response.header("location");

		response = HttpRequest.get(redirectLocation).send();
		assertEquals("value = [333]", response.bodyText());
	}

	@Test
	public void testOneMoveAction() {
		HttpResponse response = HttpRequest.get("localhost:8080/oneMove.html").send();
		assertNull(response.bodyText());
		assertEquals(302, response.statusCode());

		String redirectLocation = response.header("location");

		response = HttpRequest.get(redirectLocation).send();
		assertEquals("value = [777]", response.bodyText());
	}

}


text:
'use strict';

const colors = require('kleur/colors');
const fs = require('fs-extra');
const {ciBuildSha, isCiBuild} = require('../common/ci');
const {getStdout} = require('../common/exec');
const {log} = require('../common/logging');
const {shortSha} = require('../common/git');

const {green, yellow, cyan} = colors;
const CODECOV_EXEC = './node_modules/.bin/codecov';
const COVERAGE_REPORTS = {
  'unit_tests': 'test/coverage/lcov-unit.info',
  'integration_tests': 'test/coverage/lcov-integration.info',
  'e2e_tests': 'test/coverage-e2e/lcov.info',
};

/**
 * Uploads a single report
 * @param {string} file
 * @param {string} flags
 */
function uploadReport(file, flags) {
  const codecovCmd = `${CODECOV_EXEC} --file=${file} --flags=${flags}`;
  const output = getStdout(codecovCmd);
  const viewReportPrefix = 'View report at: ';
  const viewReport = output.match(`${viewReportPrefix}.*`);
  if (viewReport && viewReport.length > 0) {
    log(green('INFO:'), 'Uploaded', cyan(file));
  } else {
    log(
      yellow('WARNING:'),
      'Code coverage report upload may have failed:\n',
      yellow(output)
    );
  }
}

/**
 * Uploads code coverage reports for unit / integration tests during CI builds.
 */
async function codecovUpload() {
  if (!isCiBuild()) {
    log(
      yellow('WARNING:'),
      'Code coverage reports can only be uploaded by CI builds.'
    );
    return;
  }

  const commitSha = shortSha(ciBuildSha());
  log(
    green('INFO:'),
    'Uploading coverage reports to',
    cyan(`https://codecov.io/gh/ampproject/amphtml/commit/${commitSha}`)
  );

  Object.entries(COVERAGE_REPORTS)
    .filter(([, reportFile]) => fs.existsSync(reportFile))
    .forEach(([testType, reportFile]) => uploadReport(reportFile, testType));
}

module.exports = {
  codecovUpload,
};

codecovUpload.description =
  'Uploads code coverage reports to codecov.io during CI builds.';


text:
using namespace std;

class MPCB
{
  static unsigned int idInc;
  unsigned int id;
  uint8_t *start;
  unsigned int size;
  vector<MemBlock> *allocated;
public:
  MPCB(uint8_t *plStrt, unsigned int plSz);
  ~MPCB();
  uint8_t* allocate(unsigned int size);
  bool deallocate(uint8_t* strt);
  unsigned int getID();
  uint8_t* getStart();
  unsigned int getSize();
  bool fullyFree();
  unsigned int countFree();
};

#endif


text:
<dom-module id="my-app-title">
    <template></template>
</dom-module>
<script>
    (function () {
        Polymer({
            is: 'my-app-title',
            behaviors: [AppBehavior],
            properties: {
                default: {
                    type: Boolean
                },
                isCurrent: {
                    type: Boolean,
                    observer: 'currentChanged'
                }
            },
            ready: function () {
                if (this.default) {
                    AppBehavior.title.setDefault(Polymer.dom(this).textContent);
                }
            },
            currentChanged: function(newVal, oldVal) {
                if (newVal) {
                    AppBehavior.title.add(Polymer.dom(this).textContent);
                } else {
                    AppBehavior.title.remove(Polymer.dom(this).textContent);
                }
            }
        });
    })();
</script>


text:
import {Component} from '@angular/core';
import {Platform} from 'ionic-angular';
import {SocialSharing} from 'ionic-native';

/*
 This component is intented to be as an easy and simple example of:
 http://ionicframework.com/docs/v2/native/social-sharing/
 */

@Component({
    templateUrl: 'build/pages/share/share.html'
})
export class SharePage {

    public shareMsg:string;

    constructor(private platform:Platform) {
        this.platform = platform;
        this.shareMsg = "Hey! I'm currently in a workshop at http://angularcamp.org starting an Ionic 2 app! @AngularCamp #AngularCamp";
    }

    share() {
        this.platform.ready().then(() => {
            SocialSharing.share(this.shareMsg, null, null, null);
        });
    };

    shareViaTwitter() {
        this.platform.ready().then(() => {
            if (SocialSharing.canShareVia("twitter")) {
                SocialSharing.shareViaTwitter(this.shareMsg, null, null);
            }
        });
    };

    shareViaFacebook() {
        this.platform.ready().then(() => {
            if (SocialSharing.canShareVia("facebook")) {
                SocialSharing.shareViaFacebookWithPasteMessageHint(this.shareMsg, null, null, 'Paste your facebook comment!');
            }
        });
    };
}


text:
package org.apache.druid.k8s.overlord.common;

import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;

public class DruidKubernetesClient implements KubernetesClientApi
{

  private final Config config;

  public DruidKubernetesClient()
  {
    this(Config.autoConfigure(null));
  }

  public DruidKubernetesClient(Config config)
  {
    this.config = config;
  }

  @Override
  public <T> T executeRequest(KubernetesExecutor<T> executor) throws KubernetesResourceNotFoundException
  {
    try (KubernetesClient client = new DefaultKubernetesClient(config)) {
      return executor.executeRequest(client);
    }
  }
}