text:
import numpy as np
import scipy.sparse as sprs
from scipy.spatial import KDTree, distance_matrix
from scipy.spatial import ConvexHull
from scipy.spatial import Delaunay
from scipy.sparse import csgraph
from openpnm._skgraph.tools import generate_points_on_sphere
from openpnm._skgraph.tools import generate_points_on_circle
from openpnm._skgraph.tools import cart2sph, sph2cart, cart2cyl, cyl2cart

# Once a function has been stripped of all its OpenPNM dependent code it
# can be added to this list of functions to import
__all__ = [
    'get_edge_prefix',
    'get_node_prefix',
    'change_prefix',
    'isoutside',
    'dimensionality',
    'find_surface_nodes',
    'find_surface_nodes_cubic',
    'find_coincident_nodes',
    'internode_distance',
    'tri_to_am',
    'vor_to_am',
    'conns_to_am',
    'dict_to_am',
    'dict_to_im',
    'istriu',
    'istril',
    'isgtriu',
    'istriangular',
    'issymmetric',
    'get_cubic_shape',
    'get_cubic_spacing',
    'is_fully_connected',
    'get_domain_length',
    'get_domain_area',
]

def get_edge_prefix(network):
    r"""
    Determines the prefix used for edge arrays from ``<edge_prefix>.conns``

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    edge_prefix : str
        The value of ``<edge_prefix>`` used in ``g``.  This is found by
        scanning ``g.keys()`` until an array ending in ``'.conns'`` is found,
        then returning the prefix.

    Notes
    -----
    This process is surprizingly fast, on the order of nano seconds, so this
    overhead is worth it for the flexibility it provides in array naming.
    However, since all ``dict`` are now sorted in Python, it may be helpful
    to ensure the ``'conns'`` array is near the beginning of the list.
    """
    for item in network.keys():
        if item.endswith('.conns'):
            return item.split('.')[0]

def get_node_prefix(network):
    r"""
    Determines the prefix used for node arrays from ``<edge_prefix>.coords``

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    node_prefix : str
        The value of ``<node_prefix>`` used in ``g``.  This is found by
        scanning ``g.keys()`` until an array ending in ``'.coords'`` is found,
        then returning the prefix.

    Notes
    -----
    This process is surprizingly fast, on the order of nano seconds, so this
    overhead is worth it for the flexibility it provides in array naming.
    However, since all ``dict`` are now sorted in Python, it may be helpful
    to ensure the ``'conns'`` array is near the beginning of the list.
    """
    for item in network.keys():
        if item.endswith('.coords'):
            return item.split('.')[0]

def change_prefix(network, old_prefix, new_prefix):
    r"""
    Changes the prefix used when generating the graph

    Parameters
    ----------
    network : dict
        The network graph
    old_prefix : str
        The current prefix to change, can either be a node or an edge prefix
    new_prefix : str
        The prefix to use instead

    Returns
    -------
    network : dict
        The graph dictionary will arrays assigned to new keys
    """
    for key in list(network.keys()):
        if key.startswith(old_prefix):
            temp = key.split('.', 1)[1]
            network[new_prefix + '.' + temp] = network.pop(key)
    return network

def isoutside(network, shape, rtol=0.0):
    r"""
    Identifies sites that lie outside the specified shape

    Parameters
    ----------
    network : dict
        The network dictionary
    shape : array_like
        The shape of the domain beyond which points are considered "outside".
        The argument is treated as follows:

        ========== ============================================================
        shape      Interpretation
        ========== ============================================================
        [x, y, z]  A 3D cubic domain of dimension x, y and z with the origin at
                   [0, 0, 0].
        [x, y, 0]  A 2D square domain of size x by y with the origin at
                   [0, 0]
        [r, z]     A 3D cylindrical domain of radius r and height z whose
                   central axis starts at [0, 0, 0]
        [r, 0]     A 2D circular domain of radius r centered on [0, 0] and
                   extending upwards
        [r]        A 3D spherical domain of radius r centered on [0, 0, 0]
        ========== ============================================================

    rtol : scalar or array_like, optional
        Controls how far a node must be from the domain boundary to be
        considered outside. It is applied as a fraction of the domain size as
        ``x[i] > (shape[0] + shape[0]*threshold)`` or
        ``y[i] < (0 - shape[1]*threshold)``.  Discrete threshold values
        can be given for each axis by supplying a list the same size as
        ``shape``.

    Returns
    -------
    mask : boolean ndarray
        A boolean array with ``True`` values indicating nodes that lie outside
        the domain.

    Notes
    -----
    If the domain is 2D, either a circle or a square, then the z-dimension
    of ``shape`` should be set to 0.

    """
    node_prefix = get_node_prefix(network)
    coords = network[node_prefix+'.coords']
    shape = np.array(shape, dtype=float)
    if np.isscalar(rtol):
        tolerance = np.array([rtol]*len(shape))
    else:
        tolerance = np.array(rtol)
    # Label external pores for trimming below
    if len(shape) == 1:  # Spherical
        # Find external points
        R, Q, P = cart2sph(*coords.T)
        thresh = tolerance[0]*shape[0]
        Ps = R > (shape[0] + thresh)
    elif len(shape) == 2:  # Cylindrical
        # Find external pores outside radius
        R, Q, Z = cart2cyl(*coords.T)
        thresh = tolerance[0]*shape[0]
        Ps = R > shape[0]*(1 + thresh)
        # Find external pores above and below cylinder
        if shape[1] > 0:
            thresh = tolerance[1]*shape[1]
            Ps = Ps + (coords[:, 2] > (shape[1] + thresh))
            Ps = Ps + (coords[:, 2] < (0 - thresh))
        else:
            pass
    elif len(shape) == 3:  # Rectilinear
        thresh = tolerance*shape
        Ps1 = np.any(coords > (shape + thresh), axis=1)
        Ps2 = np.any(coords < (0 - thresh), axis=1)
        Ps = Ps1 + Ps2
    return Ps

def dimensionality(network, cache=True):
    r"""
    Checks the dimensionality of the network

    Parameters
    ----------
    network : dict
        The network dictionary
    cache : boolean, optional (default is True)
        If ``False`` then the dimensionality is recalculated even if it has
        already been calculated and stored in the graph dictionary.

    Returns
    -------
    dims : list
        A  3-by-1 array containing ``True`` for each axis that contains
        multiple values, indicating that the pores are spatially distributed
        in that dimension.

    """
    if cache:
        try:
            return network.params["dimensionality"]
        # union of KeyErroa and AttributeError
        except (KeyError, AttributeError):
            pass
    n = get_node_prefix(network)
    coords = network[n+'.coords']
    eps = np.finfo(float).resolution
    dims_unique = [not np.allclose(xk, xk.mean(), atol=0, rtol=eps) for xk in coords.T]
    if cache:
        network["params.dimensionality"] = np.array(dims_unique)
    return np.array(dims_unique)

def find_surface_nodes_cubic(network):
    r"""
    Identifies nodes on the outer surface of the domain assuming a cubic domain
    to save time

    Parameters
    ----------
    network : dict
        The graph dictionary

    Returns
    -------
    mask : ndarray
        A boolean array of ``True`` values indicating which nodes were found
        on the surfaces.
    """
    node_prefix = get_node_prefix(network)
    coords = network[node_prefix+'.coords']
    hits = np.zeros(coords.shape[0], dtype=bool)
    dims = dimensionality(network)
    for d in range(3):
        if dims[d]:
            hi = np.where(coords[:, d] == coords[:, d].max())[0]
            lo = np.where(coords[:, d] == coords[:, d].min())[0]
            hits[hi] = True
            hits[lo] = True
    return hits

def find_coincident_nodes(network):
    r"""
    Finds nodes with identical coordinates

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    duplicates : list of ndarrays
        A list with each sublist indicating the indices of nodes that share
        a common set of coordinates

    Notes
    -----
    This function works by computing a ``hash`` of the coordinates then finding
    all nodes with equivalent hash values. Hashes are supposed to be unique
    but they occassionally "collide", meaning nodes may be identified as
    coincident that are not.
    """
    node_prefix = get_node_prefix(network)
    coords = network[node_prefix+'.coords']
    hashed = [hash(row.tobytes()) for row in coords]
    uniq, counts = np.unique(hashed, return_counts=True)
    hits = np.where(counts > 1)[0]
    dupes = []
    for item in hits:
        dupes.append(np.where(hashed == uniq[item])[0])
    return dupes

def find_surface_nodes(network):
    r"""
    Identifies nodes on the outer surface of the domain using a Delaunay
    tessellation

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    mask : ndarray
        A boolean array of ``True`` values indicating which nodes were found
        on the surfaces.

    Notes
    -----
    This function generates points around the domain the performs a Delaunay
    tesselation between these points and the network nodes.  Any network
    nodes which are connected to a generated points is considered a surface
    node.

    """
    node_prefix = get_node_prefix(network)
    coords = np.copy(network[node_prefix+'.coords'])
    shift = np.mean(coords, axis=0)
    coords = coords - shift
    tmp = cart2sph(*coords.T)
    hits = np.zeros(coords.shape[0], dtype=bool)
    r = 2*tmp[0].max()
    dims = dimensionality(network)
    if sum(dims) == 1:
        hi = np.where(coords[:, dims] == coords[:, dims].max())[0]
        lo = np.where(coords[:, dims] == coords[:, dims].min())[0]
        hits[hi] = True
        hits[lo] = True
        return hits
    if sum(dims) == 2:
        markers = generate_points_on_circle(n=max(10, int(coords.shape[0]/10)), r=r)
        pts = np.vstack((coords[:, dims], markers))
    else:
        markers = generate_points_on_sphere(n=max(10, int(coords.shape[0]/10)), r=r)
        pts = np.vstack((coords, markers))
    tri = Delaunay(pts, incremental=False)
    (indices, indptr) = tri.vertex_neighbor_vertices
    for k in range(coords.shape[0], tri.npoints):
        neighbors = indptr[indices[k]:indices[k+1]]
        inds = np.where(neighbors < coords.shape[0])
        hits[neighbors[inds]] = True
    return hits

def internode_distance(network, inds_1=None, inds_2=None):
    r"""
    Find the distance between all nodes on set 1 to each node in set 2

    Parameters
    ----------
    network : dict
        The network dictionary
    inds_1 : array_like
        A list containing the indices of the first set of nodes
    inds_2 : array_Like
        A list containing the indices of the first set of nodes.  It's OK if
        these indices are partially or completely duplicating ``nodes1``.

    Returns
    -------
    dist : array_like
        A distance matrix with ``len(site1)`` rows and ``len(sites2)`` columns.
        The distance between site *i* in ``site1`` and *j* in ``sites2`` is
        located at *(i, j)* and *(j, i)* in the distance matrix.

    Notes
    -----
    This function computes and returns a distance matrix, so can get large.
    For distances between larger sets a KD-tree approach would be better,
    which is available in ``scipy.spatial``.

    """
    node_prefix = get_node_prefix(network)
    coords = network[node_prefix+'.coords']
    p1 = np.array(inds_1, ndmin=1)
    p2 = np.array(inds_2, ndmin=1)
    return distance_matrix(coords[p1], coords[p2])

def iscoplanar(network):
    r"""
    Determines if specified nodes are coplanar with each other

    Parameters
    ----------
    network : dict
        The graph dictionary

    Returns
    -------
    flag : bool
        A boolean value of whether given nodes are coplanar (``True``) or
        not (``False``)

    """
    node_prefix = get_node_prefix(network)
    coords = network[node_prefix + '.coords']
    if np.shape(coords)[0] < 3:
        raise Exception('At least 3 input pores are required')

    Px = coords[:, 0]
    Py = coords[:, 1]
    Pz = coords[:, 2]

    # Do easy check first, for common coordinate
    if np.shape(np.unique(Px))[0] == 1:
        return True
    if np.shape(np.unique(Py))[0] == 1:
        return True
    if np.shape(np.unique(Pz))[0] == 1:
        return True

    # Perform rigorous check using vector algebra
    # Grab first basis vector from list of coords
    n1 = np.array((Px[1] - Px[0], Py[1] - Py[0], Pz[1] - Pz[0])).T
    n = np.array([0.0, 0.0, 0.0])
    i = 1
    while n.sum() == 0:
        if i >= (np.size(Px) - 1):
            return False
        # Chose a secon basis vector
        n2 = np.array((Px[i+1] - Px[i], Py[i+1] - Py[i], Pz[i+1] - Pz[i])).T
        # Find their cross product
        n = np.cross(n1, n2)
        i += 1
    # Create vectors between all other pairs of points
    r = np.array((Px[1:-1] - Px[0], Py[1:-1] - Py[0], Pz[1:-1] - Pz[0]))
    # Ensure they all lie on the same plane
    n_dot = np.dot(n, r)

    return bool(np.sum(np.absolute(n_dot)) == 0)

def is_fully_connected(network, inds=None):
    r"""
    Checks whether graph is fully connected, i.e. not clustered

    Parameters
    ----------
    network : dict
        The network dictionary
    inds : array_like (optional)
        The indices of boundary nodes (i.e. inlets/outlets). If this is given
        the multiple sample spanning clusters will count as fully connected.

    Returns
    -------
    flag : bool
        If ``inds`` is not specified, then returns ``True`` only if
        the entire network is connected to the same cluster. If
        ``inds`` is given, then returns ``True`` only if all clusters
        are connected to the given boundary nodes.
    """
    am = dict_to_am(network)
    am = am.tolil()
    inds = np.array(inds)
    temp = csgraph.connected_components(am, directed=False)[1]
    is_connected = np.unique(temp).size == 1
    Np = am.shape[0]
    Nt = int(am.nnz/2)
    # Ensure all clusters are part of inds, if given
    if not is_connected and inds is not None:
        am.resize(Np + 1, Np + 1)
        am.rows[-1] = inds.tolist()
        am.data[-1] = np.arange(Nt, Nt + len(inds)).tolist()
        temp = csgraph.connected_components(am, directed=False)[1]
        is_connected = np.unique(temp).size == 1
    return is_connected

def get_cubic_spacing(network):
    r"""
    Determine spacing of a cubic network

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    spacing : ndarray
        An array containing the spacing between nodes in each direction

    """
    node_prefix = get_node_prefix(network)
    edge_prefix = get_edge_prefix(network)
    coords = network[node_prefix+'.coords']
    conns = network[edge_prefix+'.conns']
    # Find Network spacing
    C12 = coords[conns]
    mag = np.linalg.norm(np.diff(C12, axis=1), axis=2)
    unit_vec = np.around(np.squeeze(np.diff(C12, axis=1)) / mag, decimals=14)
    spacing = [0, 0, 0]
    dims = dimensionality(network)
    # Ensure vectors point in n-dims unique directions
    c = {tuple(row): 1 for row in unit_vec}
    mag = np.atleast_1d(mag.squeeze()).astype(float)
    if len(c.keys()) > sum(dims):
        raise Exception(
            "Spacing is undefined when throats point in more directions"
            " than network has dimensions."
        )
    for ax in [0, 1, 2]:
        if dims[ax]:
            inds = np.where(unit_vec[:, ax] == unit_vec[:, ax].max())[0]
            temp = np.unique(mag[inds])
            if not np.allclose(temp, temp[0]):
                raise Exception("A unique value of spacing could not be found.")
            spacing[ax] = temp[0]
    return np.array(spacing)

def get_cubic_shape(network):
    r"""
    Determine shape of a cubic network

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    shape : ndarray
        An array containing the shape of the network each direction

    """
    node_prefix = get_node_prefix(network)
    coords = network[node_prefix+'.coords']
    L = np.ptp(coords, axis=0)
    mask = L.astype(bool)
    S = get_cubic_spacing(network)
    shape = np.array([1, 1, 1], int)
    shape[mask] = L[mask] / S[mask] + 1
    return shape

def get_domain_area(network, inlets=None, outlets=None):
    r"""
    Determine the cross sectional area relative to the inlets/outlets.

    Parameters
    ----------
    network : dict
        The network dictionary
    inlets : array_like
        The indices of the inlets
    outlets : array_Like
        The indices of the outlets

    Returns
    -------
    area : scalar
        The cross sectional area relative to the inlets/outlets.

    """
    if dimensionality(network).sum() != 3:
        raise Exception('The network is not 3D, specify area manually')
    node_prefix = get_node_prefix(network)
    coords = network[node_prefix+'.coords']
    inlets = coords[inlets]
    outlets = coords[outlets]
    if not iscoplanar(inlets):
        print('Detected inlet pores are not coplanar')
    if not iscoplanar(outlets):
        print('Detected outlet pores are not coplanar')
    Nin = np.ptp(inlets, axis=0) > 0
    if Nin.all():
        print('Detected inlets are not oriented along a principle axis')
    Nout = np.ptp(outlets, axis=0) > 0
    if Nout.all():
        print('Detected outlets are not oriented along a principle axis')
    hull_in = ConvexHull(points=inlets[:, Nin])
    hull_out = ConvexHull(points=outlets[:, Nout])
    if hull_in.volume != hull_out.volume:
        print('Inlet and outlet faces are different area')
    area = hull_in.volume  # In 2D: volume=area, area=perimeter
    return area

def get_domain_length(network, inlets=None, outlets=None):
    r"""
    Determine the domain length relative to the inlets/outlets.

    Parameters
    ----------
    network : dict
        The network dictionary
    inlets : array_like
        The pore indices of the inlets.
    outlets : array_Like
        The pore indices of the outlets.

    Returns
    -------
    area : scalar
        The domain length relative to the inlets/outlets.

    """
    node_prefix = get_node_prefix(network)
    coords = network[node_prefix+'.coords']
    inlets = coords[inlets]
    outlets = coords[outlets]
    if not iscoplanar(inlets):
        print('Detected inlet pores are not coplanar')
    if not iscoplanar(outlets):
        print('Detected inlet pores are not coplanar')
    tree = KDTree(data=inlets)
    Ls = np.unique(np.float64(tree.query(x=outlets)[0]))
    if not np.allclose(Ls, Ls[0]):
        print('A unique value of length could not be found')
    length = Ls[0]
    return length

def tri_to_am(tri):
    r"""
    Given a Delaunay triangulation object from Scipy's ``spatial`` module,
    converts to a sparse adjacency matrix network representation.

    Parameters
    ----------
    tri : Delaunay Triangulation Object
        This object is produced by ``scipy.spatial.Delaunay``

    Returns
    -------
    A sparse adjacency matrix in COO format.  The network is undirected
    and unweighted, so the adjacency matrix is upper-triangular and all the
    weights are set to 1.

    """
    # Create an empty list-of-list matrix
    lil = sprs.lil_matrix((tri.npoints, tri.npoints))
    # Scan through Delaunay triangulation object to retrieve pairs
    indices, indptr = tri.vertex_neighbor_vertices
    for k in range(tri.npoints):
        lil.rows[k] = indptr[indices[k]:indices[k + 1]].tolist()
    # Convert to coo format
    lil.data = lil.rows  # Just a dummy array to make things work properly
    coo = lil.tocoo()
    # Set weights to 1's
    coo.data = np.ones_like(coo.data)
    # Remove diagonal, and convert to csr remove duplicates
    am = sprs.triu(A=coo, k=1, format='csr')
    # The convert back to COO and return
    am = am.tocoo()
    return am

def vor_to_am(vor):
    r"""
    Given a Voronoi tessellation object from Scipy's ``spatial`` module,
    converts to a sparse adjacency matrix network representation in COO format.

    Parameters
    ----------
    vor : Voronoi Tessellation object
        This object is produced by ``scipy.spatial.Voronoi``

    Returns
    -------
    A sparse adjacency matrix in COO format.  The network is undirected
    and unweighted, so the adjacency matrix is upper-triangular and all the
    weights are set to 1.

    """
    # Create adjacency matrix in lil format for quick matrix construction
    N = vor.vertices.shape[0]
    rc = [[], []]
    for ij in vor.ridge_dict.keys():
        row = vor.ridge_dict[ij].copy()
        # Make sure voronoi cell closes upon itself
        row.append(row[0])
        # Add connections to rc list
        rc[0].extend(row[:-1])
        rc[1].extend(row[1:])
    rc = np.vstack(rc).T
    # Make adj mat upper triangular
    rc = np.sort(rc, axis=1)
    # Remove any pairs with ends at infinity (-1)
    keep = ~np.any(rc == -1, axis=1)
    rc = rc[keep]
    data = np.ones_like(rc[:, 0])
    # Build adj mat in COO format
    M = N = np.amax(rc) + 1
    am = sprs.coo_matrix((data, (rc[:, 0], rc[:, 1])), shape=(M, N))
    # Remove diagonal, and convert to csr remove duplicates
    am = sprs.triu(A=am, k=1, format='csr')
    # The convert back to COO and return
    am = am.tocoo()
    return am

def dict_to_am(network, weights=None):
    r"""
    Convert a graph dictionary into a ``scipy.sparse`` adjacency matrix in
    COO format

    Parameters
    ----------
    network : dict
        A network dictionary
    weights : ndarray, optional
        The weight values to use for the connections. If not provided
        then 1's are assumed.

    Returns
    -------
    am : sparse matrix
        The sparse adjacency matrix in COO format

    Notes
    -----
    If the edge connections in ``g`` are in upper-triangular form, then the
    graph is assumed to be undirected and the returned adjacency matrix is
    symmetrical (i.e. the triu entries are reflected in tril). If any edges
    are found in the lower triangle, then the returned adjacency matrix is
    unsymmetrical.

    Multigraphs (i.e. duplicate connections between nodes) are not suported,
    but this is not checked for here to avoid overhead since this function is
    called frequently.

    """
    edge_prefix = get_edge_prefix(network)
    node_prefix = get_node_prefix(network)
    conns = np.copy(network[edge_prefix+'.conns'])
    shape = [network[node_prefix+'.coords'].shape[0]]*2
    if weights is None:
        weights = np.ones_like(conns[:, 0], dtype=int)
    if isgtriu(network):  # If graph is triu, then it is assumed to be undirected
        conns = np.vstack((conns, np.fliplr(conns)))  # Reflect to tril
        data = np.ones_like(conns[:, 0], dtype=int)  # Generate fake data
        am = sprs.coo_matrix((data, (conns[:, 0], conns[:, 1])), shape=shape)
        am.data = np.hstack((weights, weights))
    else:
        am = sprs.coo_matrix((weights, (conns[:, 0], conns[:, 1])), shape=shape)
    return am

def dict_to_im(network):
    r"""
    Convert a graph dictionary into a ``scipy.sparse`` incidence matrix in COO
    format

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    im : sparse matrix
        The sparse incidence matrix in COO format

    Notes
    -----
    Rows correspond to nodes and columns correspond to edges. Each column
    has 2 nonzero values indicating which 2 nodes are connected by the
    corresponding edge. Each row contains an arbitrary number of nonzeros
    whose locations indicate which edges are directly connected to the
    corresponding node.
    """
    edge_prefix = get_edge_prefix(network)
    node_prefix = get_node_prefix(network)
    conns = network[edge_prefix+'.conns']
    coords = network[node_prefix+'.coords']
    if isgtriu(network):
        data = np.ones(2*conns.shape[0], dtype=int)
        shape = (coords.shape[0], conns.shape[0])
        temp = np.arange(conns.shape[0])
        cols = np.vstack((temp, temp)).T.flatten()
        rows = conns.flatten()
        im = sprs.coo_matrix((data, (rows, cols)), shape=shape)
    else:
        raise Exception('This function is not implemented for directed graphs')
    return im

def ismultigraph(network):
    r"""
    Checks if graph contains multiple connections between any pair of nodes

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    flag : bool
        Returns ``True`` if any pair of nodes is connected by more than one
        edge.
    """
    edge_prefix = get_edge_prefix(network)
    node_prefix = get_node_prefix(network)
    conns = network[edge_prefix+'.conns']
    coords = network[node_prefix+'.coords']
    data = np.ones_like(conns[:, 0], dtype=int)
    shape = 2*[coords.shape[0]]
    am = sprs.coo_matrix((data, (conns[:, 0], conns[:, 1])), shape=shape)
    am.sum_duplicates()
    return np.any(am.data > 1)

def isgtriu(network):
    r"""
    Determines if graph connections are in upper triangular format

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    flag : bool
        Returns ``True`` if *all* rows in "conns" are ordered as [lo, hi]
    """
    edge_prefix = get_edge_prefix(network)
    conns = network[edge_prefix+'.conns']
    return np.all(conns[:, 0] < conns[:, 1])

def to_triu(network):
    r"""
    Adjusts conns array to force into upper triangular form

    Parameters
    ----------
    network : dict
        The network dictionary

    Returns
    -------
    network : dict
        The graph dictionary with edge connections updated

    Notes
    -----
    This does not check for the creation of duplicate connections
    """
    edge_prefix = get_edge_prefix(network)
    conns = network[edge_prefix+'.conns']
    network[edge_prefix+'.conns'] = np.sort(conns, axis=1)
    return network

def conns_to_am(conns, shape=None, force_triu=True, drop_diag=True,
                drop_dupes=True, drop_negs=True):
    r"""
    Converts a list of connections into a Scipy sparse adjacency matrix

    Parameters
    ----------
    conns : array_like, N x 2
        The list of site-to-site connections
    shape : list, optional
        The shape of the array.  If none is given then it is taken as 1 + the
        maximum value in ``conns``.
    force_triu : bool
        If True (default), then all connections are assumed undirected, and
        moved to the upper triangular portion of the array
    drop_diag : bool
        If True (default), then connections from a site and itself are removed.
    drop_dupes : bool
        If True (default), then all pairs of sites sharing multiple connections
        are reduced to a single connection.
    drop_negs : bool
        If True (default), then all connections with one or both ends pointing
        to a negative number are removed.

    Returns
    -------
    am : ndarray
        A sparse adjacency matrix in COO format

    """
    if force_triu:  # Sort connections to [low, high]
        conns = np.sort(conns, axis=1)
    if drop_negs:  # Remove connections to -1
        keep = ~np.any(conns < 0, axis=1)
        conns = conns[keep]
    if drop_diag:  # Remove connections of [self, self]
        keep = np.where(conns[:, 0] != conns[:, 1])[0]
        conns = conns[keep]
    # Now convert to actual sparse array in COO format
    data = np.ones_like(conns[:, 0], dtype=int)
    if shape is None:
        N = conns.max() + 1
        shape = (N, N)
    am = sprs.coo_matrix((data, (conns[:, 0], conns[:, 1])), shape=shape)
    if drop_dupes:  # Convert to csr and back too coo
        am = am.tocsr()
        am = am.tocoo()
    # Perform one last check on adjacency matrix
    missing = np.where(np.bincount(conns.flatten()) == 0)[0]
    if np.size(missing) or np.any(am.col.max() < (shape[0] - 1)):
        print('Some nodes are not connected to any bonds')
    return am

def istriu(am):
    r"""
    Returns ``True`` if the sparse adjacency matrix is upper triangular
    """
    if am.shape[0] != am.shape[1]:
        print('Matrix is not square, triangularity is irrelevant')
        return False
    if am.format != 'coo':
        am = am.tocoo(copy=False)
    return np.all(am.row <= am.col)

def istril(am):
    r"""
    Returns ``True`` if the sparse adjacency matrix is lower triangular
    """
    if am.shape[0] != am.shape[1]:
        print('Matrix is not square, triangularity is irrelevant')
        return False
    if am.format != 'coo':
        am = am.tocoo(copy=False)
    return np.all(am.row >= am.col)

def istriangular(am):
    r"""
    Returns ``True`` if the sparse adjacency matrix is either upper or lower
    triangular
    """
    if am.format != 'coo':
        am = am.tocoo(copy=False)
    return istril(am) or istriu(am)

def issymmetric(am):
    r"""
    A method to check if a square matrix is symmetric
    Returns ``True`` if the sparse adjacency matrix is symmetric
    """
    if am.shape[0] != am.shape[1]:
        print('Matrix is not square, symmetrical is irrelevant')
        return False
    if am.format != 'coo':
        am = am.tocoo(copy=False)
    if istril(am) or istriu(am):
        return False
    # Compare am with its transpose, element wise
    sym = ((am != am.T).size) == 0
    return sym


text:
import tempfile
import re
import os

import sublime
import sublime_plugin
from git import git_root, GitTextCommand

class GitClearAnnotationCommand(GitTextCommand):
    def run(self, view):
        self.active_view().settings().set('live_git_annotations', False)
        self.view.erase_regions('git.changes.x')
        self.view.erase_regions('git.changes.+')
        self.view.erase_regions('git.changes.-')

class GitToggleAnnotationsCommand(GitTextCommand):
    def run(self, view):
        if self.active_view().settings().get('live_git_annotations'):
            self.view.run_command('git_clear_annotation')
        else:
            self.view.run_command('git_annotate')

class GitAnnotationListener(sublime_plugin.EventListener):
    def on_modified(self, view):
        if not view.settings().get('live_git_annotations'):
            return
        view.run_command('git_annotate')

    def on_load(self, view):
        s = sublime.load_settings("Git.sublime-settings")
        if s.get('annotations'):
            view.run_command('git_annotate')

class GitAnnotateCommand(GitTextCommand):
    # Unfortunately, git diff does not support text from stdin, making a *live*
    # annotation difficult. Therefore I had to resort to the system diff
    # command.
    # This works as follows:
    # 1. When the command is run for the first time for this file, a temporary
    #    file with the current state of the HEAD is being pulled from git.
    # 2. All consecutive runs will pass the current buffer into diffs stdin.
    #    The resulting output is then parsed and regions are set accordingly.
    def run(self, view):
        # If the annotations are already running, we dont have to create a new
        # tmpfile
        if hasattr(self, "tmp"):
            self.compare_tmp(None)
            return
        self.tmp = tempfile.NamedTemporaryFile()
        self.active_view().settings().set('live_git_annotations', True)
        root = git_root(self.get_working_dir())
        repo_file = os.path.relpath(self.view.file_name(), root)
        self.run_command(['git', 'show', 'HEAD:{0}'.format(repo_file)], show_status=False, no_save=True, callback=self.compare_tmp, stdout=self.tmp)

    def compare_tmp(self, result, stdout=None):
        all_text = self.view.substr(sublime.Region(0, self.view.size())).encode("utf-8")
        self.run_command(['diff', '-u', self.tmp.name, '-'], stdin=all_text, no_save=True, show_status=False, callback=self.parse_diff)

    # This is where the magic happens. At the moment, only one chunk format is supported. While
    # the unified diff format theoritaclly supports more, I don't think git diff creates them.
    def parse_diff(self, result, stdin=None):
        lines = result.splitlines()
        matcher = re.compile('^@@ -([0-9]*),([0-9]*) \+([0-9]*),([0-9]*) @@')
        diff = []
        for line_index in range(0, len(lines)):
            line = lines[line_index]
            if not line.startswith('@'):
                continue
            match = matcher.match(line)
            if not match:
                continue
            line_before, len_before, line_after, len_after = [int(match.group(x)) for x in [1, 2, 3, 4]]
            chunk_index = line_index + 1
            tracked_line_index = line_after - 1
            deletion = False
            insertion = False
            while True:
                line = lines[chunk_index]
                if line.startswith('@'):
                    break
                elif line.startswith('-'):
                    if not line.strip() == '-':
                        deletion = True
                    tracked_line_index -= 1
                elif line.startswith('+'):
                    if deletion and not line.strip() == '+':
                        diff.append(['x', tracked_line_index])
                        insertion = True
                    elif not deletion:
                        insertion = True
                        diff.append(['+', tracked_line_index])
                else:
                    if not insertion and deletion:
                        diff.append(['-', tracked_line_index])
                    insertion = deletion = False
                tracked_line_index += 1
                chunk_index += 1
                if chunk_index >= len(lines):
                    break

        self.annotate(diff)

    # Once we got all lines with their specific change types (either x, +, or - for
    # modified, added, or removed) we can create our regions and do the actual annotation.
    def annotate(self, diff):
        self.view.erase_regions('git.changes.x')
        self.view.erase_regions('git.changes.+')
        self.view.erase_regions('git.changes.-')
        typed_diff = {'x': [], '+': [], '-': []}
        for change_type, line in diff:
            if change_type == '-':
                full_region = self.view.full_line(self.view.text_point(line - 1, 0))
                position = full_region.begin()
                for i in xrange(full_region.size()):
                    typed_diff[change_type].append(sublime.Region(position + i))
            else:
                point = self.view.text_point(line, 0)
                region = self.view.full_line(point)
                if change_type == '-':
                    region = sublime.Region(point, point + 5)
                typed_diff[change_type].append(region)

        for change in ['x', '+']:
            self.view.add_regions("git.changes.{0}".format(change), typed_diff[change], 'git.changes.{0}'.format(change), 'dot', sublime.HIDDEN)

        self.view.add_regions("git.changes.-", typed_diff['-'], 'git.changes.-', 'dot', sublime.DRAW_EMPTY_AS_OVERWRITE)

redpajama_set_name: RedPajamaGithub


text:
/**
 * @author Evgeniya G. Maenkova
 */
package javax.swing.text;

import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.InputMethodEvent;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodRequests;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.AttributedCharacterIterator.Attribute;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingWaitTestCase;
import org.apache.harmony.awt.text.ComposedTextParams;
import org.apache.harmony.awt.text.PropertyNames;

public class JTextComponent_IMLocationTest extends SwingWaitTestCase {
    JTextArea jta;

    JFrame jf;

    InputMethodEvent ime;

    Map<Attribute, Object> map;

    AbstractDocument doc;

    AttributedCharacterIterator iter;

    AttributedString attrString;

    static final AttributedCharacterIterator.Attribute SEGMENT_ATTRIBUTE = AttributedCharacterIterator.Attribute.INPUT_METHOD_SEGMENT;

    static final String initialContent = "IM test";

    boolean bWasException;

    InputMethodRequests imr;

    String message;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        map = new HashMap<Attribute, Object>();
        jf = new JFrame();
        jta = new JTextArea();
        jta.setText(initialContent);
        doc = (AbstractDocument) jta.getDocument();
        imr = jta.getInputMethodRequests();
        bWasException = false;
        message = null;
        jf.getContentPane().add(jta);
        jf.setSize(200, 300);
        jf.setVisible(true);
        component = jf;
    }

    @Override
    protected void tearDown() throws Exception {
        jf.dispose();
        super.tearDown();
    }

    private InputMethodEvent getTextEvent(AttributedCharacterIterator text,
            int committedCharacterCount, TextHitInfo caret, TextHitInfo visiblePosition) {
        return getEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, text,
                committedCharacterCount, caret, visiblePosition);
    }

    private InputMethodEvent getEvent(final int id, final AttributedCharacterIterator text,
            final int committedCharacterCount, final TextHitInfo caret,
            final TextHitInfo visiblePosition) {
        return new InputMethodEvent(jta, id, text, committedCharacterCount, caret,
                visiblePosition);
    }

    private Map<Attribute, Object> putSegmentAttribute(final Map<Attribute, Object> map, final Object value) {
        map.put(SEGMENT_ATTRIBUTE, value);
        return map;
    }

    private AttributedCharacterIterator getIterator(final String text, final Map<Attribute, Object> map) {
        attrString = new AttributedString(text, map);
        return attrString.getIterator();
    }

    private void setComposedText() {
        String content = "12345";
        iter = getIterator(content, putSegmentAttribute(map, Color.RED));
        ime = getTextEvent(iter, 0, TextHitInfo.afterOffset(0), TextHitInfo.afterOffset(0));
        jta.processInputMethodEvent(ime);
        assertEquals(7, jta.getCaretPosition());
        checkComposedTextParams(true, 7, 5);
        assertEquals(initialContent + content, jta.getText());
    }

    private void checkComposedTextParams(final boolean shouldBe, final int start,
            final int length) {
        if (isHarmony()) {
            Object value = doc.getProperty(PropertyNames.COMPOSED_TEXT_PROPERTY);
            if (!shouldBe) {
                assertNull(value);
                return;
            }
            assertTrue(value instanceof ComposedTextParams);
            ComposedTextParams params = (ComposedTextParams) value;
            assertEquals(start, params.getComposedTextStart());
            assertEquals(length, params.getComposedTextLength());
            AttributedString text = params.getComposedText();
            AttributedCharacterIterator iter1 = attrString.getIterator();
            AttributedCharacterIterator iter2 = text.getIterator();
            assertEquals(iter1.getAttributes(), iter2.getAttributes());
            assertEquals(iter1.getRunStart(SEGMENT_ATTRIBUTE), iter2
                    .getRunStart(SEGMENT_ATTRIBUTE));
            assertEquals(Math.min(iter1.getRunLimit(SEGMENT_ATTRIBUTE), iter2.getEndIndex()),
                    iter2.getRunLimit(SEGMENT_ATTRIBUTE));
        }
    }

    public void testGetLocationOffset() {
        try {
            setComposedText();
            Rectangle rect;
            Point location = jta.getLocationOnScreen();
            for (int i = 0; i < 7; i++) {
                rect = jta.modelToView(i);
                rect.translate(location.x, location.y);
                assertNull(imr.getLocationOffset(rect.x, rect.y));
            }
            for (int i = 7; i < 13; i++) {
                rect = jta.modelToView(i);
                rect.translate(location.x, location.y);
                assertEquals(TextHitInfo.afterOffset(i - 7), imr.getLocationOffset(rect.x,
                        rect.y));
            }
        } catch (BadLocationException e) {
        }
    }

    public void testGetTextLocation() {
        try {
            setComposedText();
            int pos = 7;
            Rectangle rect = jta.modelToView(pos);
            Point location = jta.getLocationOnScreen();
            rect.translate(location.x, location.y);
            for (int i = 0; i < 10; i++) {
                assertEquals(rect, imr.getTextLocation(TextHitInfo.beforeOffset(i)));
                assertEquals(rect, imr.getTextLocation(TextHitInfo.afterOffset(i)));
            }
            iter = getIterator("klnoprst", putSegmentAttribute(map, Color.BLACK));
            ime = getTextEvent(iter, 5, TextHitInfo.afterOffset(0), TextHitInfo.afterOffset(0));
            jta.processInputMethodEvent(ime);
            pos = 12;
            rect = jta.modelToView(pos);
            rect.translate(location.x, location.y);
            for (int i = 0; i < 10; i++) {
                assertEquals(rect, imr.getTextLocation(TextHitInfo.beforeOffset(i)));
                assertEquals(rect, imr.getTextLocation(TextHitInfo.afterOffset(i)));
            }
        } catch (BadLocationException e) {
            assertFalse("unexpectedException", true);
        }
    }
}


text:
import numpy as np
import astropy.io.fits as fits
import os

### This is a group of functions meant to manipulate 1d spectra as numpy arrays

# returns the dispersion and flux as a tuple of arrays from a fits file. The WCS is used to calculate the dispersion. Only simple linear or log dispersion is handled
def load(name, extension=0, axis=0):

	hdulist = fits.open(open(os.path.abspath(os.path.expanduser(name)), 'rb'))
	data = hdulist[extension].data

	if len(data.shape) > 1:
		data = data[axis]

	crval = hdulist[extension].header['CRVAL1']
	cdelt = hdulist[extension].header['CDELT1']

	if 'CRPIX1' in hdulist[extension].header:
		crpix = hdulist[extension].header['CRPIX1']
	else:
		crpix = 1
	wavelengths = np.arange(data.size)
	wavelengths =  (wavelengths - crpix + 1) * cdelt + crval
	if 'DC-FLAG' in hdulist[extension].header and hdulist[extension].header['DC-FLAG']:
		#log dispersion
		wavelengths = np.exp(wavelengths * np.log(10))
	hdulist.close()

	return (wavelengths, data)

def load_with_errors(name):

	hdulist = fits.open(open(os.path.abspath(os.path.expanduser(name)), 'rb'))
	fluxes = hdulist[0].data
	errors = hdulist[1].data

	crval = hdulist[0].header['CRVAL1']
	cdelt = hdulist[0].header['CDELT1']

	if 'CRPIX1' in hdulist[0].header:
		crpix = hdulist[0].header['CRPIX1']
	else:
		crpix = 1
	wavelengths = np.arange(fluxes.size)
	wavelengths =  (wavelengths - crpix + 1) * cdelt + crval
	if 'DC-FLAG' in hdulist[0].header and hdulist[0].header['DC-FLAG']:
		#log dispersion
		wavelengths = np.exp(wavelengths * np.log(10))
	hdulist.close()

	return (wavelengths, fluxes, errors)

def getspectrum(name, extension=0, axis=0):

	return load(name, extension, axis)

def write(name, wavelengths, fluxes, clobber=False):
	hdu = fits.PrimaryHDU(fluxes)
	hdu.header.set('CRPIX1', 1)
	hdu.header.set('CRVAL1', wavelengths[0])
	hdu.header.set('CDELT1', wavelengths[1] - wavelengths[0])
	hdu.header.set('DC-FLAG', 0)
	hdulist = fits.HDUList([hdu])

	hdulist.writeto(name, clobber=clobber)
	hdulist.close()

def writespectrum(name, wavelengths, fluxes, clobber=False):

	writespectrum(name, wavelengths, fluxes, clobber=False)

def save(name, wavelengths, fluxes, clobber=False):

	writespectrum(name, wavelengths, fluxes, clobber=False)

#boxcar smooth an array using of a kernel of 2 * 'kernel' + 1 pixels
def smooth(data, kernel=3):
	output = np.empty(data.size)

	for i in range(data.size):
		if i - kernel < 0:
			output[i] = data[0:i + kernel + 1].mean()
		elif data.size - (i + kernel + 1) < 0:
			output[i] = data[i - kernel:data.size].mean()
		else:
			output[i] = data[i - kernel:i + kernel + 1].mean()
	return output

def updateheader(name, pairs):
	hdulist = fits.open(name, mode='update')
	header = hdulist[0].header
	for key in pairs.keys():
		header.set(key, pairs[key])
	hdulist.close()

def listheader(name, keys=None):
	hdulist = fits.open(open(os.path.abspath(os.path.expanduser(name)), 'rb'))
	header = hdulist[0].header
	hdulist.close()
	if keys is None:
		return header
	elif isinstance(keys, str):
		return header[keys]
	else:
		output = []

		for key in keys:
			output.append(header[key])
		return output


text:
package com.microsoft.azure.documentdb;

/**
 * HTTP constants.
 */
class HttpConstants {
    public static class HttpMethods {
        public static final String GET = "GET";
        public static final String POST = "POST";
        public static final String PUT = "PUT";
        public static final String DELETE = "DELETE";
        public static final String HEAD = "HEAD";
        public static final String OPTIONS = "OPTIONS";
        public static final String PATCH = "PATCH";
    }

    public static class HttpHeaders {
        public static final String AUTHORIZATION = "authorization";
        public static final String E_TAG = "etag";
        public static final String METHOD_OVERRIDE = "X-HTTP-Method";
        public static final String SLUG = "Slug";
        public static final String CONTENT_TYPE = "Content-Type";
        public static final String LAST_MODIFIED = "Last-Modified";
        public static final String CONTENT_ENCODING = "Content-Encoding";
        public static final String CHARACTER_SET = "CharacterSet";
        public static final String USER_AGENT = "User-Agent";
        public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
        public static final String IF_MATCH = "If-Match";
        public static final String IF_NONE_MATCH = "If-None-Match";
        public static final String CONTENT_LENGTH = "Content-Length";
        public static final String ACCEPT_ENCODING = "Accept-Encoding";
        public static final String KEEP_ALIVE = "Keep-Alive";
        public static final String CACHE_CONTROL = "Cache-Control";
        public static final String TRANSFER_ENCODING = "Transfer-Encoding";
        public static final String CONTENT_LANGUAGE = "Content-Language";
        public static final String CONTENT_LOCATION = "Content-Location";
        public static final String CONTENT_MD5 = "Content-Md5";
        public static final String CONTENT_RANGE = "Content-Range";
        public static final String ACCEPT = "Accept";
        public static final String ACCEPT_CHARSET = "Accept-Charset";
        public static final String ACCEPT_LANGUAGE = "Accept-Language";
        public static final String IF_RANGE = "If-Range";
        public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since";
        public static final String MAX_FORWARDS = "Max-Forwards";
        public static final String PROXY_AUTHORIZATION = "Proxy-Authorization";
        public static final String ACCEPT_RANGES = "Accept-Ranges";
        public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate";
        public static final String RETRY_AFTER = "Retry-After";
        public static final String SET_COOKIE = "Set-Cookie";
        public static final String WWW_AUTHENTICATE = "Www-Authenticate";
        public static final String ORIGIN = "Origin";
        public static final String HOST = "Host";
        public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
        public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
        public static final String KEY_VALUE_ENCODING_FORMAT = "application/x-www-form-urlencoded";
        public static final String WRAP_ASSERTION_FORMAT = "wrap_assertion_format";
        public static final String WRAP_ASSERTION = "wrap_assertion";
        public static final String WRAP_SCOPE = "wrap_scope";
        public static final String SIMPLE_TOKEN = "SWT";
        public static final String HTTP_DATE = "date";
        public static final String PREFER = "Prefer";
        public static final String LOCATION = "Location";
        public static final String REFERER = "referer";

        // Query
        public static final String QUERY = "x-ms-documentdb-query";
        public static final String IS_QUERY = "x-ms-documentdb-isquery";

        // Our custom DocDB headers
        public static final String CONTINUATION = "x-ms-continuation";
        public static final String PAGE_SIZE = "x-ms-max-item-count";

        // Request sender generated. Simply echoed by backend.
        public static final String ACTIVITY_ID = "x-ms-activity-id";
        public static final String PRE_TRIGGER_INCLUDE = "x-ms-documentdb-pre-trigger-include";
        public static final String PRE_TRIGGER_EXCLUDE = "x-ms-documentdb-pre-trigger-exclude";
        public static final String POST_TRIGGER_INCLUDE = "x-ms-documentdb-post-trigger-include";
        public static final String POST_TRIGGER_EXCLUDE = "x-ms-documentdb-post-trigger-exclude";
        public static final String INDEXING_DIRECTIVE = "x-ms-indexing-directive";
        public static final String SESSION_TOKEN = "x-ms-session-token";
        public static final String CONSISTENCY_LEVEL = "x-ms-consistency-level";
        public static final String X_DATE = "x-ms-date";
        public static final String COLLECTION_PARTITION_INFO = "x-ms-collection-partition-info";
        public static final String COLLECTION_SERVICE_INFO = "x-ms-collection-service-info";
        public static final String RETRY_AFTER_IN_MILLISECONDS = "x-ms-retry-after-ms";
        public static final String IS_FEED_UNFILTERED = "x-ms-is-feed-unfiltered";
        public static final String RESOURCE_TOKEN_EXPIRY = "x-ms-documentdb-expiry-seconds";
        public static final String ENABLE_SCAN_IN_QUERY = "x-ms-documentdb-query-enable-scan";
        public static final String EMIT_VERBOSE_TRACES_IN_QUERY = "x-ms-documentdb-query-emit-traces";

        // Quota Info

        public static final String MAX_RESOURCE_QUOTA = "x-ms-resource-quota";
        public static final String CURRENT_RESOURCE_QUOTA_USAGE = "x-ms-resource-usage";
        public static final String MAX_MEDIA_STORAGE_USAGE_IN_MB = "x-ms-max-media-storage-usage-mb";

        // Usage Info
        public static final String REQUEST_CHARGE = "x-ms-request-charge";
        public static final String CURRENT_MEDIA_STORAGE_USAGE_IN_MB = "x-ms-media-storage-usage-mb";
        public static final String DATABASE_ACCOUNT_CONSUMED_DOCUMENT_STORAGE_IN_MB = "x-ms-databaseaccount-consumed-mb";
        public static final String DATABASE_ACCOUNT_RESERVED_DOCUMENT_STORAGE_IN_MB = "x-ms-databaseaccount-reserved-mb";
        public static final String DATABASE_ACCOUNT_PROVISIONED_DOCUMENT_STORAGE_IN_MB = "x-ms-databaseaccount-provisioned-mb";

        // Address related headers.
        public static final String FORCE_REFRESH = "x-ms-force-refresh";
        public static final String ITEM_COUNT = "x-ms-item-count";
        public static final String NEW_RESOURCE_ID = "x-ms-new-resource-id";
        public static final String USE_MASTER_COLLECTION_RESOLVER = "x-ms-use-master-collection-resolver";
        // Admin Headers
        public static final String FULL_UPGRADE = "x-ms-force-full-upgrade";
        public static final String ONLY_UPGRADE_SYSTEM_APPLICATIONS = "x-ms-only-upgrade-system-applications";
        public static final String ONLY_UPGRADE_NON_SYSTEM_APPLICATIONS = "x-ms-only-upgrade-non-system-applications";
        public static final String UPGRADE_FABRIC_RING_CODE_AND_CONFIG = "x-ms-upgrade-fabric-code-config";
        public static final String IGNORE_IN_PROGRESS_UPGRADE = "x-ms-ignore-inprogress-upgrade";
        public static final String UPGRADE_VERIFICATION_KIND = "x-ms-upgrade-verification-kind";
        public static final String IS_CANARY = "x-ms-iscanary";
        public static final String FORCE_DELETE = "x-ms-force-delete";

        // Version headers and values
        public static final String VERSION = "x-ms-version";
        public static final String SCHEMA_VERSION = "x-ms-schemaversion";
        public static final String SERVER_VERSION = "x-ms-serviceversion";
        public static final String GATEWAY_VERSION = "x-ms-gatewayversion";

        // RDFE Resource Provider headers
        public static final String OCP_RESOURCE_PROVIDER_REGISTERED_URI = "ocp-resourceprovider-registered-uri";

        // For Document service management operations only. This is in
        // essence a 'handle' to (long running) operations.
        public static final String REQUEST_ID = "x-ms-request-id";

        // Object returning this determines what constitutes state and what
        // last state change means. For replica, it is the last role change.
        public static final String LAST_STATE_CHANGE_UTC = "x-ms-last-state-change-utc";

        // CSM specific headers
        // Client-request-id: Optional caller-specified request ID, in the form
        // of a GUID
        public static final String CLIENT_REQUEST_ID = "x-ms-client-request-id";

        // Offer header
        public static final String OFFER_TYPE = "x-ms-offer-type";

        // Upsert header
        public static final String IS_UPSERT = "x-ms-documentdb-is-upsert";

        // Index progress headers
        public static final String INDEX_TRANSFORMATION_PROGRESS = "x-ms-documentdb-collection-index-transformation-progress";
        public static final String LAZY_INDEXING_PROGRESS = "x-ms-documentdb-collection-lazy-indexing-progress";

        //Owner name
        public static final String OWNER_FULL_NAME = "x-ms-alt-content-path";

        //Owner ID used for name based request in session token.
        public static final String OWNER_ID = "x-ms-content-path";
    }

    public static class Versions {
        public static String CURRENT_VERSION = "2015-08-06";
        public static String USER_AGENT = "documentdb-java-sdk-1.5.1";
    }

    public static class StatusCodes {
        public static int MINIMUM_STATUSCODE_AS_ERROR_GATEWAY = 400;
    }
}


text:
ActiveRecord::Schema.define(version: 20150331024625) do

  create_table "comments", force: :cascade do |t|
    t.integer  "post_id"
    t.string   "name"
    t.string   "email"
    t.string   "content"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "comments", ["post_id"], name: "index_comments_on_post_id"

  create_table "posts", force: :cascade do |t|
    t.string   "title"
    t.text     "content"
    t.datetime "post_time"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

end


text:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_download_manager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="android.qiao.androidlearn.activity.DownloadManagerActivity">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:ems="10"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="27dp"
        android:layout_marginTop="31dp"
        android:id="@+id/inputUrl"/>

    <TextView
        android:text="The Url of File"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/inputUrl"
        android:layout_toStartOf="@+id/inputUrl"
        android:layout_marginEnd="18dp"
        android:layout_marginBottom="10dp"
        android:id="@+id/labelUrl"/>

    <Button
        android:text="Download"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignStart="@+id/inputUrl"
        android:layout_marginBottom="42dp"
        android:id="@+id/buttonDownload"
        android:textAllCaps="false"/>

    <Button
        android:text="Get Download Info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="18dp"
        android:id="@+id/button_get_download_info"
        android:textAllCaps="false"
        android:layout_alignBaseline="@+id/buttonDownload"
        android:layout_alignBottom="@+id/buttonDownload"
        android:layout_toEndOf="@+id/buttonDownload"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/button_remove_download"
        android:textAllCaps="false"
        android:text="Remove Download"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"/>
</RelativeLayout>


text:
module Facebase
  class Shard < ActiveRecord::Base

    # Allows for a centralized configuration server
    if Facebase.config_database_uri.present?
      establish_connection(Facebase.config_database_uri)
    end

    PRINCIPLE_PROFILE = "profile"
    PRINCIPLE_EMAIL = "email"

    before_create :setup_splits

    # Returns the index of this shard when sorted by id in a array of all shards
    def asc_index
      Facebase::Shard.order("id asc").all.each_with_index do |shard, index|
        return index if shard.id == self.id
      end
    end

    def components
      [PRINCIPLE_PROFILE, PRINCIPLE_EMAIL]
    end

    def connection_spec(include_database=true)
      connection_spec = {
        :adapter => self.adapter,
        :username => self.username,
        :password => self.password,

        :pool => self.pool,
        :reconnect => self.reconnect,
        :encoding => self.encoding,
      }

      # Sometimes you want the default connection without a database specified
      connection_spec[:database] = self.database if (include_database)

      if self.host.present?
        connection_spec[:host] = self.host
      else
        connection_spec[:socket] = self.socket
      end
      connection_spec
    end

    # Shards are [ self.auto_increment_start ... auto_increment_end)
    # Ie end exclusive. The end marks the beginning of a new shard
    def owns_principle_id?(principle_id)
      (self.auto_increment_start ... auto_increment_end).cover?(principle_id.to_i)
    end

    def auto_increment_end
      self.auto_increment_start + self.auto_increment_range
    end

    def initialize_shard
      if self.principle_model == PRINCIPLE_PROFILE
        #Set the autoincrement point
        Facebase::ShardInitializer.construct_class_set_for_shard(self)
        principle_class = Facebase::Profile.shard_for_shard_id(self.id)
        principle_class.connection.execute("ALTER TABLE #{principle_class.table_name} AUTO_INCREMENT = #{self.auto_increment_start}")
        self.update_attribute(:initialized, true)
      end
    end

    protected
    def setup_splits
      # If specified on creation don't override
      return if self.auto_increment_range.present? || self.auto_increment_start.present?

      shard_to_split = nil
      largest_shard_range = nil

      # Select the shard with the largest range left as the candidate to split
      self.class.where(:principle_model => self.principle_model).all.each do |shard|
        curr_range = shard.auto_increment_range
        if largest_shard_range.nil? || curr_range > largest_shard_range
          largest_shard_range = curr_range
          shard_to_split = shard
        end
      end

      # 18446744073709551615 = 2^64 - 1 (zero based unsigned integer)
      largest_shard_range = 18446744073709551615 if largest_shard_range.nil?

      # If there was a shard that we are splitting (the case for all
      # but the first allocation). Update its range appropriately otherwise
      # initialize the first shard with the full range
      if shard_to_split.present?
        first_half, second_half = split_range(largest_shard_range)
        shard_to_split.update_attribute(:auto_increment_range, first_half)
        self.auto_increment_range = second_half
        self.auto_increment_start = shard_to_split.auto_increment_start + first_half
      else
        self.auto_increment_range = largest_shard_range
        self.auto_increment_start = 1
      end
    end

    # Splits a range evenly accounting for odd and even splits
    def split_range(partition)
      half = partition/2
      second_half = partition/2
      second_half += 1 if partition.odd?
      return half, second_half
    end

  end
end


text:
package org.springframework.boot.actuate.autoconfigure.jms;

import java.util.Map;

import javax.jms.ConnectionFactory;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthIndicatorConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.jms.JmsHealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration;
import org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * {@link EnableAutoConfiguration Auto-configuration} for {@link JmsHealthIndicator}.
 *
 * @author Stephane Nicoll
 * @since 2.0.0
 */
@Configuration
@ConditionalOnClass(ConnectionFactory.class)
@ConditionalOnBean(ConnectionFactory.class)
@ConditionalOnEnabledHealthIndicator("jms")
@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class)
@AutoConfigureAfter({ ActiveMQAutoConfiguration.class, ArtemisAutoConfiguration.class })
public class JmsHealthIndicatorAutoConfiguration extends
		CompositeHealthIndicatorConfiguration<JmsHealthIndicator, ConnectionFactory> {

	private final Map<String, ConnectionFactory> connectionFactories;

	public JmsHealthIndicatorAutoConfiguration(
			ObjectProvider<Map<String, ConnectionFactory>> connectionFactories) {
		this.connectionFactories = connectionFactories.getIfAvailable();
	}

	@Bean
	@ConditionalOnMissingBean(name = "jmsHealthIndicator")
	public HealthIndicator jmsHealthIndicator() {
		return createHealthIndicator(this.connectionFactories);
	}

}


text:
#ifndef WebGeolocationController_h
#define WebGeolocationController_h

#include "../platform/WebCommon.h"
#include "../platform/WebNonCopyable.h"

namespace blink {

class GeolocationController;
class WebGeolocationPosition;
class WebGeolocationError;

// Note that the WebGeolocationController is invalid after the
// WebGeolocationClient::geolocationDestroyed() has been received.
class WebGeolocationController : public WebNonCopyable {
public:
    BLINK_EXPORT void positionChanged(const WebGeolocationPosition&);
    BLINK_EXPORT void errorOccurred(const WebGeolocationError&);

#if BLINK_IMPLEMENTATION
    WebGeolocationController(GeolocationController* c)
        : m_private(c)
    {
    }

    blink::GeolocationController* controller() const { return m_private; }
#endif

private:
    // No implementation for the default constructor. Declared private to ensure that no instances
    // can be created by the consumers of Chromium WebKit.
    WebGeolocationController();

    GeolocationController* m_private;
};

} // namespace blink

#endif // WebGeolocationController_h


text:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Runtime.Serialization;

namespace Expenses.Data
{
    [DataContract(Name="Charge", IsReference = true)]
    public class DbCharge
    {
        public DbCharge()
        { }

        [DataMember]
        [Key]
        public int ChargeId { get; set; }
        [DataMember]
        public int EmployeeId { get; set; }
        public virtual DbEmployee Employee { get; set; }
        [DataMember]
        public int? ExpenseReportId { get; set; }
        public virtual DbExpenseReport ExpenseReport { get; set; }
        [DataMember]
        [Column(TypeName = "date")]
        public DateTime ExpenseDate { get; set; }
        [DataMember]
        [Required]
        [StringLength(50)]
        public string Merchant { get; set; }
        [DataMember]
        [Required]
        [StringLength(50)]
        public string Location { get; set; }
        [DataMember]
        [Column(TypeName = "smallmoney")]
        public decimal BilledAmount { get; set; }
        [DataMember]
        [Column(TypeName = "smallmoney")]
        public decimal TransactionAmount { get; set; }
        [DataMember]
        [Required]
        [StringLength(250)]
        public string Description { get; set; }
        [DataMember]
        [StringLength(250)]
        public string Notes { get; set; }
    }
}


text:
import { animate, style, transition, trigger } from '@angular/animations';
import {
    ChangeDetectionStrategy,
    Component,
    EventEmitter,
    Input,
    Output
} from '@angular/core';
import { Action } from '@ngrx/store';

import { Alert } from '../../state/reducers/alert';

@Component({
    selector: 'app-alert',
    templateUrl: './alert.component.html',
    changeDetection: ChangeDetectionStrategy.OnPush,
    animations: [
        trigger('translate', [
            transition(':enter', [
                style({transform: 'translateY(100%)'}),
                animate('600ms ease', style({transform: 'translateY(0)'}))
            ]),
            transition(':leave', [
                animate('600ms ease', style({transform: 'translateY(100%)'}))
            ])
        ])
    ]
})
export class AlertComponent {
    @Input()
    public alert: Alert | null = null;

    @Output()
    public close: EventEmitter<void> = new EventEmitter();

    @Output()
    public action: EventEmitter<Action[]> = new EventEmitter();

    public closeAlert(): void {
        this.close.emit();
    }

    public emitAction(alert: Alert): void {
        this.action.emit(alert.actions);
    }

    public iconInfoFromType(type: string): string {
        switch (type) {
            case 'warning':
            case 'alert-warning':
                return 'exclamation-triangle';
            case 'danger':
            case 'alert-danger':
                return 'exclamation-circle';
            case 'success':
            case 'alert-success':
                return 'check-circle';
            default:
                return 'info-circle';
        }
    }
}


text:
using System;

namespace StateBasedNavigation.Desktop.Infrastructure
{
    public class OperationResult : IOperationResult
    {
        public Exception Error
        {
            get;
            protected internal set;
        }
    }
}


text:
from __future__ import absolute_import

import responses
import sentry

from sentry.utils.compat.mock import MagicMock
from six.moves.urllib.parse import urlencode, urlparse

from sentry.shared_integrations.exceptions import ApiError
from sentry.constants import ObjectStatus
from sentry.integrations.github import GitHubIntegrationProvider, API_ERRORS
from sentry.models import Integration, OrganizationIntegration, Repository, Project
from sentry.plugins.base import plugins
from sentry.testutils import IntegrationTestCase
from tests.sentry.plugins.testutils import register_mock_plugins, unregister_mock_plugins

class GitHubIntegrationTest(IntegrationTestCase):
    provider = GitHubIntegrationProvider
    base_url = "https://api.github.com"

    def setUp(self):
        super(GitHubIntegrationTest, self).setUp()

        self.installation_id = "install_1"
        self.user_id = "user_1"
        self.app_id = "app_1"
        self.access_token = "xxxxx-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx"
        self.expires_at = "3000-01-01T00:00:00Z"

        self._stub_github()
        register_mock_plugins()

    def tearDown(self):
        unregister_mock_plugins()
        super(GitHubIntegrationTest, self).tearDown()

    def _stub_github(self):
        responses.reset()

        sentry.integrations.github.integration.get_jwt = MagicMock(return_value=b"jwt_token_1")
        sentry.integrations.github.client.get_jwt = MagicMock(return_value=b"jwt_token_1")

        responses.add(
            responses.POST,
            self.base_url + "/app/installations/{}/access_tokens".format(self.installation_id),
            json={"token": self.access_token, "expires_at": self.expires_at},
        )

        responses.add(
            responses.GET,
            self.base_url + "/installation/repositories",
            json={
                "repositories": [
                    {"id": 1296269, "name": "foo", "full_name": "Test-Organization/foo"},
                    {"id": 9876574, "name": "bar", "full_name": "Test-Organization/bar"},
                ]
            },
        )

        responses.add(
            responses.GET,
            self.base_url + "/app/installations/{}".format(self.installation_id),
            json={
                "id": self.installation_id,
                "app_id": self.app_id,
                "account": {
                    "login": "Test Organization",
                    "avatar_url": "http://example.com/avatar.png",
                    "html_url": "https://github.com/Test-Organization",
                    "type": "Organization",
                },
            },
        )

        responses.add(responses.GET, self.base_url + "/repos/Test-Organization/foo/hooks", json=[])

    def assert_setup_flow(self):
        resp = self.client.get(self.init_path)
        assert resp.status_code == 302
        redirect = urlparse(resp["Location"])
        assert redirect.scheme == "https"
        assert redirect.netloc == "github.com"
        assert redirect.path == "/apps/sentry-test-app"

        # App installation ID is provided
        resp = self.client.get(
            u"{}?{}".format(self.setup_path, urlencode({"installation_id": self.installation_id}))
        )

        auth_header = responses.calls[0].request.headers["Authorization"]
        assert auth_header == b"Bearer jwt_token_1"

        self.assertDialogSuccess(resp)
        return resp

    @responses.activate
    def test_plugin_migration(self):
        accessible_repo = Repository.objects.create(
            organization_id=self.organization.id,
            name="Test-Organization/foo",
            url="https://github.com/Test-Organization/foo",
            provider="github",
            external_id=123,
            config={"name": "Test-Organization/foo"},
        )

        inaccessible_repo = Repository.objects.create(
            organization_id=self.organization.id,
            name="Not-My-Org/other",
            provider="github",
            external_id=321,
            config={"name": "Not-My-Org/other"},
        )

        with self.tasks():
            self.assert_setup_flow()

        integration = Integration.objects.get(provider=self.provider.key)

        # Updates the existing Repository to belong to the new Integration
        assert Repository.objects.get(id=accessible_repo.id).integration_id == integration.id

        # Doesn't touch Repositories not accessible by the new Integration
        assert Repository.objects.get(id=inaccessible_repo.id).integration_id is None

    @responses.activate
    def test_basic_flow(self):
        with self.tasks():
            self.assert_setup_flow()

        integration = Integration.objects.get(provider=self.provider.key)

        assert integration.external_id == self.installation_id
        assert integration.name == "Test Organization"
        assert integration.metadata == {
            "access_token": None,
            # The metadata doesn't get saved with the timezone "Z" character
            # for some reason, so just compare everything but that.
            "expires_at": None,
            "icon": "http://example.com/avatar.png",
            "domain_name": "github.com/Test-Organization",
            "account_type": "Organization",
        }
        oi = OrganizationIntegration.objects.get(
            integration=integration, organization=self.organization
        )
        assert oi.config == {}

    @responses.activate
    def test_reinstall_flow(self):
        self._stub_github()
        self.assert_setup_flow()

        integration = Integration.objects.get(provider=self.provider.key)
        integration.update(status=ObjectStatus.DISABLED)
        assert integration.status == ObjectStatus.DISABLED
        assert integration.external_id == self.installation_id

        resp = self.client.get(
            u"{}?{}".format(self.init_path, urlencode({"reinstall_id": integration.id}))
        )

        assert resp.status_code == 302
        redirect = urlparse(resp["Location"])
        assert redirect.scheme == "https"
        assert redirect.netloc == "github.com"
        assert redirect.path == "/apps/sentry-test-app"

        # New Installation
        self.installation_id = "install_2"

        self._stub_github()

        resp = self.client.get(
            u"{}?{}".format(self.setup_path, urlencode({"installation_id": self.installation_id}))
        )

        assert resp.status_code == 200

        auth_header = responses.calls[0].request.headers["Authorization"]
        assert auth_header == b"Bearer jwt_token_1"

        integration = Integration.objects.get(provider=self.provider.key)
        assert integration.status == ObjectStatus.VISIBLE
        assert integration.external_id == self.installation_id

    @responses.activate
    def test_disable_plugin_when_fully_migrated(self):
        self._stub_github()

        project = Project.objects.create(organization_id=self.organization.id)

        plugin = plugins.get("github")
        plugin.enable(project)

        # Accessible to new Integration - mocked in _stub_github
        Repository.objects.create(
            organization_id=self.organization.id,
            name="Test-Organization/foo",
            url="https://github.com/Test-Organization/foo",
            provider="github",
            external_id="123",
            config={"name": "Test-Organization/foo"},
        )

        # Enabled before
        assert "github" in [p.slug for p in plugins.for_project(project)]

        with self.tasks():
            self.assert_setup_flow()

        # Disabled after Integration installed
        assert "github" not in [p.slug for p in plugins.for_project(project)]

    @responses.activate
    def test_get_repositories_search_param(self):
        with self.tasks():
            self.assert_setup_flow()

        responses.add(
            responses.GET,
            self.base_url + "/search/repositories?q=org:test%20ex",
            json={
                "items": [
                    {"name": "example", "full_name": "test/example"},
                    {"name": "exhaust", "full_name": "test/exhaust"},
                ]
            },
        )
        integration = Integration.objects.get(provider=self.provider.key)
        installation = integration.get_installation(self.organization)
        result = installation.get_repositories("ex")
        assert result == [
            {"identifier": "test/example", "name": "example"},
            {"identifier": "test/exhaust", "name": "exhaust"},
        ]

    @responses.activate
    def test_get_stacktrace_link_file_exists(self):
        self.assert_setup_flow()
        integration = Integration.objects.get(provider=self.provider.key)
        repo = Repository.objects.create(
            organization_id=self.organization.id,
            name="Test-Organization/foo",
            url="https://github.com/Test-Organization/foo",
            provider="integrations:github",
            external_id=123,
            config={"name": "Test-Organization/foo"},
            integration_id=integration.id,
        )

        path = "README.md"
        version = "1234567"
        default = "master"
        responses.add(
            responses.HEAD,
            self.base_url + u"/repos/{}/contents/{}?ref={}".format(repo.name, path, version),
        )
        installation = integration.get_installation(self.organization)
        result = installation.get_stacktrace_link(repo, path, default, version)

        assert result == "https://github.com/Test-Organization/foo/blob/1234567/README.md"

    @responses.activate
    def test_get_stacktrace_link_file_doesnt_exists(self):
        self.assert_setup_flow()
        integration = Integration.objects.get(provider=self.provider.key)

        repo = Repository.objects.create(
            organization_id=self.organization.id,
            name="Test-Organization/foo",
            url="https://github.com/Test-Organization/foo",
            provider="integrations:github",
            external_id=123,
            config={"name": "Test-Organization/foo"},
            integration_id=integration.id,
        )
        path = "README.md"
        version = "master"
        default = "master"
        responses.add(
            responses.HEAD,
            self.base_url + u"/repos/{}/contents/{}?ref={}".format(repo.name, path, version),
            status=404,
        )
        installation = integration.get_installation(self.organization)
        result = installation.get_stacktrace_link(repo, path, default, version)

        assert not result

    @responses.activate
    def test_get_stacktrace_link_use_default_if_version_404(self):
        self.assert_setup_flow()
        integration = Integration.objects.get(provider=self.provider.key)

        repo = Repository.objects.create(
            organization_id=self.organization.id,
            name="Test-Organization/foo",
            url="https://github.com/Test-Organization/foo",
            provider="integrations:github",
            external_id=123,
            config={"name": "Test-Organization/foo"},
            integration_id=integration.id,
        )
        path = "README.md"
        version = "12345678"
        default = "master"
        responses.add(
            responses.HEAD,
            self.base_url + u"/repos/{}/contents/{}?ref={}".format(repo.name, path, version),
            status=404,
        )
        responses.add(
            responses.HEAD,
            self.base_url + u"/repos/{}/contents/{}?ref={}".format(repo.name, path, default),
        )
        installation = integration.get_installation(self.organization)
        result = installation.get_stacktrace_link(repo, path, default, version)

        assert result == "https://github.com/Test-Organization/foo/blob/master/README.md"

    @responses.activate
    def test_get_message_from_error(self):
        self.assert_setup_flow()
        integration = Integration.objects.get(provider=self.provider.key)
        installation = integration.get_installation(self.organization)
        base_error = "Error Communicating with GitHub (HTTP 404): %s" % (API_ERRORS[404])
        assert (
            installation.message_from_error(
                ApiError("Not Found", code=404, url="https://api.github.com/repos/scefali")
            )
            == base_error
        )
        url = "https://api.github.com/repos/scefali/sentry-integration-example/compare/2adcab794f6f57efa8aa84de68a724e728395792...e208ee2d71e8426522f95efbdae8630fa66499ab"
        assert (
            installation.message_from_error(ApiError("Not Found", code=404, url=url))
            == base_error
            + " Please also confirm that the commits associated with the following URL have been pushed to GitHub: %s"
            % url
        )