@staticmethod
def arange(start=None, stop=None, step=None, incl_start=True, incl_stop=False):
    """ Simulates ``numpy.arange()``.

        In contrast to ``numpy.arange()`` this function does not allow ``dtype`` specification.
        See `numpy.arange docs <http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.arange.html>`_

        Parameters
        ----------
        start : number, optional
            starting value of the interval. default is 0
        stop : number
            end of interval
        step : number, optional
            step size. default is 1. If step is specified, start must be given.
            Must be negative, if ``start > stop``
        incl_stop : bool
            If ``False``, starting number is excluded.
        incl_stop : bool
            If ``False`` stopping number is excluded (like ``numpy.arange`` does).
            If ``True`` stopping number is included in sequence.

        Returns
        -------
        tuple[float,...]
            tuple of floats (or int) values from ``start`` to ``stop`` incremented by ``step``.

        Examples
        --------
        >>> from numpy import arange
        >>> (Util.arange(1, 5, 1), arange(1, 5, 1))
        ((1, 2, 3, 4), array([1, 2, 3, 4]))
        >>> (Util.arange(1, 5), arange(1, 5))
        ((1, 2, 3, 4), array([1, 2, 3, 4]))
        >>> (Util.arange(5, 1), arange(5, 1))  # note different behavior. np.arange requires step.
        ((5, 4, 3, 2), array([], dtype=int32))
        >>> (Util.arange(5), arange(5))
        ((0, 1, 2, 3, 4), array([0, 1, 2, 3, 4]))
        >>> (Util.arange(5, 1, -1), arange(5, 1, -1))
        ((5, 4, 3, 2), array([5, 4, 3, 2]))
        >>> (Util.arange(5, 1, 1), arange(5, 1, 1))
        ((), array([], dtype=int32))

        >>> from numpy import arange
        >>> start = 2; stop=5.3; step=.8
        >>> seq = Util.arange(start, stop, step);
        >>> npseq = arange(start, stop, step);
        >>> [i - j for i,j in zip(seq, seq)]   # differences between sequence elements
        [0, 0.0, 0.0, 0.0, 0.0]

        The difference below shows an increasing rounding error,
        (but this can also be raising from `numpy`)

        >>> start = 21.1; stop=10.3; step=-5/3
        >>> [i - j for i,j in zip(arange(start, stop, step), tuple(Util.arange(start, stop, step)))]
        [0.0, 0.0, 0.0, 0.0, -1.7763568394002505e-15, -3.5527136788005009e-15, -5.3290705182007514e-15]
        """
    if stop is None:
        stop = start
        start = 0
    if start is None:
        start = 0
    if step is None:
        step = (start < stop) * 2 - 1
    if start < stop and step < 0 or start > stop and step > 0:
        seq = ()
    else:
        seq, next = (start,), start + step
        while next <= stop and start < stop or next >= stop and start > stop:
            seq += next,
            next = seq[len(seq) - 1] + step
        if not incl_stop and seq[len(seq) - 1] == stop:
            seq = seq[0:len(seq) - 1]
        if not incl_start and len(seq) > 0:
            seq = seq[1:len(seq)]
    return seq


def purge_stats():
    """Re-initialize objects activities resume

    """
    global STATS
    STATS = {u'objects': {}}


def text_content(context):
    """XPath Extension function to return a node text content."""
    return context.context_node.xpath('string()').strip()


def table_exists(table_name, connection, schema=None):
    """Returns `True` if a table exists in a database.

    Parameters
    ----------
    table_name : str
        The name of the table.
    connection : .PeeweeDatabaseConnection
        The Peewee database connection to use.
    schema : str
        The schema in which the table lives.

    """
    return connection.table_exists(table_name, schema=schema)


def _resource_property_keys(resource):
    """Returns a list of all get_param lookup keys for the given resource.

    :type resource: tuskar.templates.heat.Resource
    :return: list of property names; empty list if none are found
    :rtype: [str]
    """
    keys = []
    for rp in resource.properties:
        if rp.name in ('resource_def', 'resource'):
            for rpv in rp.value['properties'].values():
                if isinstance(rpv, dict) and 'get_param' in rpv:
                    keys.append(rpv['get_param'])
        elif isinstance(rp.value, dict) and 'get_param' in rp.value:
            keys.append(rp.value['get_param'])
    return keys


def resize_to(img, targ_sz: int, use_min: bool=False):
    """Size to resize to, to hit `targ_sz` at same aspect ratio, in PIL coords (i.e w*h)"""
    w, h = img.size
    min_sz = (min if use_min else max)(w, h)
    ratio = targ_sz / min_sz
    return int(w * ratio), int(h * ratio)


def ReducedElectricalField(E, p=101325, T=293.15):
    """Reduced electric field strength calculation using ideal gas law.

    Args:
        E       :   Electric field.
        p       :   Ambient pressure during discharge.
        T       :   Ambient temperature during discharge.

    Returns:
        Returns the reduced electric field strength.
    """
    kB = 1.3806485279e-23
    N = p / (kB * T)
    Td = E / N
    return Td / 1e-20


@classmethod
def has_resuming(cls):
    """Returns whether it supports to resume the fetch process.

        :returns: this backend supports items resuming
        """
    return True


def implementedBy(class_):
    """Return the interfaces implemented for a class' instances

        The value returned is an IDeclaration.
        """


def modifier_move_down(modifier: str=''):
    """Move modifier down in the stack

    :param modifier: Modifier, Name of the modifier to edit
    :type modifier: str
    """
    pass


def estimate_fst_freqs_wright(p1, p2):
    """
    calculate mean fst based on called frequencies
    """
    p = (p1 + p2) / 2.0
    is_het = (p > 0) & (p < 1)
    vp = ((p1 - p) ** 2 + (p2 - p) ** 2) / 2.0
    fsts = vp[is_het] / (p * (1 - p))[is_het]
    return fsts.mean()


@classmethod
def from_settings(cls, settings):
    """Create the unit statement from the FileSettings"""
    return cls(settings.units, settings.zeros)


def _add_alert_node(nx_graph, alert):
    """Add alert node to the graph."""
    nx_graph.add_node(alert['AlertType'] + '(R)', name=alert['AlertType'],
        time=str(alert['StartTimeUtc']), displayname=alert[
        'AlertDisplayName'], color='red', count=0, node_type='alert')


def modified(obj, evt):
    """ Invoke the touch method of this object that should update the columns:

    - modified
    - last_modifier
    """
    obj.touch()


@staticmethod
def concat(x, y):
    """
        Returns the first value that is not an Exception,
        else returns the last Exception.

        Arguments:
        x -- the first value
        y -- the second value
        """
    if not isinstance(x, Exception):
        return x
    else:
        return y


def num_fragmentations(df, obj_frequencies):
    """Total number of switches from tracked to not tracked."""
    fra = 0
    for o in obj_frequencies.index:
        dfo = df.noraw[df.noraw.OId == o]
        notmiss = dfo[dfo.Type != 'MISS']
        if len(notmiss) == 0:
            continue
        first = notmiss.index[0]
        last = notmiss.index[-1]
        diffs = dfo.loc[first:last].Type.apply(lambda x: 1 if x == 'MISS' else
            0).diff()
        fra += diffs[diffs == 1].count()
    return fra


def transpose_axes(image, axes, asaxes=None):
    """Return image with its axes permuted to match specified axes.

    A view is returned if possible.

    >>> transpose_axes(numpy.zeros((2, 3, 4, 5)), 'TYXC', asaxes='CTZYX').shape
    (5, 2, 1, 3, 4)

    """
    for ax in axes:
        if ax not in asaxes:
            raise ValueError(f'unknown axis {ax}')
    if asaxes is None:
        asaxes = 'CTZYX'
    shape = image.shape
    for ax in reversed(asaxes):
        if ax not in axes:
            axes = ax + axes
            shape = (1,) + shape
    image = image.reshape(shape)
    image = image.transpose([axes.index(ax) for ax in asaxes])
    return image


def split():
    """Split off selected bones from connected unselected bones

    """
    pass


@classmethod
def expected_string(cls, dialect=None, called_from=None):
    """Return the expected string for this segment."""
    return '!!TODO!!'


def coin_trig(peaks, stachans, samp_rate, moveout, min_trig, trig_int):
    """
    Find network coincidence triggers within peaks of detection statistics.

    Useful for finding network detections from sets of detections on individual
    stations.

    :type peaks: list
    :param peaks: List of lists of tuples of (peak, index) for each         station-channel.  Index should be in samples.
    :type stachans: list
    :param stachans: List of tuples of (station, channel) in the order of         peaks.
    :type samp_rate: float
    :param samp_rate: Sampling rate in Hz
    :type moveout: float
    :param moveout: Allowable network moveout in seconds.
    :type min_trig: int
    :param min_trig: Minimum station-channels required to declare a trigger.
    :type trig_int: float
    :param trig_int:
        Minimum allowable time between network triggers in seconds.

    :return:
        List of tuples of (peak, index), for the earliest detected station.
    :rtype: list

    >>> peaks = [[(0.5, 100), (0.3, 800)], [(0.4, 120), (0.7, 850)]]
    >>> triggers = coin_trig(peaks, [('a', 'Z'), ('b', 'Z')], 10, 3, 2, 1)
    >>> print(triggers)
    [(0.45, 100)]
    """
    triggers = []
    for stachan, _peaks in zip(stachans, peaks):
        for peak in _peaks:
            trigger = peak[1], peak[0], '.'.join(stachan)
            triggers.append(trigger)
    coincidence_triggers = []
    for i, master in enumerate(triggers):
        slaves = triggers[i + 1:]
        coincidence = 1
        trig_time = master[0]
        trig_val = master[1]
        for slave in slaves:
            if abs(slave[0] - master[0]) <= moveout * samp_rate and slave[2
                ] != master[2]:
                coincidence += 1
                if slave[0] < master[0]:
                    trig_time = slave[0]
                trig_val += slave[1]
        if coincidence >= min_trig:
            coincidence_triggers.append((trig_val / coincidence, trig_time))
    if coincidence_triggers:
        coincidence_triggers.sort(key=lambda tup: tup[0], reverse=True)
        output = [coincidence_triggers[0]]
        for coincidence_trigger in coincidence_triggers[1:]:
            add = True
            for peak in output:
                if abs(coincidence_trigger[1] - peak[1]
                    ) < trig_int * samp_rate:
                    add = False
                    break
            if add:
                output.append((coincidence_trigger[0], coincidence_trigger[1]))
        output.sort(key=lambda tup: tup[1])
        return output
    else:
        return []


def whitespace_normalize_name(name):
    """Return a whitespace-normalized name."""
    return ' '.join(name.split())


def substiSentence(morphs, poses, substi, only):
    """명사와 동사를 찾아 기호로 변환하고, 명사,동사,조사,어미만 붙여 연결한다"""
    noun_list = []
    verb_list = []
    nouns = ''
    verbs = ''
    morph_idx = 0
    noun_idx = 0
    verb_idx = 0
    if substi:
        for pos in poses:
            if pos == 'NNG' or pos == 'NNP':
                noun_list.append(morphs[morph_idx])
                morphs[morph_idx] = 'NOUN' + str(noun_idx)
                noun_idx += 1
            elif pos == 'VV' or pos == 'VA' or pos == 'VX' or pos == 'XR':
                verb_list.append(morphs[morph_idx])
                morphs[morph_idx] = 'VERB' + str(verb_idx)
                verb_idx += 1
            morph_idx += 1
    new_data = ''
    if only:
        pos_idx = 0
        for morph in morphs:
            if poses[pos_idx] == 'NNG' or poses[pos_idx] == 'NNP' or poses[
                pos_idx] == 'VV' or poses[pos_idx] == 'VA' or poses[pos_idx
                ] == 'VX' or poses[pos_idx] == 'XR' or poses[pos_idx
                ].startswith('J') or poses[pos_idx].startswith('E'):
                new_data += ' ' + morph + ' '
            pos_idx += 1
    else:
        for morph in morphs:
            new_data += ' ' + morph + ' '
    for noun_each in noun_list:
        nouns += noun_each + ','
    for verb_each in verb_list:
        verbs += verb_each + ','
    return new_data, nouns, verbs


def dec(digest, alphabet=
    '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÁÂÄÅÆÉÊËÍÎÏÐÑÓÔÖÚÛÜÝÞßáâäåæçéêëíîïðñóôöøúûüýþ'
    ):
    """
    Decode digest from base-len(alphabet).
    See enc() for more info.
    :param digest:
    :param alphabet:
    :return:
    """
    res = 0
    last = len(digest) - 1
    base = len(alphabet)
    for i, d in enumerate(digest):
        res += alphabet.index(d) * pow(base, last - i)
    return res


@classmethod
def get_drivers(cls):
    """Retrieves cluster drivers from python entry_points.

        Example:

        With the following classes:
        class Driver1(Driver):
            provides = [
                ('server_type1', 'os1', 'coe1')
            ]

        class Driver2(Driver):
            provides = [
                ('server_type2', 'os2', 'coe2')
            ]

        And the following entry_points:

        magnum.drivers =
            driver_name_1 = some.python.path:Driver1
            driver_name_2 = some.python.path:Driver2

        get_drivers will return:
            {
                (server_type1, os1, coe1):
                    {'driver_name_1': Driver1},
                (server_type2, os2, coe2):
                    {'driver_name_2': Driver2}
            }

        :return: dict
        """
    if not cls.definitions:
        cls.definitions = dict()
        for entry_point, def_class in cls.load_entry_points():
            for cluster_type in def_class().provides:
                cluster_type_tuple = cluster_type['server_type'], cluster_type[
                    'os'], cluster_type['coe']
                providers = cls.definitions.setdefault(cluster_type_tuple,
                    dict())
                providers['entry_point_name'] = entry_point.name
                providers['class'] = def_class
    return cls.definitions


def provider(*interfaces):
    """A class decorator version of classProvides"""


def associate_principal_with_portfolio(AcceptLanguage=None, PortfolioId=
    None, PrincipalARN=None, PrincipalType=None):
    """
    Associates the specified principal ARN with the specified portfolio.
    See also: AWS API Documentation

    :example: response = client.associate_principal_with_portfolio(
        AcceptLanguage='string',
        PortfolioId='string',
        PrincipalARN='string',
        PrincipalType='IAM'
    )

    :type AcceptLanguage: string
    :param AcceptLanguage: The language code to use for this operation. Supported language codes are as follows:
            'en' (English)
            'jp' (Japanese)
            'zh' (Chinese)
            If no code is specified, 'en' is used as the default.

    :type PortfolioId: string
    :param PortfolioId: [REQUIRED]
            The portfolio identifier.

    :type PrincipalARN: string
    :param PrincipalARN: [REQUIRED]
            The ARN representing the principal (IAM user, role, or group).

    :type PrincipalType: string
    :param PrincipalType: [REQUIRED]
            The principal type. Must be IAM

    :rtype: dict
    :return: {}

    :returns:
    (dict) --

    """
    pass


@classmethod
def get_raw_land(cls, index):
    """
            Must be used internally by UOFiddler?
        :return: bytes --
        """
    index &= 16383
    stream, length, extra, patched = cls._file_index(index)
    if not stream:
        return None
    return stream.read(length)


def _constraint_lb_and_ub_to_cplex_sense_rhs_and_range_value(lb, ub):
    """Helper function used by Constraint and Model"""
    if lb is None and ub is None:
        raise Exception('Free constraint ...')
    elif lb is None:
        sense = 'L'
        rhs = float(ub)
        range_value = 0.0
    elif ub is None:
        sense = 'G'
        rhs = float(lb)
        range_value = 0.0
    elif lb == ub:
        sense = 'E'
        rhs = float(lb)
        range_value = 0.0
    elif lb > ub:
        raise ValueError('Lower bound is larger than upper bound.')
    else:
        sense = 'R'
        rhs = float(lb)
        range_value = float(ub - lb)
    return sense, rhs, range_value


def limit_sub_bbox(bbox, sub_bbox):
    """
    >>> limit_sub_bbox((0, 1, 10, 11), (-1, -1, 9, 8))
    (0, 1, 9, 8)
    >>> limit_sub_bbox((0, 0, 10, 10), (5, 2, 18, 18))
    (5, 2, 10, 10)
    """
    minx = max(bbox[0], sub_bbox[0])
    miny = max(bbox[1], sub_bbox[1])
    maxx = min(bbox[2], sub_bbox[2])
    maxy = min(bbox[3], sub_bbox[3])
    return minx, miny, maxx, maxy


@staticmethod
def get_value(entry, val, number=False):
    """Retrieve the desired value from the parsed response dictionary."""
    if val in entry.keys():
        return entry[val]
    else:
        return 0 if number else ''


@classmethod
def from_class(cls, target_class):
    """Create a FunctionDescriptor from a class.

        Args:
            cls: Current class which is required argument for classmethod.
            target_class: the python class used to create the function
                descriptor.

        Returns:
            The FunctionDescriptor instance created according to the class.
        """
    module_name = target_class.__module__
    class_name = target_class.__name__
    return cls(module_name, '__init__', class_name)


def increase_flux(reaction, ref_value, value):
    """
    lb                           0                           ub
    |--------------------------- ' ---------------------------|
                <- - -|----------'
                                 '----------|- - - ->

    Parameters
    ----------
    reaction: cobra.Reaction
        The reaction to over-express.
    ref_value: float
        The flux value to come from.
    value: float
        The flux value to achieve.

    """
    if abs(value) < abs(ref_value):
        raise ValueError(
            "'value' is lower than 'ref_value', this is increase_flux (%f < %f)"
             % (value, ref_value))
    if value > 0:
        reaction.lower_bound = value
    elif value < 0:
        reaction.upper_bound = value
    else:
        reaction.knock_out()


def _cost_enumerative(u, prm, fol):
    """Compute cost of cover `u` by enumerating it."""
    if u is None:
        return float('inf')
    eq = prm.eq
    cover = list()
    params = prm.p_vars
    for p in fol.pick_iter(u, params):
        r = fol.false
        for w in cover:
            w.update(p)
            r = fol.let(w, eq)
            if r == fol.true:
                break
        if r == fol.true:
            continue
        cover.append(p)
    n = len(cover)
    print('enumerative cost: {n}'.format(n=n))
    count = fol.count(u)
    assert n <= count, (n, count)
    if n < count:
        print('Cost(u) < fol.count(u)')
    return n


@classmethod
def unverified(cls, val):
    """
        Create an instance of this class set to the ``unverified`` tag with
        value ``val``.

        :param UserSelectorArg val:
        :rtype: UserAddResult
        """
    return cls('unverified', val)


def row2dict(columns, row):
    """Convert rows to dictionaries with column keys from description"""
    robj = {}
    for k, v in zip(columns, row):
        robj.setdefault(k, v)
    return robj


def get_c_pointers(concentrations, constants, propensity_ints, reaction_arr,
    catalyst_arr):
    """This function returns the C pointers to the input arrays. Pointers must be pasted to SSA library functions

	Arguments:
		- concentrations: array of doubles containing molecule abundances
		- constants: array of np doubles containing reaction constants
		- propensity_ints: array of np int32 containing propesity integer codes
		- reaction_arr: np int32 array with integers indicating the stochimetry of each reaction.
			Each row is a reaction, each column is a molecule. Reactants are negative, products are postive
		- catalyst_arr: np double array with the effect of each molecule for each reaction.
			Rows are reactions, columns are molecule, non-zero value indicate catalysis
	Return:
	 	- concentrations_ptr: points to concentration array
	 	- constants_ptr: points to constants array
	 	- propensity_ints_ptr: points to propensity_ints array
	 	- reaction_arr_ptr: points to reaction_arr array
	 	- catalyst_arr_ptr: points to catalyst_arr
	"""
    from ctypes import c_int, c_double, POINTER
    concentrations_ptr = concentrations.ctypes.data_as(POINTER(c_double))
    constants_ptr = constants.ctypes.data_as(POINTER(c_double))
    propensity_ints_ptr = propensity_ints.ctypes.data_as(POINTER(c_int))
    reaction_arr_ptr = reaction_arr.ctypes.data_as(POINTER(c_int))
    catalyst_arr_ptr = catalyst_arr.ctypes.data_as(POINTER(c_double))
    return (concentrations_ptr, constants_ptr, propensity_ints_ptr,
        reaction_arr_ptr, catalyst_arr_ptr)


def reset_connection(conn) ->object:
    """
    Resets the connection to Tableau Server by signing out and signing in again.
    :param class conn: the Tableau Server connection to reset
    :return: TableauServerConnection
    """
    conn.sign_out()
    conn.sign_in()
    return conn


def all_sprites(state):
    """
    Returns a list of sprites in the state
    """
    json_data = state.data.get('json')
    sprites = []
    if json_data != None:
        for child in json_data.get('children'):
            if 'spriteInfo' in child:
                sprites.append(child)
    return sprites


def ensure_one(found):
    """
    确保列表中仅有一个项，并返回这个项，否则抛出 `ValueError` 异常

    通常可用在查找聊天对象时，确保查找结果的唯一性，并直接获取唯一项

    :param found: 列表
    :return: 唯一项
    """
    if not isinstance(found, list):
        raise TypeError('expected list, {} found'.format(type(found)))
    elif not found:
        raise ValueError('not found')
    elif len(found) > 1:
        raise ValueError('more than one found: {}'.format(found))
    else:
        return found[0]


def rgba(red, green, blue, alpha):
    """
  RGBA color values are an extension of RGB color values with an alpha channel - which specifies the opacity of the object.

  An RGBA color is specified with the rgba() function, which has the following syntax:
  rgba(red, green, blue, alpha)
  The alpha parameter is a number between 0.0 (fully transparent) and 1.0 (fully opaque).

  https://www.w3schools.com/cssref/css_colors_legal.asp

  :param red:
  :param green:
  :param blue:
  :param alpha:
  :return:
  """
    return 'rgba(%s, %s, %s, %s)' % (red, green, blue, alpha)


def render_pep440_old(pieces):
    """TAG[.postDISTANCE[.dev0]] .

    The ".dev0" means dirty.

    Eexceptions:
    1: no tags. 0.postDISTANCE[.dev0]
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance'] or pieces['dirty']:
            rendered += '.post%d' % pieces['distance']
            if pieces['dirty']:
                rendered += '.dev0'
    else:
        rendered = '0.post%d' % pieces['distance']
        if pieces['dirty']:
            rendered += '.dev0'
    return rendered


def find_max_occurence(profile, max_count=2):
    """
    Return profile with base corresponding to max scores[CHECK!]
    """
    sorted_profile = []
    for p in profile:
        sorted_profile.append(sorted(list(p.items()), key=lambda x: x[1]))
    for i, p in enumerate(sorted_profile):
        sorted_profile[i] = p[-max_count:]
    return sorted_profile


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


def init(config):
    """Daemon initialization function. This is run after daemon configuration is
    applied. In other words, facilities like logging, database connections etc.
    all work at this point.
    """
    from garage.application import start_garage
    return [('garage', start_garage)]


def validate(d, key, validator):
    """
    Validate a single value in ``d`` using a formencode validator.

    Example::

        email = validate(request.params, 'email', validators.Email(not_empty=True))
    """
    return validator.to_python(d.get(key))


def interpolate(profile, x):
    """Interpolate y given x and a [(x: int, y: int), ...] profile.

  Requires the profile to be sorted by x, with no duplicate x values (see
  normalize).  Expects profiles with integer x and y values, and
  returns duty rounded to the nearest integer.

  >>> interpolate([(20, 50), (50, 70), (60, 100)], 33)
  59
  >>> interpolate([(20, 50), (50, 70)], 19)
  50
  >>> interpolate([(20, 50), (50, 70)], 51)
  70
  >>> interpolate([(20, 50)], 20)
  50
  """
    lower, upper = profile[0], profile[-1]
    for step in profile:
        if step[0] <= x:
            lower = step
        if step[0] >= x:
            upper = step
            break
    if lower[0] == upper[0]:
        return lower[1]
    return round(lower[1] + (x - lower[0]) / (upper[0] - lower[0]) * (upper
        [1] - lower[1]))


def _LDRSW_literal(cpu, reg_op, imm_op):
    """
        LDRSW (literal).

        :param reg_op: destination register.
        :param imm_op: immediate.
        """
    cpu._ldr_literal(reg_op, imm_op, size=32, sextend=True)


def reduceby(iterable, keyfunc, reducefunc, init):
    """Combination of ``itertools.groupby()`` and  ``reduce()``.

    This generator iterates over the iterable. The values are reduced using
    ``reducefunc`` and ``init`` as long as ``keyfunc(item)`` returns the same
    value.

    A possible use case would be to aggregate website visits and to group them
    by month. The corresponding SQL statement would be::

        SELECT SUM(visit_count) FROM visits GROUP BY month;

    Example::

        >>> keyfunc = lambda x: x % 2 == 0
        >>> reducefunc = lambda x, y: x + y
        >>> values = [1, 3, 5, 6, 8, 11]
        >>> groups = utils.reduceby(values, keyfunc, reducefunc, 0)
        >>> groups
        <generator object reduceby at 0xedc5a0>
        >>> list(groups)
        [9, 14, 11]

    :param iterable: An iterable to reduce. The iterable should be presorted.
    :param keyfunc: A key function. It should return the same value for all
        items belonging to the same group.
    :param reducefunc: The reduce function.
    :param init: The initial value for the reduction.
    :returns: A generator returning the reduced groups.
    :rtype: generator

    """
    first = True
    oldkey = None
    accum_value = init
    for i in iter(iterable):
        key = keyfunc(i)
        if first:
            oldkey = key
            first = False
        elif key != oldkey:
            yield accum_value
            accum_value = init
            oldkey = key
        accum_value = reducefunc(accum_value, i)
    yield accum_value


def registerList(ml):
    """Registers a mailing list so that it may be looked up by mail-to
           address.  Will raise a UserError if the address or mailing list
           is already registered."""


def get_bulk_modulus(cryst):
    """Calculate bulk modulus using the Birch-Murnaghan equation of state.

    The EOS must be previously calculated by get_BM_EOS routine.
    The returned bulk modulus is a :math:`B_0` coefficient of the B-M EOS.
    The units of the result are defined by ASE. To get the result in
    any particular units (e.g. GPa) you need to divide it by
    ase.units.<unit name>::

        get_bulk_modulus(cryst)/ase.units.GPa

    :param cryst: ASE Atoms object

    :returns: float, bulk modulus :math:`B_0` in ASE units.
    """
    if getattr(cryst, 'bm_eos', None) is None:
        raise RuntimeError('Missing B-M EOS data.')
    cryst.bulk_modulus = cryst.bm_eos[1]
    return cryst.bulk_modulus


@staticmethod
def _flag_what_changed(note, what_changed):
    """Flag a note field as changed"""
    if 'what_changed' not in note:
        note['what_changed'] = []
    if what_changed not in note['what_changed']:
        note['what_changed'].append(what_changed)


def convertbits(data, frombits, tobits, pad=True):
    """General power-of-2 base conversion."""
    acc = 0
    bits = 0
    ret = []
    maxv = (1 << tobits) - 1
    max_acc = (1 << frombits + tobits - 1) - 1
    for value in data:
        if value < 0 or value >> frombits:
            return None
        acc = (acc << frombits | value) & max_acc
        bits += frombits
        while bits >= tobits:
            bits -= tobits
            ret.append(acc >> bits & maxv)
    if pad:
        if bits:
            ret.append(acc << tobits - bits & maxv)
    elif bits >= frombits or acc << tobits - bits & maxv:
        return None
    return ret


def patch_click() ->None:
    """Make Click not crash.

    On certain misconfigured environments, Python 3 selects the ASCII encoding as the
    default which restricts paths that it can access during the lifetime of the
    application.  Click refuses to work in this scenario by raising a RuntimeError.

    In case of Black the likelihood that non-ASCII characters are going to be used in
    file paths is minimal since it's Python source code.  Moreover, this crash was
    spurious on Python 3.7 thanks to PEP 538 and PEP 540.
    """
    try:
        from click import core
        from click import _unicodefun
    except ModuleNotFoundError:
        return
    for module in (core, _unicodefun):
        if hasattr(module, '_verify_python3_env'):
            module._verify_python3_env = lambda : None


def _drop_duplicate_labels(a_labels, b_labels):
    """Combine lists `a_labels` and `b_labels` into a new list, dropping any duplicates."""
    a_labels = list(a_labels)
    b_labels = list(b_labels)
    for i, lbl in enumerate(a_labels):
        if lbl in b_labels:
            j = b_labels.index(lbl)
            a_labels[i] = None
            b_labels[j] = None
    a_labels.extend(b_labels)
    return a_labels


@staticmethod
def rgb_to_ansi(color):
    """
        Converts hex RGB to the 6x6x6 xterm color space

        Args:
            color (str): RGB color string in the format "#RRGGBB"

        Returns:
            str: ansi color string in the format "ansi_n", where n
                is between 16 and 230

        Reference:
            https://github.com/chadj2/bash-ui/blob/master/COLORS.md
        """
    if color[0] != '#' or len(color) != 7:
        return None
    try:
        r = round(int(color[1:3], 16) / 51.0)
        g = round(int(color[3:5], 16) / 51.0)
        b = round(int(color[5:7], 16) / 51.0)
        n = int(36 * r + 6 * g + b + 16)
        return 'ansi_{0:d}'.format(n)
    except ValueError:
        return None


def is_valid_iob(tags, version='IOB2'):
    """Judge whether `tags' is a valid IOB string.

    Parameters
    ----------
    tags: list
        List of tags.

    version: str
        The IOB version of the tags, should be one of ["IOB1", "IOB2"].

    Returns
    -------
    is_valid: boolean
        True if `tags' is in valid IOB format, otherwise False.

    """
    for i, tag in enumerate(tags):
        if tag == 'O':
            continue
        fields = tag.split('-')
        if len(fields) != 2 or fields[0] not in ['B', 'I']:
            return False
        pos, tag_name = fields
        if i == 0 or tags[i - 1].split('-') not in [['I', tag_name], ['B',
            tag_name]]:
            if version == 'IOB1' and pos == 'B':
                return False
            if version == 'IOB2' and pos == 'I':
                return False
    return True


def bytes_to_text(s, encoding):
    """
    Convert bytes objects to strings, using the given encoding. Illegally
    encoded input characters are replaced with Unicode "unknown" codepoint
    (�).

    Return any non-bytes objects without change.
    """
    if isinstance(s, bytes):
        return str(s, encoding, 'replace')
    else:
        return s


def render_git_describe(pieces):
    """TAG[-DISTANCE-gHEX][-dirty].

    Like 'git describe --tags --dirty --always'.

    Exceptions:
    1: no tags. HEX[-dirty]  (note: no 'g' prefix)
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '-%d-g%s' % (pieces['distance'], pieces['short'])
    else:
        rendered = pieces['short']
    if pieces['dirty']:
        rendered += '-dirty'
    return rendered


def __iter__():
    """Iterate over each persistent object in the ring, in the order of least
        recently used to most recently used.

        Mutating the ring while an iteration is in progress has
        undefined consequences.
        """


def get_cigar(var):
    """
    Return the cigar string describing how to align an
    alternate allele to the reference allele
    """
    return var.INFO.get('CIGAR')


@staticmethod
def split_version(version):
    """
        Takes a given string of a version (ie "1.2.3") and
        splits it into a list ([1, 2, 3]).

        :param version: The version string to convert.
        :type version: str
        :return: A list with the string representation.
        :rtype: list[int]
        """
    return map(lambda x: int(x) if x is not '' else 0, version.split('.'))


def find_tag(info_list, tag):
    """
        Iterates through info objects to find specific tag.
        Returns list of matching values.
    """
    tag_data = []
    for info in info_list:
        try:
            tag_data.append(info[tag])
        except KeyError:
            pass
    return tag_data


@staticmethod
def concat_url(endpoint, url):
    """Concatenate endpoint and final URL.

        E.g., "http://keystone/v2.0/" and "/tokens" are concatenated to
        "http://keystone/v2.0/tokens".

        :param endpoint: the base URL
        :param url: the final URL
        """
    return '%s/%s' % (endpoint.rstrip('/'), url.strip('/'))


def chkmrk(options, chosen):
    """
    Check if all options are chosen or not.
    """
    for o in options:
        if chosen[options.index(o)] == '   ':
            return False
    return True


def _register_instance(cls, instance):
    """
        registers the given instance.
        """
    cls._instances[str(cls)] = instance


def print_border(size, msg=''):
    """ Print a simple border

    :param size:
    :param msg:

    """
    for i in range(0, size):
        print('=', end='')
    print(msg, end='')
    print('')


def _cli_find_file(cli):
    u"""list file names matching regular expression

    To find e.g. all '.py' files in current folder use::

        fspath find ".*\\.py$"  .
    """
    for match in cli.folder.reMatchFind(cli.regexpr, use_dirs=not cli.
        nodirs, use_files=not cli.nofiles):
        cli.OUT.write(match + '\n')


@staticmethod
def set_update(keys, values):
    """
        Creates an update query to update a list of keys with a set of values.
        :param keys: a list of string keys or a single string key to update.
        :param values: a list of values or a single value to update. The values will be matched to keys by index.
        :return: a dictionary containing proper/valid update statement for MongoDB.
        """
    set_update = {'$set': {}}
    if isinstance(keys, str):
        set_update['$set'][keys] = values
    elif isinstance(keys, list):
        for index, key in enumerate(keys):
            set_update['$set'][key] = values[index]
    return set_update


def _join_list(lst, oxford=True):
    """Join a list of words in a gramatically correct way."""
    if len(lst) > 2:
        s = ', '.join(lst[:-1])
        if oxford:
            s += ','
        s += ' and ' + lst[-1]
    elif len(lst) == 2:
        s = lst[0] + ' and ' + lst[1]
    elif len(lst) == 1:
        s = lst[0]
    else:
        s = ''
    return s


def signed8(x):
    """ convert to signed 8-bit """
    if x > 127:
        x = x - 256
    return x


@staticmethod
def _archive_for_zip_module(module):
    """Return the archive filename for the module if relevant."""
    try:
        return module.__loader__.archive
    except AttributeError:
        pass


def plot_format(df):
    """Function to reformat plots"""
    df.xaxis.axis_label_text_font = 'times'
    df.yaxis.axis_label_text_font = 'times'
    df.xaxis.major_label_text_font_size = '14pt'
    df.yaxis.major_label_text_font_size = '14pt'
    df.xaxis.axis_label_text_font_size = '14pt'
    df.yaxis.axis_label_text_font_size = '14pt'
    df.xaxis.major_label_text_font = 'times'
    df.yaxis.major_label_text_font = 'times'
    df.xaxis.axis_label_text_font_style = 'bold'
    df.yaxis.axis_label_text_font_style = 'bold'


def asquote(astr):
    """Return the AppleScript equivalent of the given string."""
    astr = astr.replace('"', '" & quote & "')
    return '"{}"'.format(astr)


def scan_setup_py():
    """Validate the contents of setup.py against Versioneer's expectations."""
    found = set()
    setters = False
    errors = 0
    with open('setup.py', 'r') as f:
        for line in f.readlines():
            if 'import versioneer' in line:
                found.add('import')
            if 'versioneer.get_cmdclass()' in line:
                found.add('cmdclass')
            if 'versioneer.get_version()' in line:
                found.add('get_version')
            if 'versioneer.VCS' in line:
                setters = True
            if 'versioneer.versionfile_source' in line:
                setters = True
    if len(found) != 3:
        print('')
        print('Your setup.py appears to be missing some important items')
        print('(but I might be wrong). Please make sure it has something')
        print('roughly like the following:')
        print('')
        print(' import versioneer')
        print(' setup( version=versioneer.get_version(),')
        print('        cmdclass=versioneer.get_cmdclass(),  ...)')
        print('')
        errors += 1
    if setters:
        print("You should remove lines like 'versioneer.VCS = ' and")
        print("'versioneer.versionfile_source = ' . This configuration")
        print('now lives in setup.cfg, and should be removed from setup.py')
        print('')
        errors += 1
    return errors


def sliceDefaults(theSl):
    """Returns a new slice with start=None as 0 and step=None as 1."""
    return slice(theSl.start or 0, theSl.stop, theSl.step or 1)


def get_segments(tokens, max_seq_len):
    """Segments: 0 for the first sequence, 1 for the second"""
    if len(tokens) > max_seq_len:
        raise IndexError('Token length more than max seq length!')
    segments = []
    current_segment_id = 0
    for token in tokens:
        segments.append(current_segment_id)
        if token == '[SEP]':
            current_segment_id = 1
    return segments + [0] * (max_seq_len - len(tokens))


def FoP_initialisation(S, source):
    """
    'L' initialisation for FoP

    :param source:
    :return:
    """
    L, R = {}, {}
    L[source[1]] = source[0]
    R[source[1]] = source[0]
    return L, R


@classmethod
def _strip_unpinned_and_editables(cls, cache):
    """
        Strip out unpinned and editable deps from given dep cache map.
        """
    stripped = type(cache)()
    for name, dep_map in cache.items():
        stripped_dep_map = type(dep_map)()
        for version, deps in dep_map.items():
            if ':UNPINNED:' not in version and ':EDITABLE:' not in version:
                stripped_dep_map[version] = deps
        stripped[name] = stripped_dep_map
    return stripped


def get_doc():
    """Get documentation of this resource

    :return: rst string
    :rtype: str
    """
    return """
    The ``actionacknowledge`` contains the acknowledgement requested and processed.

    To acknowledge an host/service problem the client post on this endpoint to create a new
    acknowledge request that will be managed by the Alignak backend Broker module to build an
    external command notified to the Alignak framework.

    **Note** that the Alignak Web Services module allow to use more external commands.
    """


def remove_tags_from_resource(ResourceARN=None, TagKeys=None):
    """
    Removes one or more tags from the specified resource. This operation is only supported in the cached volume, stored volume and tape gateway architectures.
    See also: AWS API Documentation

    Examples
    Lists the iSCSI stored volumes of a gateway. Removes one or more tags from the specified resource.
    Expected Output:

    :example: response = client.remove_tags_from_resource(
        ResourceARN='string',
        TagKeys=[
            'string',
        ]
    )

    :type ResourceARN: string
    :param ResourceARN: [REQUIRED]
            The Amazon Resource Name (ARN) of the resource you want to remove the tags from.

    :type TagKeys: list
    :param TagKeys: [REQUIRED]
            The keys of the tags you want to remove from the specified resource. A tag is composed of a key/value pair.
            (string) --

    :rtype: dict
    :return: {
        'ResourceARN': 'string'
    }

    """
    pass


def _append_value(data, value_to_append, isdif):
    """
    Helper function for _finish_value: actual data push happens
    here based on isdif flag (direct value or difference from prev)
    """
    if isdif:
        data.append(data[-1] + value_to_append)
    else:
        data.append(value_to_append)


def read_profile(profile_filename):
    """
    Reads profile file from disk.

    Profile is a normal Python source file, that must define a function named
    `profile`. Function must take the following parameters:

    * `font`
    * `color`
    * `size`
    * `bold`
    * `italic`

    and return an instance of `odt2md.emphasis.MarkdownStyle`.
    """
    g = {}
    with open(profile_filename) as f:
        exec(f.read(), g)
    if 'profile' not in g:
        raise ValueError(
            f'profile {profile_filename} is expected to define a function named "profile"'
            )
    if not callable(g['profile']):
        raise ValueError(
            f'name "profile" in {profile_filename} must be a function')
    return g['profile']


@classmethod
def GetHasher(cls, hasher_name):
    """Retrieves an instance of a specific hasher.

    Args:
      hasher_name (str): the name of the hasher to retrieve.

    Returns:
      BaseHasher: hasher.

    Raises:
      KeyError: if hasher class is not set for the corresponding name.
    """
    hasher_name = hasher_name.lower()
    if hasher_name not in cls._hasher_classes:
        raise KeyError('hasher class not set for name: {0:s}.'.format(
            hasher_name))
    hasher_class = cls._hasher_classes[hasher_name]
    return hasher_class()


def _dataset_pre_0_3(client):
    """Return paths of dataset metadata for pre 0.3.4."""
    project_is_pre_0_3 = int(client.project.version) < 2
    if project_is_pre_0_3:
        return (client.path / 'data').rglob(client.METADATA)
    return []


def get_alias(infos):
    """Get aliases of all parameters.

    Parameters
    ----------
    infos : list
        Content of the config header file.

    Returns
    -------
    pairs : list
        List of tuples (param alias, param name).
    """
    pairs = []
    for x in infos:
        for y in x:
            if 'alias' in y:
                name = y['name'][0]
                alias = y['alias'][0].split(',')
                for name2 in alias:
                    pairs.append((name2.strip(), name))
    return pairs


def intervalSimulate(interval):
    """ Sequence of commands to simulate network """
    from .. import sim
    sim.runSimWithIntervalFunc(interval, sim.intervalSave)
    sim.fileGather()


def read_lines(file, predicate=None, encoding=None, errors=None):
    """Read and return the content of the file as a list of lines.

    Line breaks are not included in the resulting list.

    If ``predicate`` is given, it must be a callable that takes a single
    line as its argument and returns a bool. Only the lines for which
    ``True`` is returned are included in the result.

    :param file: path to file or file descriptor
    :type file: :term:`path-like object` or int
    :param predicate: predicate function
    :type predicate: callable(str)
    :param str encoding: name of the encoding
    :param str errors: error handler
    :return: list of lines
    :rtype: list(str)
    :raises OSError: on I/O failure

    .. versionchanged:: 0.6.0
       Add parameter ``errors``
    """
    result = []
    with open(file, encoding=encoding, errors=errors) as fh:
        for line in fh:
            line = line.rstrip('\n')
            if not predicate or predicate(line):
                result.append(line)
    return result


def _check_patch(i, dileft, diright, dim):
    """Check if i is too close to interval endpoints and adjust if so."""
    if i <= dileft:
        ans = dileft
    elif dim - i <= diright:
        ans = dim - diright
    else:
        ans = i
    return ans


def delete():
    """Delete the active workspace

    """
    pass


def provider_validator(request, **kwargs):
    """
    This validator verifies that the validator in URL (eg. /openid/auth0/login)
    is a configured OpenIDConnect policy.
    """
    provider = request.matchdict['provider']
    used = request.registry.settings.get('multiauth.policy.%s.use' %
        provider, '')
    if not used.endswith('OpenIDConnectPolicy'):
        request.errors.add('path', 'provider', 'Unknow provider %r' % provider)


def provider_parser(subparser):
    """Configure provider parser for Conoha"""
    subparser.add_argument('--auth-region', help=
        'specify region. If empty, region `tyo1` will be used.')
    subparser.add_argument('--auth-token', help=
        'specify token for authentication. If empty, the username and password will be used to create a token.'
        )
    subparser.add_argument('--auth-username', help=
        'specify api username for authentication. Only used if --auth-token is empty.'
        )
    subparser.add_argument('--auth-password', help=
        'specify api user password for authentication. Only used if --auth-token is empty.'
        )
    subparser.add_argument('--auth-tenant-id', help=
        'specify tenand id for authentication. Only used if --auth-token is empty.'
        )


@classmethod
def _urlize_accession(cls, accession):
    """Return an URL version of `accession`.

        Arguments:
            accession (str): an ontology accession (e.g. *MS:1000031*), from
                one of the following ontologies: **MS**, **UO**, or **IMS**.

        """
    try:
        namespace, id_ = accession.split(':', 1)
        if namespace in {'MS', 'UO'}:
            url = 'http://purl.obolibrary.org/obo/{}_{}'
        elif namespace == 'IMS':
            url = 'http://www.maldi-msi.org/download/imzml/imagingMS.obo#{}:{}'
        else:
            url = '{}:{}'
        return url.format(namespace, id_)
    except ValueError:
        return accession


def _nval(val):
    """convert value to byte array"""
    if val < 0:
        raise ValueError
    buf = b''
    while val >> 7:
        m = val & 255 | 128
        buf += m.to_bytes(1, 'big')
        val >>= 7
    buf += val.to_bytes(1, 'big')
    return buf


@classmethod
def replace_expression(cls, node, fake_tree, insert_point):
    """
        Inserts `node` as a new like with a fake path reference.
        Then, replaces the first child of the insert_point
        with this path reference.
        """
    line = insert_point.line()
    child_node = None
    if node.service is not None:
        child_node = node.service
    elif node.call_expression is not None:
        assert node.call_expression is not None
        child_node = node.call_expression
    else:
        assert node.mutation is not None
        child_node = node.mutation
    fake_path = fake_tree.add_assignment(child_node, original_line=line)
    insert_point.replace(0, fake_path.child(0))


def reverse_lookup(d, value):
    """Return first key found with given value.

    Raise ValueError exception if no matches found.
    """
    for k, v in d.iteritems():
        if v == value:
            return k


def getUserNames():
    """
        Return a list of usernames
        """


def is_inst_calibrated_to_container(instrument, container):
    """
    Returns True if instrument holds calibration data for a Container
    """
    slot = container.get_parent().get_name()
    label = container.get_name()
    data = instrument.calibration_data
    if slot in data:
        if label in data[slot].get('children'):
            return True
    return False


def normalize_bbox(coords, ymax, scaler=2):
    """
    scales all coordinates and flip y axis due to different
    origin coordinates (top left vs. bottom left)
    """
    return [coords[0] * scaler, ymax - coords[3] * scaler, coords[2] *
        scaler, ymax - coords[1] * scaler]


def row_idx_from_mat_coords(n: int, i: int, j: int) ->int:
    """Vector index corresponding to the matrix upper triangle coordinates."""
    if i <= j:
        return int(i * n - (i - 1) * i / 2 + j - i)
    else:
        return int(j * n - (j - 1) * j / 2 + i - j)


def abort_environment_update(EnvironmentId=None, EnvironmentName=None):
    """
    Cancels in-progress environment configuration update or application version deployment.
    See also: AWS API Documentation

    Examples
    The following code aborts a running application version deployment for an environment named my-env:
    Expected Output:

    :example: response = client.abort_environment_update(
        EnvironmentId='string',
        EnvironmentName='string'
    )

    :type EnvironmentId: string
    :param EnvironmentId: This specifies the ID of the environment with the in-progress update that you want to cancel.

    :type EnvironmentName: string
    :param EnvironmentName: This specifies the name of the environment with the in-progress update that you want to cancel.

    :return: response = client.abort_environment_update(
        EnvironmentName='my-env',
    )

    print(response)

    """
    pass


@classmethod
def decode_ssh_public(cls, packet):
    """Decode an SSH format DSA public key"""
    p = packet.get_mpint()
    q = packet.get_mpint()
    g = packet.get_mpint()
    y = packet.get_mpint()
    return p, q, g, y


@classmethod
def from_argparse(cls, opts):
    """
        Initialize an instance of the ethincaParameters class from an
        argparse.OptionParser instance. This assumes that
        insert_ethinca_metric_options
        and
        verify_ethinca_metric_options
        have already been called before initializing the class.
        """
    return cls(opts.ethinca_pn_order, opts.filter_cutoff, opts.
        ethinca_frequency_step, fLow=None, full_ethinca=opts.
        calculate_ethinca_metric, time_ethinca=opts.
        calculate_time_metric_components)


def get_scope(request):
    """
    Utility method to return the scope of a pytest request
    :param request:
    :return:
    """
    if request.node is request.session:
        return 'session'
    elif hasattr(request.node, 'function'):
        return 'function'
    else:
        return 'module'


def attempt_colab_login(app_url):
    """This renders an iframe to wandb in the hopes it posts back an api key"""
    from google.colab import output
    from google.colab._message import MessageError
    from IPython import display
    display.display(display.Javascript(
        """
        window._wandbApiKey = new Promise((resolve, reject) => {
            function loadScript(url) {
            return new Promise(function(resolve, reject) {
                let newScript = document.createElement("script");
                newScript.onerror = reject;
                newScript.onload = resolve;
                document.body.appendChild(newScript);
                newScript.src = url;
            });
            }
            loadScript("https://cdn.jsdelivr.net/npm/postmate/build/postmate.min.js").then(() => {
            const iframe = document.createElement('iframe')
            iframe.style.cssText = "width:0;height:0;border:none"
            document.body.appendChild(iframe)
            const handshake = new Postmate({
                container: iframe,
                url: '%s/authorize'
            });
            const timeout = setTimeout(() => reject("Couldn't auto authenticate"), 5000)
            handshake.then(function(child) {
                child.on('authorize', data => {
                    clearTimeout(timeout)
                    resolve(data)
                });
            });
            })
        });
    """
         % app_url.replace('http:', 'https:')))
    try:
        return output.eval_js('_wandbApiKey')
    except MessageError:
        return None


def bytes_to_int(s):
    """Return converted bytestring to integer.

  Args:
    s: str of bytes
  Returns:
    int: numeric interpretation of binary string `s`
  """
    return int(s.encode('hex'), 16)


def generate_presigned_url(ClientMethod=None, Params=None, ExpiresIn=None,
    HttpMethod=None):
    """
    Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
            ClientMethod.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
            default, the http method is whatever is used in the method's model.

    """
    pass


@staticmethod
def open(filename):
    """
		Equivalent to ``Table.from_file(open(filename, "r+"))``
		"""
    pass


def readUVARI(stream):
    """
    Reads a Variable-Length Unsigned Integer from stream

    :type stream: FileIO or BytesIO
    :param stream: Where to read from

    :return: result
    :rtype: int

    """
    b = stream.read(1)[0]
    if b & 128:
        if b & 64:
            b &= 63
            for i in range(3):
                b <<= 8
                b |= stream.read(1)[0]
        else:
            b &= 127
            b <<= 8
            b |= stream.read(1)[0]
    return b


def _find_logging_config(config):
    """
    Look for the dictionary containing logging-specific configurations,
    starting in the 'distributed' dictionary and then trying the top-level
    """
    logging_keys = {'logging-file-config', 'logging'}
    if logging_keys & config.get('distributed', {}).keys():
        return config['distributed']
    else:
        return config


def object_kind(object_path):
    """
    Parse the kind of object from an UDisks2 object path.

    Example:
        /org/freedesktop/UDisks2/block_devices/sdb1 => device
        /org/freedesktop/UDisks2/drives/WDC_WD...   => drive
        /org/freedesktop/UDisks2/jobs/5             => job
    """
    try:
        return {'block_devices': 'device', 'drives': 'drive', 'jobs': 'job'
            }.get(object_path.split('/')[4])
    except IndexError:
        return None


def iter_plat_repos(repos, platforms):
    """ Generator that yield a SinglePlatformRespository for every repository,
    platform combination.

    Parameters
    ----------
    repos: list
        Containing Repository objects
    platforms: list
        Containing strings of valid platforms

    Yields
    ------
    SinglePlatformRepository:
        hatcher.core.v*.repository.SinglePlatformRespository instance

    """
    for repo in repos:
        for platform in platforms:
            yield repo.platform(platform)


@staticmethod
def is_feed_url(url: str) ->bool:
    """
        Return True if URL ending contains valid feed file format.

        :param url: URL string
        :return: bool
        """
    return any(map(url.lower().endswith, ['.rss', '.rdf', '.xml', '.atom',
        '.json']))


def next():
    """Return the next message.

        It should return a Deferred which will get fired when there is a new
        project that needs to run, or already fired if there was a project
        waiting to run already.

        The message is a dict containing (at least):
        * the name of the project to be run in the '_project' key
        * the name of the spider to be run in the '_spider' key
        * a unique identifier for this run in the `_job` key
        This message will be passed later to IEnvironment.get_environment().
        """


def create_replication_group(ReplicationGroupId=None,
    ReplicationGroupDescription=None, PrimaryClusterId=None,
    AutomaticFailoverEnabled=None, NumCacheClusters=None,
    PreferredCacheClusterAZs=None, NumNodeGroups=None, ReplicasPerNodeGroup
    =None, NodeGroupConfiguration=None, CacheNodeType=None, Engine=None,
    EngineVersion=None, CacheParameterGroupName=None, CacheSubnetGroupName=
    None, CacheSecurityGroupNames=None, SecurityGroupIds=None, Tags=None,
    SnapshotArns=None, SnapshotName=None, PreferredMaintenanceWindow=None,
    Port=None, NotificationTopicArn=None, AutoMinorVersionUpgrade=None,
    SnapshotRetentionLimit=None, SnapshotWindow=None, AuthToken=None):
    """
    Creates a Redis (cluster mode disabled) or a Redis (cluster mode enabled) replication group.
    A Redis (cluster mode disabled) replication group is a collection of cache clusters, where one of the cache clusters is a read/write primary and the others are read-only replicas. Writes to the primary are asynchronously propagated to the replicas.
    A Redis (cluster mode enabled) replication group is a collection of 1 to 15 node groups (shards). Each node group (shard) has one read/write primary node and up to 5 read-only replica nodes. Writes to the primary are asynchronously propagated to the replicas. Redis (cluster mode enabled) replication groups partition the data across node groups (shards).
    When a Redis (cluster mode disabled) replication group has been successfully created, you can add one or more read replicas to it, up to a total of 5 read replicas. You cannot alter a Redis (cluster mode enabled) replication group after it has been created. However, if you need to increase or decrease the number of node groups (console: shards), you can avail yourself of ElastiCache for Redis' enhanced backup and restore. For more information, see Restoring From a Backup with Cluster Resizing in the ElastiCache User Guide .
    See also: AWS API Documentation

    :example: response = client.create_replication_group(
        ReplicationGroupId='string',
        ReplicationGroupDescription='string',
        PrimaryClusterId='string',
        AutomaticFailoverEnabled=True|False,
        NumCacheClusters=123,
        PreferredCacheClusterAZs=[
            'string',
        ],
        NumNodeGroups=123,
        ReplicasPerNodeGroup=123,
        NodeGroupConfiguration=[
            {
                'Slots': 'string',
                'ReplicaCount': 123,
                'PrimaryAvailabilityZone': 'string',
                'ReplicaAvailabilityZones': [
                    'string',
                ]
            },
        ],
        CacheNodeType='string',
        Engine='string',
        EngineVersion='string',
        CacheParameterGroupName='string',
        CacheSubnetGroupName='string',
        CacheSecurityGroupNames=[
            'string',
        ],
        SecurityGroupIds=[
            'string',
        ],
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ],
        SnapshotArns=[
            'string',
        ],
        SnapshotName='string',
        PreferredMaintenanceWindow='string',
        Port=123,
        NotificationTopicArn='string',
        AutoMinorVersionUpgrade=True|False,
        SnapshotRetentionLimit=123,
        SnapshotWindow='string',
        AuthToken='string'
    )

    :type ReplicationGroupId: string
    :param ReplicationGroupId: [REQUIRED]
            The replication group identifier. This parameter is stored as a lowercase string.
            Constraints:
            A name must contain from 1 to 20 alphanumeric characters or hyphens.
            The first character must be a letter.
            A name cannot end with a hyphen or contain two consecutive hyphens.

    :type ReplicationGroupDescription: string
    :param ReplicationGroupDescription: [REQUIRED]
            A user-created description for the replication group.

    :type PrimaryClusterId: string
    :param PrimaryClusterId: The identifier of the cache cluster that serves as the primary for this replication group. This cache cluster must already exist and have a status of available .
            This parameter is not required if NumCacheClusters , NumNodeGroups , or ReplicasPerNodeGroup is specified.

    :type AutomaticFailoverEnabled: boolean
    :param AutomaticFailoverEnabled: Specifies whether a read-only replica is automatically promoted to read/write primary if the existing primary fails.
            If true , Multi-AZ is enabled for this replication group. If false , Multi-AZ is disabled for this replication group.
            AutomaticFailoverEnabled must be enabled for Redis (cluster mode enabled) replication groups.
            Default: false
            Note
            ElastiCache Multi-AZ replication groups is not supported on:
            Redis versions earlier than 2.8.6.
            Redis (cluster mode disabled): T1 and T2 node types. Redis (cluster mode enabled): T2 node types.

    :type NumCacheClusters: integer
    :param NumCacheClusters: The number of clusters this replication group initially has.
            This parameter is not used if there is more than one node group (shard). You should use ReplicasPerNodeGroup instead.
            If AutomaticFailoverEnabled is true , the value of this parameter must be at least 2. If AutomaticFailoverEnabled is false you can omit this parameter (it will default to 1), or you can explicitly set it to a value between 2 and 6.
            The maximum permitted value for NumCacheClusters is 6 (primary plus 5 replicas).

    :type PreferredCacheClusterAZs: list
    :param PreferredCacheClusterAZs: A list of EC2 Availability Zones in which the replication group's cache clusters are created. The order of the Availability Zones in the list is the order in which clusters are allocated. The primary cluster is created in the first AZ in the list.
            This parameter is not used if there is more than one node group (shard). You should use NodeGroupConfiguration instead.
            Note
            If you are creating your replication group in an Amazon VPC (recommended), you can only locate cache clusters in Availability Zones associated with the subnets in the selected subnet group.
            The number of Availability Zones listed must equal the value of NumCacheClusters .
            Default: system chosen Availability Zones.
            (string) --

    :type NumNodeGroups: integer
    :param NumNodeGroups: An optional parameter that specifies the number of node groups (shards) for this Redis (cluster mode enabled) replication group. For Redis (cluster mode disabled) either omit this parameter or set it to 1.
            Default: 1

    :type ReplicasPerNodeGroup: integer
    :param ReplicasPerNodeGroup: An optional parameter that specifies the number of replica nodes in each node group (shard). Valid values are 0 to 5.

    :type NodeGroupConfiguration: list
    :param NodeGroupConfiguration: A list of node group (shard) configuration options. Each node group (shard) configuration has the following: Slots, PrimaryAvailabilityZone, ReplicaAvailabilityZones, ReplicaCount.
            If you're creating a Redis (cluster mode disabled) or a Redis (cluster mode enabled) replication group, you can use this parameter to individually configure each node group (shard), or you can omit this parameter.
            (dict) --node group (shard) configuration options. Each node group (shard) configuration has the following: Slots , PrimaryAvailabilityZone , ReplicaAvailabilityZones , ReplicaCount .
            Slots (string) --A string that specifies the keyspace for a particular node group. Keyspaces range from 0 to 16,383. The string is in the format startkey-endkey .
            Example: '0-3999'
            ReplicaCount (integer) --The number of read replica nodes in this node group (shard).
            PrimaryAvailabilityZone (string) --The Availability Zone where the primary node of this node group (shard) is launched.
            ReplicaAvailabilityZones (list) --A list of Availability Zones to be used for the read replicas. The number of Availability Zones in this list must match the value of ReplicaCount or ReplicasPerNodeGroup if not specified.
            (string) --

    :type CacheNodeType: string
    :param CacheNodeType: The compute and memory capacity of the nodes in the node group (shard).
            Valid node types are as follows:
            General purpose:
            Current generation: cache.t2.micro , cache.t2.small , cache.t2.medium , cache.m3.medium , cache.m3.large , cache.m3.xlarge , cache.m3.2xlarge , cache.m4.large , cache.m4.xlarge , cache.m4.2xlarge , cache.m4.4xlarge , cache.m4.10xlarge
            Previous generation: cache.t1.micro , cache.m1.small , cache.m1.medium , cache.m1.large , cache.m1.xlarge
            Compute optimized: cache.c1.xlarge
            Memory optimized:
            Current generation: cache.r3.large , cache.r3.xlarge , cache.r3.2xlarge , cache.r3.4xlarge , cache.r3.8xlarge
            Previous generation: cache.m2.xlarge , cache.m2.2xlarge , cache.m2.4xlarge

            Notes:
            All T2 instances are created in an Amazon Virtual Private Cloud (Amazon VPC).
            Redis backup/restore is not supported for Redis (cluster mode disabled) T1 and T2 instances. Backup/restore is supported on Redis (cluster mode enabled) T2 instances.
            Redis Append-only files (AOF) functionality is not supported for T1 or T2 instances.
            For a complete listing of node types and specifications, see Amazon ElastiCache Product Features and Details and either Cache Node Type-Specific Parameters for Memcached or Cache Node Type-Specific Parameters for Redis .

    :type Engine: string
    :param Engine: The name of the cache engine to be used for the cache clusters in this replication group.

    :type EngineVersion: string
    :param EngineVersion: The version number of the cache engine to be used for the cache clusters in this replication group. To view the supported cache engine versions, use the DescribeCacheEngineVersions operation.
            Important: You can upgrade to a newer engine version (see Selecting a Cache Engine and Version ) in the ElastiCache User Guide , but you cannot downgrade to an earlier engine version. If you want to use an earlier engine version, you must delete the existing cache cluster or replication group and create it anew with the earlier engine version.

    :type CacheParameterGroupName: string
    :param CacheParameterGroupName: The name of the parameter group to associate with this replication group. If this argument is omitted, the default cache parameter group for the specified engine is used.
            If you are running Redis version 3.2.4 or later, only one node group (shard), and want to use a default parameter group, we recommend that you specify the parameter group by name.
            To create a Redis (cluster mode disabled) replication group, use CacheParameterGroupName=default.redis3.2 .
            To create a Redis (cluster mode enabled) replication group, use CacheParameterGroupName=default.redis3.2.cluster.on .

    :type CacheSubnetGroupName: string
    :param CacheSubnetGroupName: The name of the cache subnet group to be used for the replication group.
            Warning
            If you're going to launch your cluster in an Amazon VPC, you need to create a subnet group before you start creating a cluster. For more information, see Subnets and Subnet Groups .

    :type CacheSecurityGroupNames: list
    :param CacheSecurityGroupNames: A list of cache security group names to associate with this replication group.
            (string) --

    :type SecurityGroupIds: list
    :param SecurityGroupIds: One or more Amazon VPC security groups associated with this replication group.
            Use this parameter only when you are creating a replication group in an Amazon Virtual Private Cloud (Amazon VPC).
            (string) --

    :type Tags: list
    :param Tags: A list of cost allocation tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value.
            (dict) --A cost allocation Tag that can be added to an ElastiCache cluster or replication group. Tags are composed of a Key/Value pair. A tag with a null Value is permitted.
            Key (string) --The key for the tag. May not be null.
            Value (string) --The tag's value. May be null.

    :type SnapshotArns: list
    :param SnapshotArns: A list of Amazon Resource Names (ARN) that uniquely identify the Redis RDB snapshot files stored in Amazon S3. The snapshot files are used to populate the new replication group. The Amazon S3 object name in the ARN cannot contain any commas. The new replication group will have the number of node groups (console: shards) specified by the parameter NumNodeGroups or the number of node groups configured by NodeGroupConfiguration regardless of the number of ARNs specified here.
            Note
            This parameter is only valid if the Engine parameter is redis .
            Example of an Amazon S3 ARN: arn:aws:s3:::my_bucket/snapshot1.rdb
            (string) --

    :type SnapshotName: string
    :param SnapshotName: The name of a snapshot from which to restore data into the new replication group. The snapshot status changes to restoring while the new replication group is being created.
            Note
            This parameter is only valid if the Engine parameter is redis .

    :type PreferredMaintenanceWindow: string
    :param PreferredMaintenanceWindow: Specifies the weekly time range during which maintenance on the cache cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period. Valid values for ddd are:
            Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period.
            Valid values for ddd are:
            sun
            mon
            tue
            wed
            thu
            fri
            sat
            Example: sun:23:00-mon:01:30

    :type Port: integer
    :param Port: The port number on which each member of the replication group accepts connections.

    :type NotificationTopicArn: string
    :param NotificationTopicArn: The Amazon Resource Name (ARN) of the Amazon Simple Notification Service (SNS) topic to which notifications are sent.
            Note
            The Amazon SNS topic owner must be the same as the cache cluster owner.

    :type AutoMinorVersionUpgrade: boolean
    :param AutoMinorVersionUpgrade: This parameter is currently disabled.

    :type SnapshotRetentionLimit: integer
    :param SnapshotRetentionLimit: The number of days for which ElastiCache retains automatic snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
            Note
            This parameter is only valid if the Engine parameter is redis .
            Default: 0 (i.e., automatic backups are disabled for this cache cluster).

    :type SnapshotWindow: string
    :param SnapshotWindow: The daily time range (in UTC) during which ElastiCache begins taking a daily snapshot of your node group (shard).
            Example: 05:00-09:00
            If you do not specify this parameter, ElastiCache automatically chooses an appropriate time range.
            Note
            This parameter is only valid if the Engine parameter is redis .

    :type AuthToken: string
    :param AuthToken:
            Reserved parameter. The password used to access a password protected server.
            Password constraints:
            Must be only printable ASCII characters.
            Must be at least 16 characters and no more than 128 characters in length.
            Cannot contain any of the following characters: '/', ''', or '@'.
            For more information, see AUTH password at Redis.

    :rtype: dict
    :return: {
        'ReplicationGroup': {
            'ReplicationGroupId': 'string',
            'Description': 'string',
            'Status': 'string',
            'PendingModifiedValues': {
                'PrimaryClusterId': 'string',
                'AutomaticFailoverStatus': 'enabled'|'disabled'
            },
            'MemberClusters': [
                'string',
            ],
            'NodeGroups': [
                {
                    'NodeGroupId': 'string',
                    'Status': 'string',
                    'PrimaryEndpoint': {
                        'Address': 'string',
                        'Port': 123
                    },
                    'Slots': 'string',
                    'NodeGroupMembers': [
                        {
                            'CacheClusterId': 'string',
                            'CacheNodeId': 'string',
                            'ReadEndpoint': {
                                'Address': 'string',
                                'Port': 123
                            },
                            'PreferredAvailabilityZone': 'string',
                            'CurrentRole': 'string'
                        },
                    ]
                },
            ],
            'SnapshottingClusterId': 'string',
            'AutomaticFailover': 'enabled'|'disabled'|'enabling'|'disabling',
            'ConfigurationEndpoint': {
                'Address': 'string',
                'Port': 123
            },
            'SnapshotRetentionLimit': 123,
            'SnapshotWindow': 'string',
            'ClusterEnabled': True|False,
            'CacheNodeType': 'string'
        }
    }

    :returns:
    Redis versions earlier than 2.8.6.
    Redis (cluster mode disabled):T1 and T2 cache node types. Redis (cluster mode enabled): T1 node types.

    """
    pass


def __window_ss_fill(x, win_sq, n_frames, hop_length):
    """Helper function for window sum-square calculation."""
    n = len(x)
    n_fft = len(win_sq)
    for i in range(n_frames):
        sample = i * hop_length
        x[sample:min(n, sample + n_fft)] += win_sq[:max(0, min(n_fft, n -
            sample))]


@classmethod
def no_expiration_link_gen_create_report(cls, val):
    """
        Create an instance of this class set to the
        ``no_expiration_link_gen_create_report`` tag with value ``val``.

        :param NoExpirationLinkGenCreateReportType val:
        :rtype: EventType
        """
    return cls('no_expiration_link_gen_create_report', val)


def ilshift(a, b):
    """Same as a <<= b."""
    a <<= b
    return a


def set_identity_dkim_enabled(Identity=None, DkimEnabled=None):
    """
    Enables or disables Easy DKIM signing of email sent from an identity:
    For email addresses (e.g., user@example.com ), you can only enable Easy DKIM signing if the corresponding domain (e.g., example.com ) has been set up for Easy DKIM using the AWS Console or the VerifyDomainDkim action.
    This action is throttled at one request per second.
    For more information about Easy DKIM signing, go to the Amazon SES Developer Guide .
    See also: AWS API Documentation

    Examples
    The following example configures Amazon SES to Easy DKIM-sign the email sent from an identity:
    Expected Output:

    :example: response = client.set_identity_dkim_enabled(
        Identity='string',
        DkimEnabled=True|False
    )

    :type Identity: string
    :param Identity: [REQUIRED]
            The identity for which DKIM signing should be enabled or disabled.

    :type DkimEnabled: boolean
    :param DkimEnabled: [REQUIRED]
            Sets whether DKIM signing is enabled for an identity. Set to true to enable DKIM signing for this identity; false to disable it.

    :rtype: dict
    :return: {}

    :returns:
    Identity (string) -- [REQUIRED]
    The identity for which DKIM signing should be enabled or disabled.

    DkimEnabled (boolean) -- [REQUIRED]
    Sets whether DKIM signing is enabled for an identity. Set to true to enable DKIM signing for this identity; false to disable it.

    """
    pass


@classmethod
def int_keywords(cls):
    """Will return the current set of integer keywords."""
    return cls.int_kw_set


def get_string_trace_attribute_rep(trace, trace_attribute):
    """
    Get a representation of the feature name associated to a string trace attribute value

    Parameters
    ------------
    trace
        Trace of the log
    trace_attribute
        Attribute of the trace to consider

    Returns
    ------------
    rep
        Representation of the feature name associated to a string trace attribute value
    """
    if trace_attribute in trace.attributes:
        return 'trace:' + str(trace_attribute) + '@' + str(trace.attributes
            [trace_attribute])
    return 'trace:' + str(trace_attribute) + '@UNDEFINED'


def extract_tests(api_response, defined_tests):
    """
    Create and return a dict of test name to test data.

    If api_response is None, return a dict with an empty dict.

    api_response: the JSON response from the Proctor API in Python object form.
    defined_tests: an iterable of test name strings defining the tests that
        should be available to the user. Usually from Django settings.
    """
    if api_response is None:
        return {'tests': {}}
    api_audit = api_response['audit']
    api_tests = api_response['tests']
    test_dict = {}
    for test_name in defined_tests:
        if test_name in api_tests:
            test_dict[test_name] = api_tests[test_name]
        else:
            test_dict[test_name] = {}
    return {'audit': api_audit, 'tests': test_dict}


def render_pep440_pre(pieces):
    """TAG[.post.devDISTANCE] -- No -dirty.

    Exceptions:
    1: no tags. 0.post.devDISTANCE
    """
    if pieces['closest-tag']:
        rendered = pieces['closest-tag']
        if pieces['distance']:
            rendered += '.post.dev%d' % pieces['distance']
    else:
        rendered = '0.post.dev%d' % pieces['distance']
    return rendered


@classmethod
def apply_suggester_completion_match(cls, suggester_name, queryset, options,
    value):
    """Apply `completion` suggester match.

        This is effective when used with Ngram fields.

        :param suggester_name:
        :param queryset: Original queryset.
        :param options: Filter options.
        :param value: value to filter on.
        :type suggester_name: str
        :type queryset: elasticsearch_dsl.search.Search
        :type options: dict
        :type value: str
        :return: Modified queryset.
        :rtype: elasticsearch_dsl.search.Search
        """
    queryset = queryset.query('match', **{options['field']: value})
    queryset = cls.apply_query_size(queryset, options)
    return queryset


def tokens(nodes):
    """Helper to yield tokens from the iterable of nodes."""
    for n in nodes:
        if n.is_token:
            yield n
        else:
            yield from n.tokens()


@staticmethod
def _unmarshal_relationships(pkg_reader, package, parts):
    """
        Add a relationship to the source object corresponding to each of the
        relationships in *pkg_reader* with its target_part set to the actual
        target part in *parts*.
        """
    for source_uri, srel in pkg_reader.iter_srels():
        source = package if source_uri == '/' else parts[source_uri]
        target = srel.target_ref if srel.is_external else parts[srel.
            target_partname]
        source.load_rel(srel.reltype, target, srel.rId, srel.is_external)


@classmethod
def descriptions(cls):
    """ Retrieve status descriptions from status.gandi.net. """
    schema = cls.json_get('%s/status/schema' % cls.api_url, empty_key=True,
        send_key=False)
    descs = {}
    for val in schema['fields']['status']['value']:
        descs.update(val)
    return descs


@staticmethod
def positional_to_model(value):
    """Converts a positional argument to a model value"""
    return value


def get_headers(headers):
    """By default headers are folded by mitmproxy."""
    headers_dict = {}
    for key, val in headers.items():
        headers_dict[key] = val
    return headers_dict


@staticmethod
def format_packet(command):
    """Format packet to be sent."""
    frame_header = b'\xaa'
    verify = b'\x0b'
    send_delim = b'\xbb'
    return frame_header + command.ljust(17, b'\x00') + verify + send_delim


def process_exit_code(retval):
    """Process a waitpid returned exit code.

    :return: The exit code if it exit'd, the signal if it died from signalling.
    """
    if retval & 255:
        return (retval & 255) << 8
    return retval >> 8


def chunk(iterable, chunk_size):
    """
    Yield successive n-sized chunks from an iterable.
    If the iterable does not fit evenly into chunk_size, the last chunk will be smaller than chunk_size.
    :param iterable: any iterable
    :param chunk_size: size of chunks
    >>> r = range(5)
    >>> for c in chunk(r, 2):
    ...     print(c)
    (0, 1)
    (2, 3)
    (4,)
    """
    x = iter(iterable)
    for item in x:
        yield item, *(next(x) for _ in range(chunk_size - 1))


def calc_phase(p, t):
    """
    Calculate the phase array.

    Args:
        t (array): The time array (in days).
        p (float): Period (in days)

    Returns
        phase (array): The phase array.
    """
    return t % p / p


def _expr_to_smtlib(e, daggify=True):
    """
    Dump the symbol in its smt-format depending on its type

    :param e: symbol to dump
    :param daggify: The daggify parameter can be used to switch from a linear-size representation that uses ‘let’
                    operators to represent the formula as a dag or a simpler (but possibly exponential) representation
                    that expands the formula as a tree

    :return string: smt-lib representation of the symbol
    """
    if e.is_symbol():
        return '(declare-fun %s %s)' % (e.symbol_name(), e.symbol_type().
            as_smtlib())
    else:
        return '(assert %s)' % e.to_smtlib(daggify=daggify)


def sponsor_sort(sort):
    """
    Returns the actual name of the key to sort by.
    """
    if sort == 'id':
        return '_id'
    elif sort == 'sponsor':
        return 'account'
    elif sort == 'witness':
        return 'is_witness'
    elif sort == 'percentage':
        return 'percentage_total_vesting_shares'
    else:
        return 'vesting_shares'


def transform(hostsvars):
    """Transform an Ansible hostsvars object prior to JSON serialization.

    This transform is the identify function and is provided as an example.

    Args:
        hostsvars: A dictionary mapping hosts (usually IP addresses) to
            dictionaries of variables for each host.

    Returns:
        A modified hostsvars dictionary.
    """
    return hostsvars


@classmethod
def _get_dma(cls, df):
    """ Different of Moving Average

        default to 10 and 50.
        :param df: data
        :return: None
        """
    df['dma'] = df['close_10_sma'] - df['close_50_sma']


def create_scan(target):
    """
    Creates CreateScan mutation query
    :param target: Target name
    :return: CreateScan mutation query
    """
    create_scan_query = (
        """
        mutation {
          createScan(target: "%s") {
            scan {
              name
              createdOn
            }
          }
        }
        """
         % target)
    return create_scan_query


@staticmethod
def get_multipliers(record):
    """
        Private quick method to determine the multipliers for a BLAST alignment
        according to the application present in the record.
        :param record:
        :return:
        """
    q_mult, h_mult = 1, 1
    application = record.program.upper()
    if application in ('BLASTN', 'TBLASTX', 'BLASTP'):
        q_mult = 1
        h_mult = 1
    elif application == 'BLASTX':
        q_mult = 3
        h_mult = 1
    elif application == 'TBLASTN':
        q_mult = 1
        h_mult = 3
    return q_mult, h_mult


def bit_invert(value, width=32):
    """! @brief Return the bitwise inverted value of the argument given a specified width.

    @param value Integer value to be inverted.
    @param width Bit width of both the input and output. If not supplied, this defaults to 32.
    @return Integer of the bitwise inversion of @a value.
    """
    return (1 << width) - 1 & ~value


@classmethod
def from_data(cls, data):
    """Construct a polyline from a data dict.

        Parameters
        ----------
        data : dict
            The data dictionary.

        Returns
        -------
        :class:`compas.geometry.Polyline`
            The constructed polyline.

        Examples
        --------
        >>> polyline = Polyline.from_data({'points': [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0, 0.0]]})
        >>> polyline
        Polyline(Point(0.000, 0.000, 0.000), Point(1.000, 0.000, 0.000), Point(1.000, 1.000, 0.000))
        """
    return cls(data['points'])


def stringvalue(string):
    """
    Retrieve actual value of string without quotes. Escaped
    quotes inside the value are resolved, e.g.::

        ``'a 'string'`` => ``a 'string``
    """
    return string.replace('\\' + string[0], string[0])[1:-1]


@staticmethod
def _asyn_deal_msg_fun_default(topic_name, record):
    """
        将日志record对象中的日志内容部分处理为msg并返回(默认函数, 不改变msg)

        @param {string} topic_name - 日志主题
        @param {object} record - 日志信息对象

        @return {string} - 处理后的msg
        """
    return record.msg


@classmethod
def construct_array_type(cls):
    """
        Return the array type associated with this dtype.

        Returns
        -------
        type
        """
    from pandas.core.arrays import PeriodArray
    return PeriodArray


def subsets_from_metadata(metadata, minimum, subset_type, ignore=None):
    """Get subsets from metadata, including boolean and categorical columns

    Parameters
    ----------
    metadata : pandas.DataFrame
        The dataframe whose columns to use to create subsets of the rows
    minimum : int
        Minimum number of rows required for a column or group in the column
        to be included
    subset_type : str
        The name of the kind of subset. e.g. "samples" or "features"
    ignore : list-like
        List of columns to ignore

    Returns
    -------
    subsets : dict
        A name: row_ids mapping of which samples correspond to which group
    """
    subsets = {}
    sorted_bool = False, True
    ignore = () if ignore is None else ignore
    if metadata is not None:
        for col in metadata:
            if col in ignore:
                continue
            if tuple(sorted(metadata[col].dropna().unique())) == sorted_bool:
                series = metadata[col].dropna()
                sample_subset = series[series].index
                subsets[col] = sample_subset
            else:
                grouped = metadata.groupby(col)
                sizes = grouped.size()
                filtered_sizes = sizes[sizes >= minimum]
                for group in filtered_sizes.keys():
                    if isinstance(group, bool):
                        continue
                    name = '{}: {}'.format(col, group)
                    subsets[name] = grouped.groups[group]
        for sample_subset in subsets.copy().keys():
            name = 'not ({})'.format(sample_subset)
            if 'False' in name or 'True' in name:
                continue
            if name not in subsets:
                in_features = metadata.index.isin(subsets[sample_subset])
                subsets[name] = metadata.index[~in_features]
        subsets['all {}'.format(subset_type)] = metadata.index
    return subsets


def select_most_recent_belief(df: 'classes.BeliefsDataFrame'
    ) ->'classes.BeliefsDataFrame':
    """Drop all but most recent belief."""
    if 'belief_horizon' in df.index.names:
        return df.groupby(level=['event_start', 'source'], group_keys=False
            ).apply(lambda x: x.xs(min(x.lineage.belief_horizons), level=
            'belief_horizon', drop_level=False))
    elif 'belief_time' in df.index.names:
        return df.groupby(level=['event_start', 'source'], group_keys=False
            ).apply(lambda x: x.xs(max(x.lineage.belief_times), level=
            'belief_time', drop_level=False))
    else:
        raise KeyError(
            'No belief_horizon or belief_time index level found in DataFrame.')


def handleModified(ob):
    """ Modufy object in queue
        """


def get_querystring_for_page(request, page_number, querystring_key,
    default_number=1):
    """Return a querystring pointing to *page_number*."""
    querydict = request.GET.copy()
    querydict[querystring_key] = page_number
    if page_number == default_number:
        del querydict[querystring_key]
    if 'querystring_key' in querydict:
        del querydict['querystring_key']
    if querydict:
        return '?' + querydict.urlencode()
    return ''


def truelen(string):
    """
    It appears one Asian character takes two spots, but __len__
    counts it as three, so this function counts the dispalyed
    length of the string.

    将汉字的所占的长度进行重新地换算，因为单纯地用Python自带的长度计算方法有
    错误

    >>> truelen('abc')
    3
    >>> truelen('你好')
    4
    >>> truelen('1二3')
    4
    >>> truelen('')
    0
    """
    return len(string) + sum(1 for c in string if c > chr(127))


@classmethod
def register_conf_options(cls, conf, group):
    """Register the oslo_config options that are needed for a plugin.

        :param conf: A config object.
        :type conf: oslo_config.cfg.ConfigOpts
        :param string group: The group name that options should be read from.
        """
    plugin_opts = cls.get_options()
    conf.register_opts(plugin_opts, group=group)


def baskets(items, basketsize=10):
    """generates balanced baskets from iterable, contiguous items"""
    num_items = len(items)
    num_baskets = max(1, num_items // basketsize)
    if num_items % basketsize and basketsize < num_items:
        num_baskets += 1
    step = num_items // num_baskets
    for i in range(0, num_items, step):
        yield items[i:i + step]


def doBinomialTest(p, sample_size, observed, significance_threshold=0.05):
    """perform a binomial test.

    Given are p: the probability of the NULL hypothesis, the sample_size
    and the number of observed counts.
    """
    pass


def make_repr_html(obj):
    """
    Make a nice HTML table
    :param obj: Python object
    :return: HTML string
    """
    html_text = f'
{obj.__class__.__name__} {obj.name}
'
    html_text += '

'
    if hasattr(obj, 'package_names'):
        html_text += '
number of packages:	'
        html_text += f'{len(obj.package_names)}
'
    if hasattr(obj, 'var_names'):
        html_text += '
number of variables: 	'
        html_text += f'{len(obj.var_names)}
'
    if hasattr(obj, 'value'):
        html_text += '
value: 	'
        html_text += f'{repr(obj.value)}
'
        if obj.value.shape:
            html_text += '
shape: 	'
            html_text += f'{obj.value.shape}
'
    if hasattr(obj, 'origin'):
        html_text += '
location: 	'
        html_text += f'{obj.origin}
'
    html_text += '

'
    return html_text


@staticmethod
def setup_subparser(parser, cmd=None):
    """
        Set up a subparser for 'help'
        """
    group = parser.add_argument_group('Help')
    group.add_argument('help', action='append', default=None, nargs='?')


def add_tags_to_resource(ResourceName=None, Tags=None):
    """
    Adds up to 50 cost allocation tags to the named resource. A cost allocation tag is a key-value pair where the key and value are case-sensitive. You can use cost allocation tags to categorize and track your AWS costs.
    When you apply tags to your ElastiCache resources, AWS generates a cost allocation report as a comma-separated value (CSV) file with your usage and costs aggregated by your tags. You can apply tags that represent business categories (such as cost centers, application names, or owners) to organize your costs across multiple services. For more information, see Using Cost Allocation Tags in Amazon ElastiCache in the ElastiCache User Guide .
    See also: AWS API Documentation

    :example: response = client.add_tags_to_resource(
        ResourceName='string',
        Tags=[
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    )

    :type ResourceName: string
    :param ResourceName: [REQUIRED]
            The Amazon Resource Name (ARN) of the resource to which the tags are to be added, for example arn:aws:elasticache:us-west-2:0123456789:cluster:myCluster or arn:aws:elasticache:us-west-2:0123456789:snapshot:mySnapshot .
            For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces .

    :type Tags: list
    :param Tags: [REQUIRED]
            A list of cost allocation tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value.
            (dict) --A cost allocation Tag that can be added to an ElastiCache cluster or replication group. Tags are composed of a Key/Value pair. A tag with a null Value is permitted.
            Key (string) --The key for the tag. May not be null.
            Value (string) --The tag's value. May be null.

    :rtype: dict
    :return: {
        'TagList': [
            {
                'Key': 'string',
                'Value': 'string'
            },
        ]
    }

    """
    pass


@classmethod
def Colors(cls):
    """Returns the list of colors.
        """
    return cls.colors


def colorbar_extension(colour_min, colour_max, data_min, data_max):
    """
    For the range specified by `colour_min' to `colour_max', return whether the data range specified by `data_min'
    and `data_max' is inside, outside or partially overlapping. This allows you to automatically set the `extend'
    keyword on a `matplotlib.pyplot.colorbar' call.

    Parameters
    ----------
    colour_min, colour_max : float
        Minimum and maximum value of the current colour bar limits.
    data_min, data_max : float
        Minimum and maximum value of the data limits.

    Returns
    -------
    extension : str
        Will be 'neither', 'both', 'min, or 'max' for the case when the colour_min and colour_max values are: equal
        to the data; inside the data range; only larger or only smaller, respectively.
    """
    if data_min < colour_min and data_max > colour_max:
        extension = 'both'
    elif data_min < colour_min and data_max <= colour_max:
        extension = 'min'
    elif data_min >= colour_min and data_max > colour_max:
        extension = 'max'
    else:
        extension = 'neither'
    return extension


def IsBlankLine(line):
    """Returns true if the given line is blank.

  We consider a line to be blank if the line is empty or consists of
  only white spaces.

  Args:
    line: A line of a string.

  Returns:
    True, if the given line is blank.
  """
    return not line or line.isspace()


def print_config(config, logger):
    """
    Print configuration of the model
    """
    for k, v in config.items():
        logger.info('{}:\t{}'.format(k.ljust(15), v))


def _check_length(data, labels, num_seqs_check=None):
    """
    Checks the lengths of the clustal sequences to make
    sure that they are lining up right

    num_seqs_check: The number of sequences to check

    Return True if all of the subsequence lengths are equal
                or if data is empty
    Return False if one of the subsequence lengths differs
    """
    if len(labels) == 0:
        return True
    num_subseqs = len(data[labels[0]])
    if num_seqs_check is None:
        num_seqs_check = num_subseqs
    elif num_seqs_check > num_subseqs:
        num_seqs_check = num_subseqs
    subseq_length = len(data[labels[0]][0])
    end_lengths = set()
    for i in range(num_seqs_check):
        for label in labels:
            seq = data[label][i]
            if len(seq) > subseq_length:
                return False
            elif i + 1 == num_subseqs:
                end_lengths.add(len(seq))
            elif len(seq) < subseq_length:
                return False
    if len(end_lengths) > 1:
        return False
    return True


def grouper(iterable, size=2):
    """
    Collect data into fixed-length chunks or blocks.
    grouper('ABCDEFGHI', 3) --> ABC DEF GHI
    """
    return zip(*([iter(iterable)] * size))


def extrude_region_move(MESH_OT_extrude_region=None, TRANSFORM_OT_translate
    =None):
    """Extrude region and move result

    :param MESH_OT_extrude_region: Extrude Region, Extrude region of faces
    :param TRANSFORM_OT_translate: Translate, Translate (move) selected items
    """
    pass


def convert_none_to_empty_dict(val):
    """ if val is None, return an empty dict"""
    if val is None:
        return {}
    return val


@staticmethod
def get_resource_metadata():
    """Returns the (resource, mime-type) for the handlers spec.
        """
    pass


@staticmethod
def getPossibleMoves(state):
    """
		Return the list of move that can be played from the given state

		:param state:  Game state to evaluate (GameState)
		:return:  List of possible moves (list)
		:raises NotImplementedError: if child does not override this function
		"""
    raise NotImplementedError()


def unquote_plus():
    """Return the objects URL unquote_plus  representation."""


def swap(arr, p0, p1):
    """
    Intercambia los valores de dos posiciones de un arreglo.
    """
    arr_list = list(arr)
    aux = arr_list[p0]
    arr_list[p0] = arr_list[p1]
    arr_list[p1] = aux
    return ''.join(arr_list)