def stop(win, ctx):
    """Stop and unload any active JoyCursors for the given *ctx*.
    """
    if hasattr(ctx, 'joycursor'):
        ctx.joycursor.activated = False
        win.unbind(children=ctx.joycursor.on_window_children, on_keyboard=
            ctx.joycursor.keyboard_shortcuts)
        win.funbind('on_joy_button_down', ctx.joycursor.joystick_shortcuts)
        win.remove_widget(ctx.joycursor)
        del ctx.joycursor


def ceil_div(a: int, b: int) ->int:
    """Integer division that rounds up."""
    return (a - 1) // b + 1


def at_end_of_domain(z, sub):
    """Check if a cell a river mouth at the end of domain.
    Parameters
    ----------
    z : ndarray
        2D-array of elevations.
    sub : tuple of int
        Row and column subscript into *z*.
    Returns
    -------
    boolean
        True if the cell at the given subscript is at the river mouth.
    """
    try:
        return sub[0] == z.shape[0] - 1
    except IndexError:
        return True


@classmethod
def parse(cls, line):
    """Parse the contribution line as bytes"""
    name, line = line.split(b' <', 1)
    email, line = line.split(b'> ', 1)
    timestamp, line = line.split(b' ', 1)
    return cls(name.decode('utf-8'), email.decode('utf-8'), int(timestamp))


@classmethod
def send(cls, *args, **kargs):
    """Sends a notification to all the subscribers listening to this event.
        """
    event = cls(*args, **kargs)
    cls.manager.notify(event)


def parse_dir(dirname):
    """
    Hack to remove '/path/to/folder/untitled/' error from QTFileDialog where /untitled/ gets appended by default
    This happens when you select OK in in the getExistingDirectory dialog without manually selecting a directory
    Essentially you want to say OK to the default directory but for some reason /untitled/ gets added to the path

    :param dirname: string path to directory delimited by /
    :return: string path to directory delimited by / without .../untitled/... if it exists

    :Test Cases:
        x = '/User/Test/Desktop/'
        y = '/User/Test/untitled/Desktop/'
        z = '/untitled/User/Test/Desktop/'

        all will return the string '/User/Test/Desktop'

    :Note: If this will cause problems if the User actually has data stored in a path with a folder
           called untitled intentionally
    """
    splt = dirname.split('/')
    if 'untitled' in splt:
        index = splt.index('untitled')
        del splt[index]
        print('Warning: detected .../untitled/... somewhere in path')
        print(
            'This is often caused by an error in the QFileDialog implementation.'
            )
        print('Attempting to fix path automatically ...')
    return '/'.join(splt)


def config(encode_hook=None, decode_hook=None):
    """
    Provides high-level configuration for the entire package.  It is not required; it is
    designed to allow customization.

    encode_hook
      A function that accepts a URL handler response as either a list or dictionary and JSON
      encodes it to a UTF-8 encoded string.  If not provided, json.dumps is used.

    decode_hook
      A JSON object hook (for json.loads(object_hook)) that is called for every object

      A function that accepts a Unicode JSON string and decodes it into a Python dictionary.
      If not provided, json.loads is used.

      A dictionary is required since it is used to populate URL handler arguments and we need
      to know the name of the argument each element should be assigned to.

    annotation_converter
      A function that post processes request variables (after the decode_hook, etc.) and
      optionally converts values based on Python argument annotations.

      This function is only called if the Route has annotations.  If so, the variables are
      passed as a mapping from argument name to value.

        func(route, map_arg_to_value) -> None

      If a value is to be converted, the new value should overwrite the old one in the map.
    """
    from .requests import Request
    Request._ohook = decode_hook
    from .responses import Response
    Response._ohook = encode_hook


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

        :param SharedContentAddLinkExpiryType val:
        :rtype: EventType
        """
    return cls('shared_content_add_link_expiry', val)


@classmethod
def equals(cls, this, that):
    """
        Compares a reference to an enum and returns whether it is the second
        passed enum or not
        :param this: The study object to be compared
        :type this: object
        :param that: What we are comparing against
        :type that: object
        :return: Whether they are one and the same
        :rtype: boolean
        """
    return cls.get(this) is cls.get(that)


def cas2sas_date(cdt):
    """
    Convert a CAS date to a SAS date

    Parameters
    ----------
    cdt : int
        CAS date.

    Examples
    --------
    >>> cas2sas_date(3653)
    3653.0

    Returns
    -------
    float
        SAS date

    """
    return float(cdt)


def list_del_indices(mylist, indices):
    """
    iteratively remove elements of a list by indices
    Parameters
    ----------
    mylist : list
        the list of elements of interest

    indices : list
        the list of indices of elements that should be removed

    Returns
    -------
    list
        the reduced mylist entry

    """
    for index in sorted(indices, reverse=True):
        del mylist[index]
    return mylist


def get_dicts(data):
    """
    data must be a list of lists, from a tab delimited file.
    in each list:
    the first list item will be the type of data.
    the second list item will be a tab delimited list of headers.
    the remaining items  will be a tab delimited list following the list of headers.
    """
    data_dictionaries = []
    for chunk in data[:-1]:
        if not chunk:
            continue
        data1 = data[0]
        file_type = chunk[0].split('\t')[1].strip('\n').strip('\r')
        keys = chunk[1].split('\t')
        clean_keys = []
        for key in keys:
            clean_key = key.strip('\n').strip('\r')
            if clean_key:
                clean_keys.append(clean_key)
        for line in chunk[2:]:
            data_dict = {}
            for key in clean_keys:
                data_dict[key] = ''
            line = line.split('\t')
            for n, key in enumerate(clean_keys):
                data_dict[key] = line[n].strip('\n').strip('\r')
            data_dict['file_type'] = file_type
            data_dictionaries.append(data_dict)
    return data_dictionaries


@staticmethod
def execute_criticality_score(G, model_results, gamma):
    """
        Applies the criticality score

        :return: dict including criticality scores)
        """
    df_diff = model_results.diff().drop([0])
    nodes = G.nodes
    for node in nodes:
        for i in list(range(len(df_diff)))[1:]:
            df_diff[node][i] = df_diff[node][i] / i ** gamma
    df_sum_diff = df_diff.sum()
    df_results = df_sum_diff + 1
    crit = df_results.to_dict()
    return crit


def descendants(revs):
    """Obtain descendant revision numbers for a set of revision numbers.

        If ``nullrev`` is in the set, this is equivalent to ``revs()``.
        """


def open_python_files(filepaths):
    """For each specified filepath, yield (path, content) pairs."""
    for filepath in sorted(filepaths):
        with open(filepath, 'r') as f:
            contents = f.read()
        yield filepath, contents


@classmethod
def get_connection(cls, pid, connection):
    """Return the specified :class:`~queries.pool.Connection` from the
        pool.

        :param str pid: The pool ID
        :param connection: The connection to return for
        :type connection: psycopg2.extensions.connection
        :rtype: queries.pool.Connection

        """
    with cls._lock:
        return cls._pools[pid].connection_handle(connection)


def rw(T, Wse, verbose=False, Celcius=False):
    """
    Tc = 60.0       # Temperature (F)
    Wse =  60000.0  # Salinity (ppm)
    """
    if Celcius == True:
        Tf = 9.0 / 5.0 * T + 32.0
    else:
        Tf = T
    Rw = (400000.0 / (Tf * Wse)) ** 0.88
    if verbose == True:
        print('T (f):     %10.2f' % Tf)
        print('Wse (ppm): %10.2f' % Wse)
        print('Rw (Ohm*m):%10.5f' % Rw)
    return Rw


def elemDisappearedCallback(retelem, obj, **kwargs):
    """Callback for checking if a UI element is no longer onscreen.

    kwargs should contains some unique set of identifier (e.g. title/value, role)
    Returns:  Boolean
    """
    return not obj.findFirstR(**kwargs)


@classmethod
def canEmulate(cls):
    """Tells whether emulation is supported.
        """
    return cls.build_send_payload('canEmulate', {}), cls.convert_payload({
        'result': {'class': bool, 'optional': False}})


def decls(hub, name, state, sls_ref):
    """
    Resolve and state formatting and data insertion
    """
    for id_ in state:
        if not isinstance(state[id_], dict):
            if id_ == '__extend__':
                continue
            if id_ == '__exclude__':
                continue
            if isinstance(state[id_], str):
                if '.' in state[id_]:
                    comps = state[id_].split('.')
                    state[id_] = {'__sls__': sls_ref, comps[0]: [comps[1]]}
                    continue
            hub.idem.RUNS[name]['errors'].append(
                f'ID {id_} in SLS {sls_ref} is not a dictionary')
            continue
        skeys = set()
        for key in list(state[id_]):
            if key.startswith('_'):
                continue
            if not isinstance(state[id_][key], list):
                continue
            if '.' in key:
                comps = key.split('.')
                ref = '.'.join(comps[:-1])
                if ref in skeys:
                    hub.idem.RUNS[name]['errors'].append(
                        f'ID "{id_}" in SLS "{sls_ref}" contains multiple state declarations of the same type'
                        )
                    continue
                state[id_][ref] = state[id_].pop(key)
                state[id_][ref].append(comps[-1])
                skeys.add(ref)
                continue
            skeys.add(key)
        if '__sls__' not in state[id_]:
            state[id_]['__sls__'] = sls_ref


def _tess_product_paths(file_name):
    """ TESS Product File """
    sssss = file_name[18:23]
    zzzz = file_name[24:28]
    ffff = file_name[28:32]
    pppp = file_name[32:36]
    llll = file_name[36:40]
    parts = ['tess', 'public', 'tid', sssss, zzzz, ffff, pppp, llll, file_name]
    return ['/'.join(parts)]


def __getStationName(name, id):
    """Construct a station name."""
    name = name.replace('Meetstation', '')
    name = name.strip()
    name += ' (%s)' % id
    return name


@staticmethod
def _dict_to_list(data_to_convert, color=None):
    """Converts dictionary elements into list.

        Args:
          data_to_convert: dictionary to convert
          color: color code (i.e. '%red%' for each row)

        Returns:
          list with converted data.

        """
    if not isinstance(data_to_convert, dict):
        return data_to_convert
    array = []
    for key, val in data_to_convert.items():
        if color is not None:
            array.append('{color}{key}%reset% : {val}'.format(color=color,
                key=key, val=val))
        else:
            array.append('%s: %s' % (key, val))
    return array


def view_all():
    """Resize view so you can see all logic bricks

    """
    pass


def _open_shelve(shelffn, withclosing=False):
    """
    Opens a shelf file.  If ``withclosing`` is True, it will be opened with
    closing, allowing use like:

        with _open_shelve('somefile',True) as s:
            ...
    """
    import shelve
    import contextlib
    shelf = shelve.open(shelffn, protocol=2)
    if withclosing:
        return contextlib.closing(shelf)
    else:
        return shelf


def notifyDelete(service, nodeIdentifier, subscribers, redirectURI=None):
    """
        Send out node deletion notifications.

        @param service: The entity the notifications will originate from.
        @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: The identifier of the node that was deleted.
        @type nodeIdentifier: C{unicode}
        @param subscribers: The subscribers for which a notification should be
            sent out.
        @type subscribers: C{list} of
            L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param redirectURI: Optional XMPP URI of another node that subscribers
            are redirected to.
        @type redirectURI: C{str}
        """


def fromqpixmap(im):
    """Creates an image instance from a QPixmap image"""
    from . import ImageQt
    if not ImageQt.qt_is_installed:
        raise ImportError('Qt bindings are not installed')
    return ImageQt.fromqpixmap(im)


def add_onetime_fee():
    """Add one time fee to all users in most recent billing cycle"""
    from attbillsplitter.services import add_onetime_fee
    add_onetime_fee()


@staticmethod
def __parse_reason_503_error(content: bytes) ->str:
    """ Parsing the cause of the error from the server response. """
    html: str = content.decode(encoding='UTF-8')
    body_block = html.rsplit('')[-1]
    reason = body_block.rsplit('
Ошибка авторизации: ')[-1].split('
')[0]
    return reason


@staticmethod
def _format_step(step_name, indices, value):
    """Help method for formatting solution step history."""
    return '[{0},{1}] = {2}, {3}'.format(indices[0] + 1, indices[1] + 1,
        value, step_name)


@classmethod
def info(cls, name):
    """ Get information about a vlan."""
    return cls._info(cls.usable_id(name))


@classmethod
def show(cls, sublist='all'):
    """
        Returns a list of the color names

        :param: str sublist: (default='all') options 'colors'/'core'/'neutral'/'all'

        :returns: a list of color names
        :rtype: list

        """
    if sublist is not None:
        if sublist not in ['core', 'neutral', 'colors', 'all']:
            raise Exception(
                'List type can only be "core", "neutral", "colors", or "all"')
    list_ = []
    for color in getattr(cls, sublist):
        list_.append(color)
    return list_


def is_list_block(doc, pos, tokenizer):
    """Returns True if pos is in list block"""
    pos = doc.gettol(pos)
    while pos:
        pos -= 1
        tol = doc.gettol(pos)
        s = doc.gettext(tol, pos).rstrip()
        if not s:
            continue
        token = tokenizer.get_token_at(doc, tol)
        if token is tokenizer.tokens.list:
            return True
        if s[0] not in ['\t ']:
            break
        pos = tol


@staticmethod
def _wrap_uid_bytes(bytestream):
    """Return `bytestream` without any trailing null padding."""
    if bytestream[-1:] == b'\x00':
        return bytestream[:-1]
    return bytestream


def has_decorator(source_lines: list) ->bool:
    """
    Checks if the source code for a function has a decorator or not
    :param source_lines: Source code lines of a function
    :return: True if there is a decorator else False
    """
    return '@' in source_lines[0]


def polygon_from_bounds(bounds):
    """Return a GeoJSON Polygon dict from a (minx, miny, maxx, maxy) tuple"""
    return {'type': 'Polygon', 'coordinates': (((bounds[2], bounds[1]), (
        bounds[2], bounds[3]), (bounds[0], bounds[3]), (bounds[0], bounds[1
        ]), (bounds[2], bounds[1])),)}


def p_quantifier_optional(p):
    """quantifier : K_OPTIONAL"""
    p[0] = [('optional', ())]


def trailing_blank_lines(physical_line, lines, line_number, total_lines):
    """Trailing blank lines are superfluous.

    Okay: spam(1)
    W391: spam(1)\\n

    However the last line should end with a new line (warning W292).
    """
    if line_number == total_lines:
        stripped_last_line = physical_line.rstrip()
        if not stripped_last_line:
            return 0, 'W391 blank line at end of file'
        if stripped_last_line == physical_line:
            return len(physical_line), 'W292 no newline at end of file'


def psi_Ba_K_Cl_PK74(T, P):
    """c-c'-a: barium potassium chloride [PK74]."""
    psi = 0.0
    valid = T == 298.15
    return psi, valid


@classmethod
def makeService(cls, options):
    """
        Create an L{IService} for the parameters and return it
        """
    from ampoule import service
    return service.makeService(options)


@staticmethod
def AllInventoriesInt():
    """
        Get all inventory types as ints.

        Returns:
            list: of int formatted inventory types.
        """
    return [1, 2, 224]


@staticmethod
def get_parallel_inductance(b, w):
    """b : susceptance (siemens)
w : angular frequency (rad/s)
return parallel inductance Lp (henry) if defines"""
    if b is None or b >= 0:
        return None
    return -1 / (b * w)


def update_biomass_coefficients(dict_of_coefficients, model):
    """
    Updates the biomass coefficients given the input metabolite:coefficient dictionary.

    :param dict_of_coefficients: dictionary of metabolites and coefficients

    :param model: model to update

    :return: The biomass objective function is updated.
    """
    from BOFdat import update
    update.update_biomass(dict_of_coefficients, model)


def select_circle(x: int=0, y: int=0, radius: int=1, gesture_mode: int=0):
    """Select markers using circle selection

    :param x: X
    :type x: int
    :param y: Y
    :type y: int
    :param radius: Radius
    :type radius: int
    :param gesture_mode: Gesture Mode
    :type gesture_mode: int
    """
    pass


def get_instrument_variables(ds):
    """
    Returns a list of instrument variables

    :param netCDF4.Dataset ds: An open netCDF4 Dataset
    """
    candidates = []
    for variable in ds.variables:
        instrument = getattr(ds.variables[variable], 'instrument', '')
        if instrument and instrument in ds.variables:
            if instrument not in candidates:
                candidates.append(instrument)
    instrument = getattr(ds, 'instrument', '')
    if instrument and instrument in ds.variables:
        if instrument not in candidates:
            candidates.append(instrument)
    return candidates


def draw_axes(axes, color='black', fontsize=12, linewidth=1.5):
    """Plot axes and annotations of Hudson's MT decomposition diagram."""
    axes.set_axis_off()
    axes.set_aspect(1.0)
    axes.set_xlim(-4.0 / 3.0 - 0.1, 4.0 / 3.0 + 0.1)
    axes.set_ylim(-1.1, 1.1)
    axes.plot([-4.0 / 3.0, 0.0, 4.0 / 3.0, 0.0, -4 / 3.0], [-1.0 / 3.0, -
        1.0, 1.0 / 3.0, 1.0, -1.0 / 3.0], zorder=-1, linewidth=linewidth,
        color=color)
    axes.plot([-1.0, 1.0], [0.0, 0.0], zorder=-1, linewidth=linewidth,
        color=color)
    axes.plot([0.0, 0.0], [-1.0, 1.0], zorder=-1, linewidth=linewidth,
        color=color)
    d = fontsize / 3.0
    for txt, pos, off, va, ha in [('+Isotropic', (0.0, 1.0), (-d, d),
        'bottom', 'right'), ('-Isotropic', (0.0, -1.0), (d, -d), 'top',
        'left'), ('-CLVD', (+1.0, 0.0), (d, -d), 'top', 'left'), ('+CLVD',
        (-1.0, 0.0), (-d, d), 'bottom', 'right')]:
        axes.plot(pos[0], pos[1], 'o', color=color, markersize=fontsize / 2.0)
        axes.annotate(txt, xy=pos, xycoords='data', xytext=off, textcoords=
            'offset points', verticalalignment=va, horizontalalignment=ha,
            rotation=0.0)
    for txt, pos, off, va, ha in [('-Dipole', (2.0 / 3.0, -1.0 / 3.0), (d,
        -d), 'top', 'left'), ('+Dipole', (-2.0 / 3.0, 1.0 / 3.0), (-d, d),
        'bottom', 'right'), ('-Crack', (4.0 / 9.0, -5.0 / 9.0), (d, -d),
        'top', 'left'), ('+Crack', (-4.0 / 9.0, 5.0 / 9.0), (-d, d),
        'bottom', 'right')]:
        axes.plot(pos[0], pos[1], 'o', color=color, markersize=fontsize / 2.0)
        axes.annotate(txt, xy=pos, xycoords='data', xytext=off, textcoords=
            'offset points', verticalalignment=va, horizontalalignment=ha,
            rotation=0.0)


def daily_total_solar_radiation(ra_24_toa, ra_24_toa_flat, diffusion_index,
    trans_24):
    """
    Computes the daily solar radiation at the earth's surface taken
    diffuse and direct solar radiation into account

    .. math ::
        S^{\\downarrow} = I_{diff} \\tau S_{toa,f} +(1-I_{diff}) \\tau S_{toa}

    Parameters
    ----------
    ra_24_toa : float
        daily solar radiation at the top of atmosphere
        :math:`S_{toa}`
        [Wm-2]
    ra_24_toa_flat : float
        daily solar radiation at the top of atmosphere for a flat surface
        :math:`S_{toa,f}`
        [Wm-2]
    diffusion_index : float
        diffusion_index
        :math:`I_{diff}`
        [-]
    trans_24 : float
        daily atmospheric transmissivity
        :math:`\\tau`
        [-]

    Returns
    -------
    ra_24 : float
        daily solar radiation
        :math:`S^{\\downarrow}`
        [Wm-2]

    """
    diffuse = trans_24 * ra_24_toa_flat * diffusion_index
    direct = trans_24 * ra_24_toa * (1 - diffusion_index)
    ra_24 = diffuse + direct
    return ra_24


def _validate_dependencies_met():
    """
    Verifies that PyOpenSSL's package-level dependencies have been met.
    Throws `ImportError` if they are not met.
    """
    from cryptography.x509.extensions import Extensions
    if getattr(Extensions, 'get_extension_for_class', None) is None:
        raise ImportError(
            "'cryptography' module missing required functionality.  Try upgrading to v1.3.4 or newer."
            )
    from OpenSSL.crypto import X509
    x509 = X509()
    if getattr(x509, '_x509', None) is None:
        raise ImportError(
            "'pyOpenSSL' module missing required functionality. Try upgrading to v0.14 or newer."
            )


def _lookup(dic, key):
    """Lookup a key in a dictionary, where None returns an empty string
    but an unmatched key returns a question mark. Used in :class:`G2VarObj`
    """
    if key is None:
        return ''
    elif key == '*':
        return '*'
    else:
        return dic.get(key, '?')


def parse_subcluster(data_dict):
    """Retrieve Subcluster from PhagesDB.

    If for some reason no cluster info is added at the time
    the genome is added to PhagesDB, 'psubcluster' may automatically be
    set to NULL, which gets returned as None.
    If the phage is a Singleton, 'psubcluster' is None.
    If the phage is clustered but not subclustered, 'psubcluster' is None.
    If the phage is clustered and subclustered, 'psubcluster'
    is a dictionary, and one key is the Subcluster data.

    :param data_dict: Dictionary of data retrieved from PhagesDB.
    :type data_dict: dict
    :returns: Subcluster of the phage.
    :rtype: str
    """
    try:
        if data_dict['psubcluster'] is None:
            subcluster = 'none'
        else:
            subcluster = data_dict['psubcluster']['subcluster']
    except:
        subcluster = ''
    return subcluster


@classmethod
def get_image_variant_attributes_pattern(cls):
    """
        Return list of patterns to match the available variant attributes.

        :return: list Contains the patterns to match the available variant attributes.
        """
    return [cls.VariantAttributePattern('color', '-c:(?P<{}>\\w+)', None),
        cls.VariantAttributePattern('size', '-s:(?P<{}>\\w+)', None)]


def default_add_one_res_2_all_res2(one_res: list, all_res: list) ->list:
    """
    默认函数2: one_res 增加到all_res
    :param one_res:
    :param all_res:
    :return:
    """
    for i in one_res:
        all_res.append(i)
    return all_res


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

        :param GroupDescriptionUpdatedType val:
        :rtype: EventType
        """
    return cls('group_description_updated', val)


def Type():
    """Return the resource type

        Return a human-readable type name for the resource.

        The first unqualified Dublin Core `Type` element value is
        returned as a unicode string if an unqualified element is
        defined, otherwise, an empty unicode string is returned.
        """


def setup_extra_parser(parser):
    """for dictknife.cliutils.extraarguments"""
    return parser


def ipynb_vega_init():
    """Initialize the IPython notebook display elements

    This function borrows heavily from the excellent vincent package:
    http://github.com/wrobstory/vincent
    """
    try:
        from IPython.core.display import display, HTML
    except ImportError:
        print('IPython Notebook could not be loaded.')
    require_js = """
    if (window['d3'] === undefined) {{
        require.config({{ paths: {{d3: "http://d3js.org/d3.v3.min"}} }});
        require(["d3"], function(d3) {{
          window.d3 = d3;
          {0}
        }});
    }};
    if (window['topojson'] === undefined) {{
        require.config(
            {{ paths: {{topojson: "http://d3js.org/topojson.v1.min"}} }}
            );
        require(["topojson"], function(topojson) {{
          window.topojson = topojson;
        }});
    }};
    """
    d3_geo_projection_js_url = 'http://d3js.org/d3.geo.projection.v0.min.js'
    d3_layout_cloud_js_url = (
        'http://wrobstory.github.io/d3-cloud/d3.layout.cloud.js')
    topojson_js_url = 'http://d3js.org/topojson.v1.min.js'
    vega_js_url = 'http://trifacta.github.com/vega/vega.js'
    dep_libs = (
        """$.getScript("%s", function() {
        $.getScript("%s", function() {
            $.getScript("%s", function() {
                $.getScript("%s", function() {
                        $([IPython.events]).trigger("vega_loaded.vincent");
                })
            })
        })
    });"""
         % (d3_geo_projection_js_url, d3_layout_cloud_js_url,
        topojson_js_url, vega_js_url))
    load_js = require_js.format(dep_libs)
    html = '<script>' + load_js + '</script>'
    display(HTML(html))


def validate(action, data):
    """The default form validator

        If an action is submitted and the action doesn't have it's own
        validator then this function will be called.
        """


def html_email(email, title=None):
    """
    >>> html_email('username@example.com')
    'username@example.com'
    """
    if not title:
        title = email
    return '{title}'.format(email=email, title
        =title)


@classmethod
def least_significant_bit(cls, value):
    """
        Computes the least-significant bit of the specified ``long``
        that is set to ``1``. Zero-indexed.

        See <http://stackoverflow.com/questions/757059/position-of-least-significant-bit-that-is-set>
        and <http://www-graphics.stanford.edu/~seander/bithacks.html>.

        :param long value: the ``long`` whose least-significant bit is desired.
        :returns: the least-significant bit of the specified ``long``.
                  ``-1`` is returned if there are no bits set.
        :rtype: int
        """
    if value == 0:
        return -1
    elif value & 255 != 0:
        index = int(cls.unsigned_right_shift_long(value, 0) & 255)
        return cls.LEAST_SIGNIFICANT_BIT[index] + 0
    elif value & 65535 != 0:
        index = int(cls.unsigned_right_shift_long(value, 8) & 255)
        return cls.LEAST_SIGNIFICANT_BIT[index] + 8
    elif value & 16777215 != 0:
        index = int(cls.unsigned_right_shift_long(value, 16) & 255)
        return cls.LEAST_SIGNIFICANT_BIT[index] + 16
    elif value & 4294967295 != 0:
        index = int(cls.unsigned_right_shift_long(value, 24) & 255)
        return cls.LEAST_SIGNIFICANT_BIT[index] + 24
    elif value & 1099511627775 != 0:
        index = int(cls.unsigned_right_shift_long(value, 32) & 255)
        return cls.LEAST_SIGNIFICANT_BIT[index] + 32
    elif value & 281474976710655 != 0:
        index = int(cls.unsigned_right_shift_long(value, 40) & 255)
        return cls.LEAST_SIGNIFICANT_BIT[index] + 40
    elif value & 72057594037927935 != 0:
        index = int(cls.unsigned_right_shift_long(value, 48) & 255)
        return cls.LEAST_SIGNIFICANT_BIT[index] + 48
    else:
        index = int(cls.unsigned_right_shift_long(value, 56) & 255)
        return cls.LEAST_SIGNIFICANT_BIT[index] + 56


def save(sel_filename, version, time, scans, no_sensors, duration, sensors,
    scale_factors=None):
    """Create HAWC2 sel-file

    Parameters
    ----------
    sel_filename : str
        Filename
    version : str
        Version tag
    time : datetime.datetime
        Date and time of creation
    scans : int
        Number of scans/observations/rows
    no_sensors : int
        Number of sensors/channels/columns
    duration : int, float
        Duration of simulation
    sensors : array_like
        List of (name, unit, description)-tuples
    scale_factors : array_like, optional
        Array of scale factors. Only for BINARY format
    """
    lines = []
    linesep = '_' * 120
    lines.append(linesep)
    lines.append('  Version ID : %s' % version)
    lines.append(' ' * 60 + 'Time : %s' % time.strftime('%H:%M:%S'))
    lines.append(' ' * 60 + 'Date : %s' % time.strftime('%d:%m.%Y'))
    lines.append(linesep)
    lines.append('  Result file : %s.dat' % sel_filename[:-4])
    lines.append(linesep)
    lines.append('   Scans    Channels    Time [sec]      Format')
    lines.append('   %8s    %3s       %8.3f       %s' % (scans, no_sensors,
        duration, ('BINARY', 'ASCII')[scale_factors is None]))
    lines.append('')
    lines.append('  Channel   Variable Description               ')
    lines.append('')
    for nr, sensor in enumerate(sensors, 1):
        name, unit, description = sensor
        lines.append('  %4s      %-30s %-10s %s' % (nr, name[:30], unit[:10
            ], description[:512]))
    lines.append(linesep)
    if scale_factors is not None:
        lines.append('Scale factors:')
        for sf in scale_factors:
            lines.append('  %.5E' % sf)
    with open(sel_filename, 'w', encoding='utf-8') as f:
        f.write('\n'.join(lines))


def add(name, other, send_events=True, reserved_names=(), duplicating=None,
    moving=None, loading=False, registry=None):
    """ Same as ``__setitem__``.

        If ``send_events`` is false, suppress the sending of folder events.
        Disallow the addition of the name provided is in the ``reserved_names``
        list.  If ``duplicating`` is not None, it must be the object being
        duplicated; when non-None, the ObjectWillBeAdded and ObjectAdded events
        sent will be marked as 'duplicating', which typically has the effect
        that the subobject's object id will be overwritten instead of reused.
        If ``registry`` is passed, it should be a Pyramid registry object;
        otherwise the :func:`pyramid.threadlocal.get_current_registry`
        function is used to look up the current registry.

        This method returns the name used to place the subobject in the
        folder (a derivation of ``name``, usually the result of
        ``self.check_name(name)``).
        """


@staticmethod
def from_onnx(parameters=None, attributes=None):
    """
        Constructs a CrypTen model from an ONNX Protobuf string or file.
        """
    raise NotImplementedError('Call this function on a Module type.')


def convert_flags(flags, flag_dict, logger):
    """ Bitwise-OR of flags in conf and convert them to the readable flags """
    flaglist = []
    flagstr = ''
    logger.info('The given flags are %s ' % flags)
    if '|' not in flags:
        flagn = int(flags)
        flaglist.append(flagn)
    else:
        flaglist = flags.split('|')
        flagn = 0
        for flag in flaglist:
            flagn |= int(flag)
    for flag_key in flaglist:
        if int(flag_key) in flag_dict:
            flagstr += flag_dict.get(int(flag_key))
    logger.info('Converted flags:' + flagstr if flagstr != '' else 'no flag')
    return flaglist, flagn


def check_availability_linux_binaries():
    """Returns False or True depending on the availability of programs."""
    return True


@staticmethod
def hover_and_click(element):
    """ hover/move cursor to element and click
        :type element: WebElement
        :rtype: WebDriver
        """
    return element.hover_and_click()


@classmethod
def get_format_string(cls):
    """See BranchFormat.get_format_string()."""
    return b'Bazaar Branch Format 6 (bzr 0.15)\n'


def _volume(shape):
    """Return the volume of a shape."""
    prod = 1
    for start, stop in shape:
        prod *= stop - start
    return prod


@staticmethod
def handle_leap_ti(ti, drop_leap=False):
    """Handle a time index for a leap year by dropping a day.

        Parameters
        ----------
        ti : pandas.DatetimeIndex
            Time-series datetime index with or without a leap day.
        drop_leap : bool
            Option to drop leap day (if True) or drop the last day of the year
            (if False).

        Returns
        -------
        ti : pandas.DatetimeIndex
            Time-series datetime index with length a multiple of 365.
        """
    leap_day = (ti.month == 2) & (ti.day == 29)
    last_day = (ti.month == 12) & (ti.day == 31)
    if drop_leap:
        ti = ti.drop(ti[leap_day])
    elif any(leap_day):
        ti = ti.drop(ti[last_day])
    if len(ti) % 365 != 0:
        raise ValueError('Bad time index with length not a multiple of 365: {}'
            .format(ti))
    return ti


@staticmethod
def can_handle(content_type_name):
    """
        given a content type, returns true if this serializer
        can convert bodies of the given type.
        """
    return 'yaml' in content_type_name


def user_input(text: 'str', choices: 'Iterable[str]', default: 'str'=None,
    selection: 'str'='') ->'str':
    """ Default can be a selection from choice and allows empty input. """
    while True:
        selection = input(text).strip().lower()
        if selection != '' and selection in choices:
            break
        if selection == '' and default is not None:
            selection = default
            break
    return selection


def shorten_citekey(standard_citekey):
    """
    Return a shortened citekey derived from the input citekey.
    The input citekey should be standardized prior to this function,
    since differences in the input citekey will result in different shortened citekeys.
    Short citekeys are generated by converting the input citekey to a 6 byte hash,
    and then converting this digest to a base62 ASCII str. Shortened
    citekeys consist of characters in the following ranges: 0-9, a-z and A-Z.
    """
    import hashlib
    import base62
    assert not standard_citekey.startswith('@')
    as_bytes = standard_citekey.encode()
    blake_hash = hashlib.blake2b(as_bytes, digest_size=6)
    digest = blake_hash.digest()
    short_citekey = base62.encodebytes(digest)
    return short_citekey


def dummy():
    """Dummy function to make sure docstrings don't get rendered as text"""
    pass


def Reset():
    """Reset global state.  Used by unit tests that end up using
    SConsign multiple times to get a clean slate for each test."""
    global sig_files, DB_sync_list
    sig_files = []
    DB_sync_list = []


def calc_times(z_int, vp_mod):
    """
    t_int = calc_times(z_int, vp_mod)
    """
    nlayers = len(vp_mod)
    nint = nlayers - 1
    t_int = []
    for i in range(0, nint):
        if i == 0:
            tbuf = z_int[i] / vp_mod[i]
            t_int.append(tbuf)
        else:
            zdiff = z_int[i] - z_int[i - 1]
            tbuf = 2 * zdiff / vp_mod[i] + t_int[i - 1]
            t_int.append(tbuf)
    return t_int


@classmethod
def telefono_valido(cls, telefono):
    """Verificador de numeros de telefono validos.

        Argumento:
            telefono {str}

        Retorno:
            bool -- True si pasa la verificacion, de lo contraio False.
        """
    if len(telefono) != 12:
        return False
    for i in range(0, 3):
        if not telefono[i].isdecimal():
            return False
    if telefono[3] != '-':
        return False
    for i in range(4, 7):
        if not telefono[i].isdecimal():
            return False
    if telefono[7] != '-':
        return False
    for i in range(8, 12):
        if not telefono[i].isdecimal():
            return False
    return True


def plugin_factory():
    """ A factory function which returns a plain Plugin instance.

    """
    from .plugin import Plugin
    return Plugin()


def delete_trail(Name=None):
    """
    Deletes a trail. This operation must be called from the region in which the trail was created. DeleteTrail cannot be called on the shadow trails (replicated trails in other regions) of a trail that is enabled in all regions.
    See also: AWS API Documentation

    :example: response = client.delete_trail(
        Name='string'
    )

    :type Name: string
    :param Name: [REQUIRED]
            Specifies the name or the CloudTrail ARN of the trail to be deleted. The format of a trail ARN is: arn:aws:cloudtrail:us-east-1:123456789012:trail/MyTrail

    :rtype: dict
    :return: {}

    """
    pass


def iter_except(func, exception, first_=None):
    """ Call a function repeatedly until an exception is raised.

    Converts a call-until-exception interface to an iterator interface.
    Like __builtin__.iter(func, sentinel) but uses an exception instead
    of a sentinel to end the loop.

    Examples:
        # priority queue iterator
        iter_except(functools.partial(heappop, h), IndexError)

        # non-blocking dict iterator
        iter_except(d.popitem, KeyError)

        # non-blocking deque iterator
        iter_except(d.popleft, IndexError)

        # loop over a producer Queue
        iter_except(q.get_nowait, Queue.Empty)

        # non-blocking set iterator
        iter_except(s.pop, KeyError)

    http://docs.python.org/3.4/library/itertools.html#itertools-recipes
    """
    try:
        if first_ is not None:
            yield first_()
        while 1:
            yield func()
    except exception:
        pass


def straighten(s, length, align_left=True, delimiter=' '):
    """Straighten a Unicode string to have a fixed length.

    :Parameters:
        s : str
            string to be trimmed
        length : int
            number of characters of the output string
        align_left : bool
            whether to align the string to the left (True) or to the right (False)
        delimiter : char
            the whitespace character to fill in if the length input string is shorter than the output length

    :Returns:
        retval : str
            straightened string

    :Examples:

    >>> from mt.base.str import straighten
    >>> straighten('Hello world', 7)
    'Hello …'
    >>> straighten('Hi there', 3, align_left=False)
    '…re'
    >>> straighten("Oh Carol!", 20, align_left=False)
    '           Oh Carol!'
    """
    if not isinstance(s, str):
        raise ValueError('Input is not a string: {}'.format(s))
    if length < 0:
        raise ValueError('Output length must be non-negative, received {}'.
            format(length))
    if not isinstance(delimiter, str) or len(delimiter) != 1:
        raise ValueError(
            "Expecting delimiter to be a single character, but '{}' received."
            .format(delimiter))
    in_len = len(s)
    if in_len == length:
        return s
    if in_len < length:
        if align_left:
            return s + delimiter * (length - in_len)
        return delimiter * (length - in_len) + s
    if length == 1:
        return '…'
    if align_left:
        return s[:length - 1] + '…'
    return '…' + s[in_len - length + 1:]


def withinPro(file2, mutation):
    """ PTMs (predicted) involved in the crosstalk within a given protein at baker's years (Minguez el 2012)"""
    with open('within_protein.txt', 'w') as file1:
        with open(file2, 'rU') as f:
            for l in f:
                line = l.split()
                if len(line) > 19:
                    take = line[15] + '\t' + line[16] + '\t' + line[3
                        ] + '\t' + line[17] + '\t' + line[7] + '\t' + line[19]
                    take = take.split()
                    with open(mutation, 'r') as mu:
                        for m in mu:
                            m = m.split()
                            if m[0] == take[1] and m[1] == take[3]:
                                take2 = take[0] + '\t' + take[1] + '\t' + take[
                                    2] + '\t' + take[3] + '\t' + 'PTMcode'
                                fi = take2.split()
                                with open('yeastID.txt') as id:
                                    for di in id:
                                        di = di.split()
                                        if len(di) > 2 and di[2] == fi[1]:
                                            summary = open('summary.txt', 'a+')
                                            summary.write(di[0] + '\t' + di[2] +
                                                '\t' + fi[3] + '\t' + fi[2] + '\t' +
                                                'WithinProtein' + '\t' + 'PTMcode' +
                                                '\n')
                                            if take2 > str(0):
                                                with open('within_protein.txt', 'a'
                                                    ) as file1:
                                                    file1.write(take2 + '\n')
                                                    continue
                            if m[0] == take[1] and m[1] == take[5]:
                                take3 = take[0] + '\t' + take[1] + '\t' + take[
                                    4] + '\t' + take[5] + '\t' + 'PTMcode'
                                fi = take3.split()
                                with open('yeastID.txt') as id:
                                    for di in id:
                                        di = di.split()
                                        if len(di) > 2 and di[2] == fi[1]:
                                            summary = open('summary.txt', 'a+')
                                            summary.write(di[0] + '\t' + di[2] +
                                                '\t' + fi[3] + '\t' + fi[2] + '\t' +
                                                'WithinProtein' + '\t' + 'PTMcode' +
                                                '\n')
                                            if take3 > str(0):
                                                with open('within_protein.txt', 'a+'
                                                    ) as file1:
                                                    file1.write(take3 + '\n')


def searchMyIssues(**query):
    """Returns a list of issues for the current user that satify the
        query."""


@classmethod
def class_name(cls):
    """ Returns the name of the class. The name of the class is also the
            default collection name.

            .. seealso:: :func:`~Document.get_collection_name`
        """
    return cls.__name__


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


def is_liked(item_type, item_id, user_id=None):
    """Does <user_id> like <item_type> <item_id>?"""


def autodec(fwhm):
    """
    Automatically calculates the appropriate decimal place to track based on a full-width-at-half-maximum

    :param fwhm: full-width-at-half-maximum
    :return: decimal power
    :rtype: int
    """
    shift = fwhm
    n = 0
    while shift < 1.0:
        n += 1
        shift = fwhm * 10 ** n
    return n + 1


def describe_orderable_cluster_options(ClusterVersion=None, NodeType=None,
    MaxRecords=None, Marker=None):
    """
    Returns a list of orderable cluster options. Before you create a new cluster you can use this operation to find what options are available, such as the EC2 Availability Zones (AZ) in the specific AWS region that you can specify, and the node types you can request. The node types differ by available storage, memory, CPU and price. With the cost involved you might want to obtain a list of cluster options in the specific region and specify values when creating a cluster. For more information about managing clusters, go to Amazon Redshift Clusters in the Amazon Redshift Cluster Management Guide .
    See also: AWS API Documentation

    :example: response = client.describe_orderable_cluster_options(
        ClusterVersion='string',
        NodeType='string',
        MaxRecords=123,
        Marker='string'
    )

    :type ClusterVersion: string
    :param ClusterVersion: The version filter value. Specify this parameter to show only the available offerings matching the specified version.
            Default: All versions.
            Constraints: Must be one of the version returned from DescribeClusterVersions .

    :type NodeType: string
    :param NodeType: The node type filter value. Specify this parameter to show only the available offerings matching the specified node type.

    :type MaxRecords: integer
    :param MaxRecords: The maximum number of response records to return in each call. If the number of remaining response records exceeds the specified MaxRecords value, a value is returned in a marker field of the response. You can retrieve the next set of records by retrying the command with the returned marker value.
            Default: 100
            Constraints: minimum 20, maximum 100.

    :type Marker: string
    :param Marker: An optional parameter that specifies the starting point to return a set of response records. When the results of a DescribeOrderableClusterOptions request exceed the value specified in MaxRecords , AWS returns a value in the Marker field of the response. You can retrieve the next set of response records by providing the returned marker value in the Marker parameter and retrying the request.

    :rtype: dict
    :return: {
        'OrderableClusterOptions': [
            {
                'ClusterVersion': 'string',
                'ClusterType': 'string',
                'NodeType': 'string',
                'AvailabilityZones': [
                    {
                        'Name': 'string'
                    },
                ]
            },
        ],
        'Marker': 'string'
    }

    """
    pass


@staticmethod
def save_image(image_content: bytes, save_to: str):
    """Save image bytes ti file"""
    with open(save_to, 'wb') as image_file:
        image_file.write(image_content)


def model_device(model):
    """Determine the device the model is allocated on."""
    try:
        return str(next(model.parameters()).device)
    except StopIteration:
        pass
    return 'cpu'


def lambd_NH3_ClO3_CB89(T, P):
    """n-a: ammonia chlorate [CB89]."""
    lambd = -0.004
    valid = T == 298.15
    return lambd, valid


def elemwise_div(lhs=None, rhs=None, out=None, name=None, **kwargs):
    """Divides arguments element-wise.

    The storage type of ``elemwise_div`` output is always dense

    Parameters
    ----------
    lhs : NDArray
        first input
    rhs : NDArray
        second input

    out : NDArray, optional
        The output NDArray to hold the result.

    Returns
    -------
    out : NDArray or list of NDArrays
        The output of this function.
    """
    return 0,


def reduce_sum(input):
    """Returns the sum of all elements in the input tensor.

    Parameters
    ----------
    input : Tensor
        The input tensor.

    Returns
    -------
    Tensor
        A framework-specific tensor with shape (1,)
    """
    pass


def _merge_lib_dict(d1, d2):
    """ Merges lib_dict `d2` into lib_dict `d1`
    """
    for required, requirings in d2.items():
        if required in d1:
            d1[required].update(requirings)
        else:
            d1[required] = requirings
    return None


def is_primitive(value):
    """
    Checks if value if a python primitive
    :param value:
    :return:
    """
    return type(value) in (int, float, bool, str)


@classmethod
def _get_element(cls, container, index, default):
    """Get an element from the container if it exists, otherwise return
        the default.

        Args:
            container (obj): Object that should be returned from.
            index (obj): Index of element that should be returned.
            default (obj): Default that should be returned if the index is not
                in the container.

        Returns:
            object: Container contents at specified element.

        """
    out = default
    if cls._has_element(container, index):
        out = container[index]
    return out


def row_normalization(data):
    """
    Perform z-normalization on all rows
    """
    data_mu = data.mean(axis=1, keepdims=True)
    data_sigma = data.std(axis=1, keepdims=True)
    data_sigma[data_sigma == 0] = 1.0
    return (data - data_mu) / data_sigma


def validate(item, **kwargs):
    """Checks if item has take_key value"""
    if not item.get('anpa_take_key', '').strip():
        raise KeyError('Take key cannot be empty!')
    return item


def componentName():
    """
    This provide the name of the module component to be associated to the study.
    """
    return 'ADAO'


def register(viewer):
    """
        Register the *viewer* to be tracked by this object.

        A matching call to :meth:`unregister` is expected.
        """


def _inverse_transform(pca, data):
    """
    Inverse transform on PCA.

    Use PCA's `project` method by temporary replacing its factors with
    `data`.

    Parameters
    ----------
    pca : statsmodels Principal Component Analysis instance
        The PCA object to use.
    data : sequence of ndarrays or 2-D ndarray
        The vectors of functions to create a functional boxplot from.  If a
        sequence of 1-D arrays, these should all be the same size.
        The first axis is the function index, the second axis the one along
        which the function is defined.  So ``data[0, :]`` is the first
        functional curve.

    Returns
    -------
    projection : array
        nobs by nvar array of the projection onto ncomp factors

    """
    factors = pca.factors
    pca.factors = data.reshape(-1, factors.shape[1])
    projection = pca.project()
    pca.factors = factors
    return projection


def button_start_pressed(controller):
    """
    Callback function that is triggered, when the start button was pressed

    :param controller:              the controller that triggered the action
    :type controller:               steuer.Controller
    """
    print('ACTION:' + str(controller.number) + ':' + controller.name +
        ':Button Start pressed')


@classmethod
def from_registry(cls, schema_type, schema_classes, **kwargs):
    """Construct a ComponentSchema from a registry entry.

        Args:
            schema_type (str): Name of component type to build.
            schema_classes (list): List of classes for the component type.
            **kwargs: Additional keyword arguments are passed to the class
                __init__ method.

        Returns:
            ComponentSchema: Schema with information from classes.

        """
    out = None
    for x in schema_classes.values():
        if out is None:
            out = cls(schema_type, x._schema_subtype_key, **kwargs)
        out.append(x)
    return out


@staticmethod
def get_subtype(object_dictionary):
    """
        Given the hash representation of a subtype of this class,
        use the info in the hash to return the class of the subtype.
        """
    type = object_dictionary['source']
    if type == 'DATABASE':
        return 'CreateAutonomousDatabaseCloneDetails'
    if type == 'BACKUP_FROM_ID':
        return 'CreateAutonomousDatabaseFromBackupDetails'
    if type == 'BACKUP_FROM_TIMESTAMP':
        return 'CreateAutonomousDatabaseFromBackupTimestampDetails'
    if type == 'NONE':
        return 'CreateAutonomousDatabaseDetails'
    else:
        return 'CreateAutonomousDatabaseBase'


@staticmethod
def interpolate(dq0, dq1, t):
    """Return the interpolation of two DualQuaternions.

        This uses the Dual Quaternion Linear Blending Method as described by Matthew Smith's
        'Applications of Dual Quaternions in Three Dimensional Transformation and Interpolation'
        https://www.cosc.canterbury.ac.nz/research/reports/HonsReps/2013/hons_1305.pdf

        Parameters
        ----------
        dq0 : :obj:`DualQuaternion`
            The first DualQuaternion.

        dq1 : :obj:`DualQuaternion`
            The second DualQuaternion.

        t : float
            The interpolation step in [0,1]. When t=0, this returns dq0, and
            when t=1, this returns dq1.

        Returns
        -------
        :obj:`DualQuaternion`
            The interpolated DualQuaternion.

        Raises
        ------
        ValueError
            If t isn't in [0,1].
        """
    if not 0 <= t <= 1:
        raise ValueError('Interpolation step must be between 0 and 1! Got {0}'
            .format(t))
    dqt = dq0 * (1 - t) + dq1 * t
    return dqt.normalized


@classmethod
def get_row_permission(cls, obj, ar, state, ba):
    """Returns True if the given action is allowed for the given instance
        `obj` and the given user.

        """
    if obj is None:
        return True
    return obj.get_row_permission(ar, state, ba)


@classmethod
def _get_elliptic_curves(cls, lib):
    """
        Get, cache, and return the curves supported by OpenSSL.

        :param lib: The OpenSSL library binding object.

        :return: A :py:type:`set` of ``cls`` instances giving the names of the
            elliptic curves the underlying library supports.
        """
    if cls._curves is None:
        cls._curves = cls._load_elliptic_curves(lib)
    return cls._curves


def ansi_color_to_black(s):
    """
    convert ansi color to blank
    https://github.com/shiena/ansicolor
    :param s:
    :return:
    """
    s = s.replace('\\u001b[91m', '')
    s = s.replace('\\u001b[0m', '')
    return s


def _handle_shape(X, t, name):
    """My version of the shape extracting function. """
    if name == 'obs_mat':
        if len(X.shape) == 4:
            return X[t, ...]
        else:
            return X


@classmethod
def create_ikepolicy(cls, name):
    """Wrapper utility that returns a test ike policy."""
    body = cls.client.create_ikepolicy(name=name)
    ikepolicy = body['ikepolicy']
    cls.ikepolicies.append(ikepolicy)
    return ikepolicy


def default_filter(src, dst):
    """The default progress/filter callback; returns True for all files"""
    return dst


def get_facts(device):
    """
    Doesn't get any facts.
    """
    return {}


def get_pipeline(name=None, version=None):
    """
    Returns the metadata, structure, stages, and actions of a pipeline. Can be used to return the entire structure of a pipeline in JSON format, which can then be modified and used to update the pipeline structure with  UpdatePipeline .
    See also: AWS API Documentation

    :example: response = client.get_pipeline(
        name='string',
        version=123
    )

    :type name: string
    :param name: [REQUIRED]
            The name of the pipeline for which you want to get information. Pipeline names must be unique under an Amazon Web Services (AWS) user account.

    :type version: integer
    :param version: The version number of the pipeline. If you do not specify a version, defaults to the most current version.

    :rtype: dict
    :return: {
        'pipeline': {
            'name': 'string',
            'roleArn': 'string',
            'artifactStore': {
                'type': 'S3',
                'location': 'string',
                'encryptionKey': {
                    'id': 'string',
                    'type': 'KMS'
                }
            },
            'stages': [
                {
                    'name': 'string',
                    'blockers': [
                        {
                            'name': 'string',
                            'type': 'Schedule'
                        },
                    ],
                    'actions': [
                        {
                            'name': 'string',
                            'actionTypeId': {
                                'category': 'Source'|'Build'|'Deploy'|'Test'|'Invoke'|'Approval',
                                'owner': 'AWS'|'ThirdParty'|'Custom',
                                'provider': 'string',
                                'version': 'string'
                            },
                            'runOrder': 123,
                            'configuration': {
                                'string': 'string'
                            },
                            'outputArtifacts': [
                                {
                                    'name': 'string'
                                },
                            ],
                            'inputArtifacts': [
                                {
                                    'name': 'string'
                                },
                            ],
                            'roleArn': 'string'
                        },
                    ]
                },
            ],
            'version': 123
        }
    }

    :returns:
    (string) --
    (string) --

    """
    pass


def deregister_container_instance(cluster=None, containerInstance=None,
    force=None):
    """
    Deregisters an Amazon ECS container instance from the specified cluster. This instance is no longer available to run tasks.
    If you intend to use the container instance for some other purpose after deregistration, you should stop all of the tasks running on the container instance before deregistration to avoid any orphaned tasks from consuming resources.
    Deregistering a container instance removes the instance from a cluster, but it does not terminate the EC2 instance; if you are finished using the instance, be sure to terminate it in the Amazon EC2 console to stop billing.
    See also: AWS API Documentation

    Examples
    This example deregisters a container instance from the specified cluster in your default region. If there are still tasks running on the container instance, you must either stop those tasks before deregistering, or use the force option.
    Expected Output:

    :example: response = client.deregister_container_instance(
        cluster='string',
        containerInstance='string',
        force=True|False
    )

    :type cluster: string
    :param cluster: The short name or full Amazon Resource Name (ARN) of the cluster that hosts the container instance to deregister. If you do not specify a cluster, the default cluster is assumed.

    :type containerInstance: string
    :param containerInstance: [REQUIRED]
            The container instance ID or full Amazon Resource Name (ARN) of the container instance to deregister. The ARN contains the arn:aws:ecs namespace, followed by the region of the container instance, the AWS account ID of the container instance owner, the container-instance namespace, and then the container instance ID. For example, ``arn:aws:ecs:region :aws_account_id :container-instance/container_instance_ID `` .

    :type force: boolean
    :param force: Forces the deregistration of the container instance. If you have tasks running on the container instance when you deregister it with the force option, these tasks remain running until you terminate the instance or the tasks stop through some other means, but they are orphaned (no longer monitored or accounted for by Amazon ECS). If an orphaned task on your container instance is part of an Amazon ECS service, then the service scheduler starts another copy of that task, on a different container instance if possible.
            Any containers in orphaned service tasks that are registered with a Classic load balancer or an Application load balancer target group are deregistered, and they will begin connection draining according to the settings on the load balancer or target group.

    :rtype: dict
    :return: {
        'containerInstance': {
            'containerInstanceArn': 'string',
            'ec2InstanceId': 'string',
            'version': 123,
            'versionInfo': {
                'agentVersion': 'string',
                'agentHash': 'string',
                'dockerVersion': 'string'
            },
            'remainingResources': [
                {
                    'name': 'string',
                    'type': 'string',
                    'doubleValue': 123.0,
                    'longValue': 123,
                    'integerValue': 123,
                    'stringSetValue': [
                        'string',
                    ]
                },
            ],
            'registeredResources': [
                {
                    'name': 'string',
                    'type': 'string',
                    'doubleValue': 123.0,
                    'longValue': 123,
                    'integerValue': 123,
                    'stringSetValue': [
                        'string',
                    ]
                },
            ],
            'status': 'string',
            'agentConnected': True|False,
            'runningTasksCount': 123,
            'pendingTasksCount': 123,
            'agentUpdateStatus': 'PENDING'|'STAGING'|'STAGED'|'UPDATING'|'UPDATED'|'FAILED',
            'attributes': [
                {
                    'name': 'string',
                    'value': 'string',
                    'targetType': 'container-instance',
                    'targetId': 'string'
                },
            ],
            'registeredAt': datetime(2015, 1, 1)
        }
    }

    :returns:
    (string) --

    """
    pass


def GetScriptExecutionStationName(*args, **kwargs):
    """ Stub Anduin function."""
    print('GetScriptExecutionStationName', args, kwargs)


def _create_valid_graph(graph):
    """Sets all weights of edges for different edges as 1, inplace.

    Parameters
    ----------
    graph : :class:`~gensim.summarization.graph.Graph`
        Given graph.

    """
    nodes = graph.nodes()
    for i in range(len(nodes)):
        for j in range(len(nodes)):
            if i == j:
                continue
            edge = nodes[i], nodes[j]
            if graph.has_edge(edge):
                graph.del_edge(edge)
            graph.add_edge(edge, 1)


def default_sipmetadata_name_formatter(sipmetadata):
    """Default generator for the SIPMetadata filenames."""
    return '{name}.{format}'.format(name=sipmetadata.type.name, format=
        sipmetadata.type.format)


def __sub__(a, b):
    """ Return the subtraction of *a* with *b*. """
    return a.clone().subtract(b)


def get_engine(cls, current_app):
    """Proxy for compatibility with flask-debugtoolbar
        """
    databases = getattr(current_app, 'databases', None)
    if not databases:
        return None
    return databases[0].engine


def remove_weekends(data):
    """ Return Series/DataFrame with weekend dates removed """
    return data[data.index.weekday < 5]


def update(label_id, title, color, by_user):
    """Updates the label with ID ``label_id``.
        Raises a ``KeyError`` when there is no such label.
        """


def axis_lengths(ax):
    """
    Takes a matplotlib axis and returns the length of the axes
    :param ax: The Axes instance to find the lengths of
    :return: length of x and y axis
    """
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()
    dx = abs(xlim[1] - xlim[0])
    dy = abs(ylim[1] - ylim[0])
    return dx, dy


def printline(line):
    """Function to simmulate appending to a plainText widget."""
    print(line, end=' ')


def correct_negative_bg(y_bg_rm, bg):
    """
    function to shift the bg and the y data with the bg removed up if there are negative values.
    :param y_bg_rm: the y data with bg removed
    :param bg: the bg as an np array
    :return:
    """
    y_min = y_bg_rm.min()
    if y_min < 0:
        y_bg_rm += abs(y_min)
        bg -= abs(y_min)
    return y_bg_rm, bg


def relative_script(lines):
    """Return a script that'll work in a relocatable environment."""
    activate = (
        "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); exec(compile(open(activate_this).read(), activate_this, 'exec'), dict(__file__=activate_this)); del os, activate_this"
        )
    activate_at = None
    for idx, line in reversed(list(enumerate(lines))):
        if line.split()[:3] == ['from', '__future__', 'import']:
            activate_at = idx + 1
            break
    if activate_at is None:
        activate_at = 1
    return lines[:activate_at] + ['', activate, ''] + lines[activate_at:]


def scatter_props(event):
    """
    Get information for a pick event on a PathCollection artist (usually
    created with ``scatter``).

    Parameters
    -----------
    event : PickEvent
        The pick event to process

    Returns
    --------
    A dict with keys:
        `c`: The value of the color array at the point clicked.
        `s`: The value of the size array at the point clicked.
        `z`: Identical to `c`. Specified for convenience.

    Notes
    -----
    If constant values were specified to ``c`` or ``s`` when calling
    ``scatter``, `c` and/or `z` will be ``None``.
    """
    ind = event.ind[0]
    try:
        sizes = event.artist.get_sizes()
    except AttributeError:
        sizes = None
    if sizes is None or len(sizes) == 1:
        s = None
    else:
        s = sizes[ind]
    try:
        xorig, yorig = event.artist.get_offsets().T
        x, y = xorig[ind], yorig[ind]
        return dict(x=x, y=y, s=s)
    except IndexError:
        return dict(s=s)


def pt2str(point):
    """Return prettier string version of point tuple.

    >>> pt2str((1.8, 1.9))
    '(1.8, 1.9)'

    """
    return '(%s, %s)' % (str(point[0]), str(point[1]))


def imageToPlot(row, col, origin=(0.0, 0.0), scale=(1.0, 1.0)):
    """Convert a position from image to plot coordinates.

    :param row: Row coordinate(s) in image.
    :type row: int or numpy.ndarray
    :param col: Column coordinate(s) in image.
    :type col: int or numpy.ndarray
    :param origin: Origin of the image in the plot.
    :type origin: 2-tuple of float: (ox, oy).
    :param scale: Scale of the image in the plot.
    :type scale: 2-tuple of float: (sx, sy).
    :return: Position in the image.
    :rtype: 2-tuple of float or numpy.ndarray: (x, y).
    """
    x = origin[0] + col * scale[0]
    y = origin[1] + row * scale[1]
    return x, y


def replace_missing_csv(csv_list, missing_rep):
    """
    Replaces missing items in a CSV with a given missing representation string.
    """
    full_list = []
    for line in csv_list:
        line_list = line.split(',')
        new_line_list = []
        for item in line_list:
            if item == '':
                item = missing_rep
            new_line_list.append(item)
        full_list.append(new_line_list)
    return full_list


@classmethod
def dicts_to_url(cls, dic, url=None):
    """
        将字典转换成get的url参数部分
        :param dic:
        :return:
        """
    parastring = ''
    for key, value in dic.items():
        parastring += str(key) + '=' + str(value) + '&'
    parastring = parastring[:-1]
    if url:
        return url + '?' + parastring
    return parastring


def setOutgoingInterface(addr):
    """
        Set interface for outgoing multicast packets.

        Returns Deferred of success.
        """


def attach_user_policy(UserName=None, PolicyArn=None):
    """
    Attaches the specified managed policy to the specified user.
    You use this API to attach a managed policy to a user. To embed an inline policy in a user, use  PutUserPolicy .
    For more information about policies, see Managed Policies and Inline Policies in the IAM User Guide .
    See also: AWS API Documentation

    Examples
    The following command attaches the AWS managed policy named AdministratorAccess to the IAM user named Alice.
    Expected Output:

    :example: response = client.attach_user_policy(
        UserName='string',
        PolicyArn='string'
    )

    :type UserName: string
    :param UserName: [REQUIRED]
            The name (friendly name, not ARN) of the IAM user to attach the policy to.
            This parameter allows (per its regex pattern ) a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: =,.@-

    :type PolicyArn: string
    :param PolicyArn: [REQUIRED]
            The Amazon Resource Name (ARN) of the IAM policy you want to attach.
            For more information about ARNs, see Amazon Resource Names (ARNs) and AWS Service Namespaces in the AWS General Reference .

    :return: response = client.attach_user_policy(
        PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess',
        UserName='Alice',
    )

    print(response)

    """
    pass


def claim_get(transport, request, queue_name, claim_id):
    """Gets a Claim `claim_id`

    :param transport: Transport instance to use
    :type transport: `transport.base.Transport`
    :param request: Request instance ready to be sent.
    :type request: `transport.request.Request`
    """
    request.operation = 'claim_get'
    request.params['queue_name'] = queue_name
    request.params['claim_id'] = claim_id
    resp = transport.send(request)
    return resp.deserialized_content


def can_paginate(operation_name=None):
    """
    Check if an operation can be paginated.

    :type operation_name: string
    :param operation_name: The operation name. This is the same name
            as the method name on the client. For example, if the
            method name is create_foo, and you'd normally invoke the
            operation as client.create_foo(**kwargs), if the
            create_foo operation can be paginated, you can use the
            call client.get_paginator('create_foo').

    """
    pass


@classmethod
def get_configuration_for_impersonation(cls, uri, impersonate_user, username):
    """
        Return a configuration dictionary that can be merged with other configs
        that can set the correct properties for impersonating users
        :param uri: URI string
        :param impersonate_user: Bool indicating if impersonation is enabled
        :param username: Effective username
        :return: Dictionary with configs required for impersonation
        """
    return {}


def estimate_fpr(sketch):
    """
    Get a rough estimate of the false positive rate of this sketch.

    Stolen shamelessly from khmer/__init__.py
    """
    sizes = sketch.hashsizes()
    n_ht = float(len(sizes))
    occupancy = float(sketch.n_occupied())
    min_size = min(sizes)
    fp_one = occupancy / min_size
    fp_all = fp_one ** n_ht
    return fp_all


def equal_angle_stereographic_projection_conv_YZ_plane(x, y, z):
    """Function to take 3D grid coords for a cartesian coord system and convert to 2D equal area projection."""
    Y = y / (1 + x)
    Z = z / (1 + x)
    return Y, Z


def screw(steps: int=9, turns: int=1, center: float=(0.0, 0.0, 0.0), axis:
    float=(0.0, 0.0, 0.0)):
    """Extrude selected vertices in screw-shaped rotation around the cursor in indicated viewport

    :param steps: Steps, Steps
    :type steps: int
    :param turns: Turns, Turns
    :type turns: int
    :param center: Center, Center in global view space
    :type center: float
    :param axis: Axis, Axis in global view space
    :type axis: float
    """
    pass


def split_namespace(clarkName):
    """Return (namespace, localname) tuple for a property name in Clark Notation.

    Namespace defaults to ''.
    Example:
    '{DAV:}foo'  -> ('DAV:', 'foo')
    'bar'  -> ('', 'bar')
    """
    if clarkName.startswith('{') and '}' in clarkName:
        ns, localname = clarkName.split('}', 1)
        return ns[1:], localname
    return '', clarkName


def enumerate_model_node_outputs(model, add_node=False):
    """
    Enumerates all the nodes of a model.

    :param model: ONNX graph
    :param add_node: if False, the function enumerates
        all output names from every node, otherwise, it
        enumerates tuple (output name, node)
    :return: enumerator
    """
    if not hasattr(model, 'graph'):
        raise TypeError('Parameter model is not an ONNX model but {}'.
            format(type(model)))
    for node in model.graph.node:
        for out in node.output:
            yield (out, node) if add_node else out


def append_verbosity_argument(cmd, verbosity):
    """
    Just in case we want to modify how many v's we use, centralise this here.
    """
    return cmd + ' -vvvv' if verbosity else cmd


def remove(mail_host):
    """Remove the domain.

        :param mail_host: The email host name of the domain to remove.
        :type mail_host: string
        :raises KeyError: if the named domain does not exist.
        """


def validate_age(name: str, tolerance: float, from_timestamp: float,
    to_timestamp: float) ->None:
    """Check if age is valid (within tolerance)"""
    age = to_timestamp - from_timestamp
    assert age <= tolerance, f'{name} is too old! (Age: {age} > Tolerance: {tolerance})'


def get_col_prim(me, xid):
    """get_col_prim with transparent index mapping."""
    xid = me._colmap.map(xid) if xid else xid
    if xid > 0:
        return me._get_col_prim(xid)


@classmethod
def name(cls):
    """Returns the name of the object, used in __str__()."""
    return 'ComputedObject'


def _mutable_iter(dict):
    """
    Iterate over items in the dict, yielding the first one, but allowing
    it to be mutated during the process.
    >>> d = dict(a=1)
    >>> it = _mutable_iter(d)
    >>> next(it)
    ('a', 1)
    >>> d
    {}
    >>> d.update(b=2)
    >>> list(it)
    [('b', 2)]
    """
    while dict:
        prev_key = next(iter(dict))
        yield prev_key, dict.pop(prev_key)


@classmethod
def has_archiving(cls):
    """Returns whether it supports archiving items on the fetch process.

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


def identity(x):
    """Identity Function."""
    return x


def join_names(values):
    """
    Produces a string by concatenating the items in ``values`` with
    commas, except the last element, which is concatenated with an "and".

    >>> join_names(["apples", "bananas", "oranges"])
    'apples, bananas and oranges'
    >>> join_names(["apples", "bananas"])
    'apples and bananas'
    >>> join_names(["apples"])
    'apples'

    :param values:
        A list of strings.
    :return:
        The concatenated string.
    """
    if len(values) > 1:
        return ', '.join(values[:-1]) + ' and ' + values[-1]
    else:
        return values[0]


@classmethod
def _from_xml(cls, node, path):
    """Create an instance of this class from an XML node.

        Parameters
        ----------
        node : :class:`lxml.etree.Element`
            The node to parse.
        path : str
            The string path where the XML file is located (used for resolving
            the location of mesh or image files).

        Returns
        -------
        obj : :class:`URDFType`
            An instance of this class parsed from the node.
        """
    return cls(**cls._parse(node, path))


def _extrapolate_constant(to_time, from_sample):
    """Extrapolate a power rating to an earlier or later time.

    This models a constant power rating before (or after)
    the `from_sample` input to the `to_time`.

    It returns a power sample, of the same class as the `from_sample`
    but at the time specified in `to_time`.
    """
    sample_class = from_sample.__class__
    watts = from_sample.watts
    extrapolated_sample = sample_class(watts=watts, moment=to_time)
    return extrapolated_sample


def efficientnet_params(model_name):
    """ Map EfficientNet model name to parameter coefficients. """
    params_dict = {'efficientnet-b0': (1.0, 1.0, 224, 0.2),
        'efficientnet-b1': (1.0, 1.1, 240, 0.2), 'efficientnet-b2': (1.1,
        1.2, 260, 0.3), 'efficientnet-b3': (1.2, 1.4, 300, 0.3),
        'efficientnet-b4': (1.4, 1.8, 380, 0.4), 'efficientnet-b5': (1.6,
        2.2, 456, 0.4), 'efficientnet-b6': (1.8, 2.6, 528, 0.5),
        'efficientnet-b7': (2.0, 3.1, 600, 0.5)}
    return params_dict[model_name]


def lower(text):
    """
    Creates a copy of ``text`` with all the cased characters converted to lowercase.

    The lowercasing algorithm used is described in section 3.13 of the Unicode Standard.

    :param text: The string to convert
    :type text:  ``str``

    :return: A copy of ``text`` with all the cased characters converted to lowercase.
    :rtype: ``str``
    """
    assert isinstance(text, str), '%s is not a string' % text
    return text.lower()


def provides(varmap):
    """Return a minimal ``provides`` list from the setup vars.
    """
    try:
        return ['{} ({})'.format(varmap['name'], varmap['version'])]
    except KeyError:
        return [varmap['name']]


@property
def label(cls):
    """Returns the label of the hasher"""
    return cls.name if not cls._weak else '{} (weak)'.format(cls.name)


def sec2HMS(sec):
    """Convert time in sec to H:M:S string

    :param sec: time in seconds
    :return: H:M:S string (to nearest 100th second)

    """
    H = int(sec // 3600)
    M = int(sec // 60 - H * 60)
    S = sec - 3600 * H - 60 * M
    return '%d:%2d:%.2f' % (H, M, S)


@classmethod
def from_refresh_token(Cls, refresh_token):
    """
        Given a refresh token, return an instance of ShortLivedTokenMixin
        configured using information from ``refresh_token``.

        :param refresh_token: A refresh token instance.
        :returns: A new ShortLivedToken instance.

        .. warning::

            You must implement this method

        """
    raise NotImplemented(
        'You must implement from_refresh_token. Invoke {}() and instantiate it using information from the refresh token'
        .format(Cls.__name__))


def __termios(fd):
    """Try to discover terminal width with fcntl, struct and termios."""
    try:
        import fcntl
        import termios
        import struct
        cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
    except Exception:
        return None
    return cr


def psi_H_Mg_OH_HMW84(T, P):
    """c-c'-a: hydrogen magnesium hydroxide [HMW84]."""
    psi = 0
    valid = T == 298.15
    return psi, valid


def checkmember(value, values, msg=''):
    """Check value for membership; raise ValueError if fails."""
    if value not in values:
        raise ValueError(f'ERROR {msg}: {value} should be in {values}')


def ekm_no_log(output_string):
    """ No-op predefined module level logging callback.

    Args:
        output_string (str): string to output.
    """
    pass


@staticmethod
def check_dates(results: dict) ->dict:
    """
        In cases where the entire time series does not contain a break day, simply make it be equal to the model's
        end day.

        """
    for ind, model in enumerate(results['change_models']):
        if model['break_day'] < 1:
            model['break_day'] = model['end_day']
    return results


def get_listOfCompartments(model):
    """Get list of compartments in a SBML model

    Args:
        model (xml.etree.ElementTree.Element): SBML model

    Returns:
        xml.etree.ElementTree.Element: list of compartments
    """
    listOfCompartments = None
    for e in model:
        if e.tag[0] == '{':
            uri, tag = e.tag[1:].split('}')
        else:
            tag = e.tag
        if tag == 'listOfCompartments':
            listOfCompartments = e
            break
    return listOfCompartments


def set_nested(input_dict, nested_key, value):
    """
    Set a nested key
    e.g. nested_get({'a': {'b': 1}}, ['a', 'b'], 2) => {'a': {'b': 2}}
    """
    current_dict = input_dict
    for k in nested_key[:-1]:
        if k not in current_dict or current_dict[k] is None:
            current_dict[k] = {}
        elif type(current_dict[k]) is not dict:
            raise Exception(f'{k} is not a dict')
        current_dict = current_dict[k]
    current_dict[nested_key[-1]] = value


def _writer(func):
    """
	Decorator for a custom writer, but a default reader
	"""
    name = func.__name__
    return property(fget=lambda self: getattr(self, '_%s' % name), fset=func)


@staticmethod
def contains_any(text, any_of):
    """
        @param text: The text we want to check
        :type str
        @param any_of: list of char
        :type list
        :returns False if text nit
        """
    if not text or not any_of:
        return False
    any_of = list(set(any_of))
    for c in any_of:
        if c in text:
            return True
    return False


def nanmode(col):
    """
    Return the Mode of the column, including NaN as an indicator

    :param col: The col of data to work on
    :return:    The mode
    """
    return col.value_counts(dropna=False).idxmax()


def is_unusual_tag(tagstr):
    """Identify unusual tags with word to comma ratio > 3.

    Parameters
    ----------
    tagstr : str
        tag string to check.

    Returns
    -------
    bool
        True if valid tag else False.
    """
    if not tagstr:
        return False
    nwords = len(tagstr.split())
    ncommas = tagstr.count(',') + 1
    if nwords / ncommas > 3:
        return True
    return False


def parse_line(arg, n_args=None, type=int):
    """Convert a series of zero or more numbers to an argument tuple"""
    result = tuple(map(type, arg.split()))
    if isinstance(n_args, str):
        if n_args[-1] == '+':
            min_limit = int(n_args[:-1])
            if len(result) < min_limit:
                errormsg = 'expected minimum ' + str(min_limit
                    ) + ' arguments, received ' + str(len(result))
            else:
                errormsg = None
    elif isinstance(n_args, int):
        if n_args and len(result) != n_args:
            errormsg = 'expected ' + str(n_args
                ) + ' arguments, received ' + str(len(result))
        else:
            errormsg = None
    else:
        errormsg = None
    return result, errormsg


def soundclip_add():
    """Add a strip for controlling when speaker plays its sound clip

    """
    pass


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


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

        :param EmmRefreshAuthTokenDetails val:
        :rtype: EventDetails
        """
    return cls('emm_refresh_auth_token_details', val)


def _file_iter_range(fp, offset, bytes, maxread=1024 * 1024):
    """ Yield chunks from a range in a file. No chunk is bigger than maxread."""
    fp.seek(offset)
    while bytes > 0:
        part = fp.read(min(bytes, maxread))
        if not part:
            break
        bytes -= len(part)
        yield part


def _shift(src, dst):
    """Pops the first item in ``src`` and moves it to ``dst``."""
    key, value = src.popitem(last=False)
    dst.append(key)


def uprint(*args, print_ok=True, **kwargs):
    """Print option interface.

    This function is equal to ``print`` function but added ``print_ok``
    option. This allows you to control printing in a function.

    Parameters
    ----------
    *args: whatever ``print`` allows.
      It is same as ``print`` does.

    print_ok: Boolean (default: True)
      An option whether you want to print something out or not.

    arg_zip: zip (default: None)
      A ``zip`` instance.

    """
    if print_ok:
        print(*args, **kwargs)


def generate_urn(gallery_image):
    """
    This function takes an azure gallery image and outputs a corresponding URN
    :param gallery_image: a GalleryImageReference object
    :return: URN as string
    """
    reference_dict = gallery_image.as_dict()
    return ':'.join([reference_dict['publisher'], reference_dict['offer'],
        reference_dict['sku'], reference_dict['version']])


def CDPP(flux, mask=[], cadence='lc'):
    """
  Compute the CDPP metric for a given timeseries.

  :param array_like flux: The flux array to compute the CDPP for
  :param array_like mask: The indices to be masked
  :param str cadence: The light curve cadence. Default `lc`

  """
    raise NotImplementedError('This mission is not yet supported.')


@classmethod
def fetch_many(cls, job_ids, connection):
    """
        Bulk version of Job.fetch

        For any job_ids which a job does not exist, the corresponding item in
        the returned list will be None.
        """
    with connection.pipeline() as pipeline:
        for job_id in job_ids:
            pipeline.hgetall(cls.key_for(job_id))
        results = pipeline.execute()
    jobs = []
    for i, job_id in enumerate(job_ids):
        if results[i]:
            job = cls(job_id, connection=connection)
            job.restore(results[i])
            jobs.append(job)
        else:
            jobs.append(None)
    return jobs


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


@classmethod
def local(cls, lon_lat=(0, 0), origin=(0, 0), azimuth=0, elevation=0, datum
    ='WGS 84', local_datum=None, scale_factor=0.9996, vcs=None):
    """
        Create an ad-hoc local coordinate system.

        :param lon_lat:         (longitude, latitude) of the center
        :param origin:          (x, y) to assign to the center
        :param azimuth:         local rotation of the system relative to geographic North, in degrees azimuth
        :param elevation:       elevation for z = 0.
        :param datum:           datum, default is "WGS 84"
        :param local_datum:     local datum, default will be the default for the specified datum
        :param scale_factor:    central scale factor. The default is 0.9996 as the most common map system
                                is UTM and thus relative distances in the local system will be similar,
                                though not the same, as UTM.
        :param vcs:             name for the vertical coordinate system reference, default is unknown

        Local coordinate systems are simple cartesian systems established for a specific purpose without
        complete geodetic control, but for which one knows or can estimate the longitude, latitude of a point
        on the local coordinate system. In this way local coordinates can be located reasonably well relative
        to the Earth and and other Earth-refeerenced data.

        The local system will be constructed as an oblique stereographic projection centered at the system
        origin, which is similar to what one sees when looking at maps in Google maps.

        .. versionadded:: 9.3.1
        """
    csdict = {'type': 'local', 'lon_lat': lon_lat, 'origin': origin,
        'azimuth': azimuth, 'elevation': elevation, 'datum': datum,
        'scale_factor': scale_factor}
    if local_datum:
        csdict['local_datum'] = local_datum
    if vcs:
        csdict['vcs'] = vcs
    return cls(csdict)


def p_Specials(p):
    """Specials : Special Specials"""
    p[0] = [p[1]] + p[2]


def get_config():
    """Return ISparcAppConfiguration provider for current runtime configuration settings"""


def make_trips_diary(valid_segments, missing_segments):
    """
    Zips together lists of valid segments and missing segments in timestamp order
    into continuous trip diary.
    """
    if not missing_segments:
        return valid_segments
    trips = []
    missing_iter = iter(missing_segments)
    missing_test_segment = next(missing_iter)
    trip_idx = 0
    missing_idxs = []
    for valid_segment in valid_segments:
        if not missing_test_segment:
            trips.append(valid_segment)
            trip_idx += 1
        elif missing_test_segment and valid_segment[0
            ].timestamp_UTC < missing_test_segment[0].timestamp_UTC:
            trips.append(valid_segment)
            trip_idx += 1
        else:
            trips.append(missing_test_segment)
            missing_idxs.append(trip_idx)
            trip_idx += 1
            trips.append(valid_segment)
            trip_idx += 1
            missing_test_segment = next(missing_iter, None)
    diary = {'trips': trips, 'missing': missing_idxs}
    return diary


def _solve_insert_ambiguity(insert):
    """
    Deals with ambiguities in the insert part. They arise between locations
    and lengths.

    Example:
    - REF:100>200 - 200 can be interpreted as a location or a length.

    We interpret insert as length (size) for the following:
    - NUMBER
    - (NUMBER)
    - (NUMBER_NUMBER)
    Examples:
    - 10, (10) something of length 10 is inserted;
    - (10_20): something of a length between 10 and 20 is inserted.
    - (?_20)
    - (20_?)
    - ?

    We interpret insert as location for the following:
    - point_point
    - (point_point)_point
    - point_(point_point)
    Examples:
    - 10_20
    - 10_(20_30)
    - (10_20)_30
    - (10_20)_(30_40)
    """
    if len(insert.children) == 2:
        if insert.children[0].children[0].data == 'length' and insert.children[
            1].children[0].data == 'location':
            return insert.children[0]
        elif insert.children[0].children[0
            ].data == 'location' and insert.children[1].children[0
            ].data == 'length':
            return insert.children[1]


def words(zelf, *args, **kwargs):
    """ get the arguments of the txt attribute. """
    if 'txt' in zelf:
        return zelf.txt.split()


@classmethod
def convert_to_duckling_language_id(cls, lang):
    """Ensure a language identifier has the correct duckling format and is supported."""
    if lang is not None and cls.is_supported(lang):
        return lang
    elif lang is not None and cls.is_supported(lang + '$core'):
        return lang + '$core'
    else:
        raise ValueError("Unsupported language '{}'. Supported languages: {}"
            .format(lang, ', '.join(cls.SUPPORTED_LANGUAGES)))


def currency_display(value, currency='AUD', show_complete=False,
    include_sign=True):
    """
    Create a human readable string to display a currency from some number of smallest units (e.g. cents).

    :param value: value of currency in smallest units (cents)
    :param currency: e.g. 'AUD'
    :param show_complete: if True, show '$5.00' rather than '$5'
    :param include_sign: Include the e.g. dollar sign
    :return:
    """
    if currency != 'AUD':
        raise NotImplementedError('Only AUD currently supported')
    unit_modulo = 100
    large_units = int(value / unit_modulo)
    small_units = value % unit_modulo
    sign = '$' if include_sign else ''
    if show_complete or small_units:
        return '{sign}{large}.{small:02}'.format(sign=sign, large=
            large_units, small=small_units)
    else:
        return '{sign}{large}'.format(sign=sign, large=large_units)


def betweenPro(fileb, mutation):
    """ PTMs (predicted) involved in the crosstalk in different proteins at baker's years (PTMcode 2.0; Minguez el 2012) """
    with open('ptm_between_proteins.txt', 'w') as file1:
        with open(fileb, 'rU') as f:
            for l in f:
                line = l.split()
                if len(line) > 20:
                    take = line[16] + '\t' + line[18] + '\t' + line[15
                        ] + '\t' + line[17] + '\t' + line[19] + '\t' + line[21
                        ] + '\t' + line[4] + '\t' + line[8]
                    take = take.split()
                    with open(mutation, 'r') as mu:
                        for m in mu:
                            m = m.split()
                            if m[0] == take[0] and m[1] == take[4]:
                                take2 = take[0] + '\t' + take[2] + '\t' + take[
                                    4] + '\t' + take[6] + '\t' + 'PTMcode'
                                fi = take2.split()
                                with open('yeastID.txt') as id:
                                    for di in id:
                                        di = di.split()
                                        if len(di) > 2 and di[2] == fi[0]:
                                            summary = open('summary.txt', 'a+')
                                            summary.write(di[0] + '\t' + di[2] +
                                                '\t' + fi[2] + '\t' + fi[3] + '\t' +
                                                'BetweenProteins' + '\t' +
                                                'PTMcode' + '\n')
                                            if take2 > str(0):
                                                with open('ptm_between_proteins.txt', 'a'
                                                    ) as file1:
                                                    file1.write(take2 + '\n')
                                                    continue
                            if m[0] == take[1] and m[1] == take[5]:
                                take3 = take[1] + '\t' + take[3] + '\t' + take[
                                    5] + '\t' + take[7] + '\t' + 'PTMcode'
                                fi = take3.split()
                                with open('yeastID.txt') as id:
                                    for di in id:
                                        di = di.split()
                                        if len(di) > 2 and di[2] == fi[0]:
                                            summary = open('summary.txt', 'a+')
                                            summary.write(di[0] + '\t' + di[2] +
                                                '\t' + fi[2] + '\t' + fi[3] + '\t' +
                                                'BetweenProteins' + '\t' +
                                                'PTMcode' + '\n')
                                            if take3 > str(0):
                                                with open('ptm_between_proteins.txt', 'a+'
                                                    ) as file1:
                                                    file1.write(take3 + '\n')


def intinlist(lst):
    """test if int in list"""
    for item in lst:
        try:
            item = int(item)
            return True
        except ValueError:
            pass
    return False


@classmethod
def from_fastx(cls, fastx, name=None):
    """Create a Read from a fasta/q file.

        :param fastx: input file path.
        :param name: name of Read. If not given the filename will be used.

        """
    try:
        read = next(cls.multi_from_fastx(fastx, take_all=True))
    except Exception:
        raise IOError('Could not create Read from file {}.'.format(fastx))
    return read


def decode_response(client_message, to_object=None):
    """ Decode response from client message"""
    parameters = dict(response=None)
    parameters['response'] = client_message.read_bool()
    return parameters


def abspath(path):
    """Convert the given path to an absolute path.

    Since FS objects have no concept of a *current directory*, this
    simply adds a leading ``/`` character if the path doesn't already
    have one.

    Arguments:
        path (str): A PyFilesytem path.

    Returns:
        str: An absolute path.

    """
    if not path.startswith('/'):
        return '/' + path
    return path


def slide_point(slide_feather: bool=False, is_new_point: bool=False):
    """Slide control points

    :param slide_feather: Slide Feather, First try to slide feather instead of vertex
    :type slide_feather: bool
    :param is_new_point: Slide New Point, Newly created vertex is being slid
    :type is_new_point: bool
    """
    pass


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

        :param list of [str] val:
        :rtype: DeleteManualContactsError
        """
    return cls('contacts_not_found', val)


def _add_doc(func, doc):
    """Add documentation to a function."""
    func.__doc__ = doc


def update_position(config, adaptator, adapt, adaptator_length, ntuple):
    """
    Update barcode position in config file when a barcode is removed

    params: config
    params: adaptator
    params: adapt
    params: adaptator_length
    """
    if not adapt == 'conditions' and not adapt == adaptator and config[adapt][
        'coords']['header'] == config[adaptator]['coords']['header'
        ] and config[adapt]['coords']['reads'] == ntuple:
        if config[adapt]['coords']['start'] > config[adaptator]['coords'][
            'start']:
            config[adapt]['coords']['start_update'] = config[adapt]['coords'][
                'start'] - adaptator_length
            config[adapt]['coords']['stop_update'] = config[adapt]['coords'][
                'stop'] - adaptator_length
    return config


def stopConnecting():
    """
        Stop attempting to connect.
        """


def brok_last_time(ref, val):
    """Convert float to int

    :param ref: Not used
    :type ref:
    :param val: value to convert
    :type val: float
    :return: int(val)
    :rtype: int
    """
    return int(val)


@classmethod
def validate(cls, unit):
    """
        Check if the given unit is valid (exists).

        Parameters
        ----------
        unit : unicode
            The unit to be checked.

        Returns
        -------
        None
            If the given unit is valid and exists.

        Raises
        ------
        Unit.UnknownUnitError
        """
    if not any(map(lambda d: unit in cls._units_per_dimension[d], cls.
        _units_per_dimension)):
        raise cls.UnknownUnitError(unit)