text:
package flowcontrol

import (
	"sync"
	"time"

	"github.com/ethereum/go-ethereum/common/mclock"
)

const fcTimeConst = 1000000

type ServerParams struct {
	BufLimit, MinRecharge uint64
}

type ClientNode struct {
	params   *ServerParams
	bufValue uint64
	lastTime int64
	lock     sync.Mutex
	cm       *ClientManager
	cmNode   *cmNode
}

func NewClientNode(cm *ClientManager, params *ServerParams) *ClientNode {
	node := &ClientNode{
		cm:       cm,
		params:   params,
		bufValue: params.BufLimit,
		lastTime: getTime(),
	}
	node.cmNode = cm.addNode(node)
	return node
}

func (peer *ClientNode) Remove(cm *ClientManager) {
	cm.removeNode(peer.cmNode)
}

func (peer *ClientNode) recalcBV(time int64) {
	dt := uint64(time - peer.lastTime)
	if time < peer.lastTime {
		dt = 0
	}
	peer.bufValue += peer.params.MinRecharge * dt / fcTimeConst
	if peer.bufValue > peer.params.BufLimit {
		peer.bufValue = peer.params.BufLimit
	}
	peer.lastTime = time
}

func (peer *ClientNode) AcceptRequest() (uint64, bool) {
	peer.lock.Lock()
	defer peer.lock.Unlock()

	time := getTime()
	peer.recalcBV(time)
	return peer.bufValue, peer.cm.accept(peer.cmNode, time)
}

func (peer *ClientNode) RequestProcessed(cost uint64) (bv, realCost uint64) {
	peer.lock.Lock()
	defer peer.lock.Unlock()

	time := getTime()
	peer.recalcBV(time)
	peer.bufValue -= cost
	peer.recalcBV(time)
	rcValue, rcost := peer.cm.processed(peer.cmNode, time)
	if rcValue < peer.params.BufLimit {
		bv := peer.params.BufLimit - rcValue
		if bv > peer.bufValue {
			peer.bufValue = bv
		}
	}
	return peer.bufValue, rcost
}

type ServerNode struct {
	bufEstimate uint64
	lastTime    int64
	params      *ServerParams
	sumCost     uint64            // sum of req costs sent to this server
	pending     map[uint64]uint64 // value = sumCost after sending the given req
	lock        sync.RWMutex
}

func NewServerNode(params *ServerParams) *ServerNode {
	return &ServerNode{
		bufEstimate: params.BufLimit,
		lastTime:    getTime(),
		params:      params,
		pending:     make(map[uint64]uint64),
	}
}

func getTime() int64 {
	return int64(mclock.Now())
}

func (peer *ServerNode) recalcBLE(time int64) {
	dt := uint64(time - peer.lastTime)
	if time < peer.lastTime {
		dt = 0
	}
	peer.bufEstimate += peer.params.MinRecharge * dt / fcTimeConst
	if peer.bufEstimate > peer.params.BufLimit {
		peer.bufEstimate = peer.params.BufLimit
	}
	peer.lastTime = time
}

func (peer *ServerNode) canSend(maxCost uint64) uint64 {
	if peer.bufEstimate >= maxCost {
		return 0
	}
	return (maxCost - peer.bufEstimate) * fcTimeConst / peer.params.MinRecharge
}

func (peer *ServerNode) CanSend(maxCost uint64) uint64 {
	peer.lock.RLock()
	defer peer.lock.RUnlock()

	return peer.canSend(maxCost)
}

// blocks until request can be sent
func (peer *ServerNode) SendRequest(reqID, maxCost uint64) {
	peer.lock.Lock()
	defer peer.lock.Unlock()

	peer.recalcBLE(getTime())
	for peer.bufEstimate < maxCost {
		wait := time.Duration(peer.canSend(maxCost))
		peer.lock.Unlock()
		time.Sleep(wait)
		peer.lock.Lock()
		peer.recalcBLE(getTime())
	}
	peer.bufEstimate -= maxCost
	peer.sumCost += maxCost
	if reqID >= 0 {
		peer.pending[reqID] = peer.sumCost
	}
}

func (peer *ServerNode) GotReply(reqID, bv uint64) {
	peer.lock.Lock()
	defer peer.lock.Unlock()

	sc, ok := peer.pending[reqID]
	if !ok {
		return
	}
	delete(peer.pending, reqID)
	peer.bufEstimate = bv - (peer.sumCost - sc)
	peer.lastTime = getTime()
}


text:
"""Main module."""
from typing import Dict, Optional, Tuple, Union

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.distributions import Normal
from torch.distributions import kl_divergence as kl

from scvi._compat import Literal
from scvi.core.distributions import (
    NegativeBinomial,
    NegativeBinomialMixture,
    ZeroInflatedNegativeBinomial,
)

from ._base import DecoderTOTALVI, EncoderTOTALVI
from .utils import one_hot

torch.backends.cudnn.benchmark = True

# VAE model
class TOTALVAE(nn.Module):
    """
    Total variational inference for CITE-seq data.

    Implements the totalVI model of [GayosoSteier20]_.

    Parameters
    ----------
    n_input_genes
        Number of input genes
    n_input_proteins
        Number of input proteins
    n_batch
        Number of batches
    n_labels
        Number of labels
    n_hidden
        Number of nodes per hidden layer for encoder and decoder
    n_latent
        Dimensionality of the latent space
    n_layers
        Number of hidden layers used for encoder and decoder NNs
    dropout_rate
        Dropout rate for neural networks
    gene_dispersion
        One of the following

        * ``'gene'`` - genes_dispersion parameter of NB is constant per gene across cells
        * ``'gene-batch'`` - genes_dispersion can differ between different batches
        * ``'gene-label'`` - genes_dispersion can differ between different labels
    protein_dispersion
        One of the following

        * ``'protein'`` - protein_dispersion parameter is constant per protein across cells
        * ``'protein-batch'`` - protein_dispersion can differ between different batches NOT TESTED
        * ``'protein-label'`` - protein_dispersion can differ between different labels NOT TESTED
    log_variational
        Log(data+1) prior to encoding for numerical stability. Not normalization.
    gene_likelihood
        One of

        * ``'nb'`` - Negative binomial distribution
        * ``'zinb'`` - Zero-inflated negative binomial distribution
    latent_distribution
        One of

        * ``'normal'`` - Isotropic normal
        * ``'ln'`` - Logistic normal with normal params N(0, 1)
    protein_batch_mask
        Dictionary where each key is a batch code, and value is for each protein, whether it was observed or not.
    encode_covariates
        Whether to concatenate covariates to expression in encoder
    protein_background_prior_mean
        Array of proteins by batches, the prior initialization for the protein background mean (log scale)
    protein_background_prior_scale
        Array of proteins by batches, the prior initialization for the protein background scale (log scale)
    use_observed_lib_size
        Use observed library size for RNA as scaling factor in mean of conditional distribution
    """

    def __init__(
        self,
        n_input_genes: int,
        n_input_proteins: int,
        n_batch: int = 0,
        n_labels: int = 0,
        n_hidden: int = 256,
        n_latent: int = 20,
        n_layers_encoder: int = 2,
        n_layers_decoder: int = 1,
        dropout_rate_decoder: float = 0.2,
        dropout_rate_encoder: float = 0.2,
        gene_dispersion: str = "gene",
        protein_dispersion: str = "protein",
        log_variational: bool = True,
        gene_likelihood: str = "nb",
        latent_distribution: str = "normal",
        protein_batch_mask: Dict[Union[str, int], np.ndarray] = None,
        encode_covariates: bool = True,
        protein_background_prior_mean: Optional[np.ndarray] = None,
        protein_background_prior_scale: Optional[np.ndarray] = None,
        use_observed_lib_size: bool = True,
        use_batch_norm: Literal["encoder", "decoder", "none", "both"] = "both",
        use_layer_norm: Literal["encoder", "decoder", "none", "both"] = "none",
    ):
        super().__init__()
        self.gene_dispersion = gene_dispersion
        self.n_latent = n_latent
        self.log_variational = log_variational
        self.gene_likelihood = gene_likelihood
        self.n_batch = n_batch
        self.n_labels = n_labels
        self.n_input_genes = n_input_genes
        self.n_input_proteins = n_input_proteins
        self.protein_dispersion = protein_dispersion
        self.latent_distribution = latent_distribution
        self.protein_batch_mask = protein_batch_mask
        self.use_observed_lib_size = use_observed_lib_size

        # parameters for prior on rate_back (background protein mean)
        if protein_background_prior_mean is None:
            if n_batch > 0:
                self.background_pro_alpha = torch.nn.Parameter(
                    torch.randn(n_input_proteins, n_batch)
                )
                self.background_pro_log_beta = torch.nn.Parameter(
                    torch.clamp(torch.randn(n_input_proteins, n_batch), -10, 1)
                )
            else:
                self.background_pro_alpha = torch.nn.Parameter(
                    torch.randn(n_input_proteins)
                )
                self.background_pro_log_beta = torch.nn.Parameter(
                    torch.clamp(torch.randn(n_input_proteins), -10, 1)
                )
        else:
            if protein_background_prior_mean.shape[1] == 1 and n_batch != 1:
                init_mean = protein_background_prior_mean.ravel()
                init_scale = protein_background_prior_scale.ravel()
            else:
                init_mean = protein_background_prior_mean
                init_scale = protein_background_prior_scale
            self.background_pro_alpha = torch.nn.Parameter(
                torch.from_numpy(init_mean.astype(np.float32))
            )
            self.background_pro_log_beta = torch.nn.Parameter(
                torch.log(torch.from_numpy(init_scale.astype(np.float32)))
            )

        if self.gene_dispersion == "gene":
            self.px_r = torch.nn.Parameter(torch.randn(n_input_genes))
        elif self.gene_dispersion == "gene-batch":
            self.px_r = torch.nn.Parameter(torch.randn(n_input_genes, n_batch))
        elif self.gene_dispersion == "gene-label":
            self.px_r = torch.nn.Parameter(torch.randn(n_input_genes, n_labels))
        else:  # gene-cell
            pass

        if self.protein_dispersion == "protein":
            self.py_r = torch.nn.Parameter(2 * torch.rand(self.n_input_proteins))
        elif self.protein_dispersion == "protein-batch":
            self.py_r = torch.nn.Parameter(
                2 * torch.rand(self.n_input_proteins, n_batch)
            )
        elif self.protein_dispersion == "protein-label":
            self.py_r = torch.nn.Parameter(
                2 * torch.rand(self.n_input_proteins, n_labels)
            )
        else:  # protein-cell
            pass

        use_batch_norm_encoder = use_batch_norm == "encoder" or use_batch_norm == "both"
        use_batch_norm_decoder = use_batch_norm == "decoder" or use_batch_norm == "both"
        use_layer_norm_encoder = use_layer_norm == "encoder" or use_layer_norm == "both"
        use_layer_norm_decoder = use_layer_norm == "decoder" or use_layer_norm == "both"

        # z encoder goes from the n_input-dimensional data to an n_latent-d
        # latent space representation
        self.encoder = EncoderTOTALVI(
            n_input_genes + self.n_input_proteins,
            n_latent,
            n_layers=n_layers_encoder,
            n_cat_list=[n_batch] if encode_covariates else None,
            n_hidden=n_hidden,
            dropout_rate=dropout_rate_encoder,
            distribution=latent_distribution,
            use_batch_norm=use_batch_norm_encoder,
            use_layer_norm=use_layer_norm_encoder,
        )
        self.decoder = DecoderTOTALVI(
            n_latent,
            n_input_genes,
            self.n_input_proteins,
            n_layers=n_layers_decoder,
            n_cat_list=[n_batch],
            n_hidden=n_hidden,
            dropout_rate=dropout_rate_decoder,
            use_batch_norm=use_batch_norm_decoder,
            use_layer_norm=use_layer_norm_decoder,
        )

    def sample_from_posterior_z(
        self,
        x: torch.Tensor,
        y: torch.Tensor,
        batch_index: Optional[torch.Tensor] = None,
        give_mean: bool = False,
        n_samples: int = 5000,
    ) -> torch.Tensor:
        """
        Access the tensor of latent values from the posterior.

        Parameters
        ----------
        x
            tensor of values with shape ``(batch_size, n_input_genes)``
        y
            tensor of values with shape ``(batch_size, n_input_proteins)``
        batch_index
            tensor of batch indices
        give_mean
            Whether to sample, or give mean of distribution
        n_samples
            Number of samples for monte carlo estimation

        Returns
        -------
        type
            tensor of shape ``(batch_size, n_latent)``
        """
        if self.log_variational:
            x = torch.log(1 + x)
            y = torch.log(1 + y)
        qz_m, qz_v, _, _, latent, _ = self.encoder(
            torch.cat((x, y), dim=-1), batch_index
        )
        z = latent["z"]
        if give_mean:
            if self.latent_distribution == "ln":
                samples = Normal(qz_m, qz_v.sqrt()).sample([n_samples])
                z = self.encoder.z_transformation(samples)
                z = z.mean(dim=0)
            else:
                z = qz_m
        return z

    def sample_from_posterior_l(
        self,
        x: torch.Tensor,
        y: torch.Tensor,
        batch_index: Optional[torch.Tensor] = None,
        give_mean: bool = True,
    ) -> torch.Tensor:
        """
        Provides the tensor of library size from the posterior.

        Parameters
        ----------
        x
            tensor of values with shape ``(batch_size, n_input_genes)``
        y
            tensor of values with shape ``(batch_size, n_input_proteins)``
        batch_index
            tensor of values with shape ``(batch_size, 1)``
        give_mean
            return mean of l or sample from it

        Returns
        -------
        type
            tensor of shape ``(batch_size, 1)``
        """
        if self.log_variational:
            x = torch.log(1 + x)
            y = torch.log(1 + y)
        _, _, ql_m, ql_v, latent, _ = self.encoder(
            torch.cat((x, y), dim=-1), batch_index
        )
        library_gene = latent["l"]
        if give_mean is True:
            return torch.exp(ql_m + 0.5 * ql_v)
        else:
            return library_gene

    def get_sample_dispersion(
        self,
        x: torch.Tensor,
        y: torch.Tensor,
        batch_index: Optional[torch.Tensor] = None,
        label: Optional[torch.Tensor] = None,
        n_samples: int = 1,
    ) -> Tuple[torch.Tensor, torch.Tensor]:
        """
        Returns the tensors of dispersions for genes and proteins.

        Parameters
        ----------
        x
            tensor of values with shape ``(batch_size, n_input_genes)``
        y
            tensor of values with shape ``(batch_size, n_input_proteins)``
        batch_index
            array that indicates which batch the cells belong to with shape ``batch_size``
        label
            tensor of cell-types labels with shape ``(batch_size, n_labels)``
        n_samples
            number of samples

        Returns
        -------
        type
            tensors of dispersions of the negative binomial distribution
        """
        outputs = self.inference(
            x, y, batch_index=batch_index, label=label, n_samples=n_samples
        )
        px_r = outputs["px_"]["r"]
        py_r = outputs["py_"]["r"]
        return px_r, py_r

    def get_reconstruction_loss(
        self,
        x: torch.Tensor,
        y: torch.Tensor,
        px_dict: Dict[str, torch.Tensor],
        py_dict: Dict[str, torch.Tensor],
        pro_batch_mask_minibatch: Optional[torch.Tensor] = None,
    ) -> Tuple[torch.Tensor, torch.Tensor]:
        """Compute reconstruction loss."""
        px_ = px_dict
        py_ = py_dict
        # Reconstruction Loss
        if self.gene_likelihood == "zinb":
            reconst_loss_gene = (
                -ZeroInflatedNegativeBinomial(
                    mu=px_["rate"], theta=px_["r"], zi_logits=px_["dropout"]
                )
                .log_prob(x)
                .sum(dim=-1)
            )
        else:
            reconst_loss_gene = (
                -NegativeBinomial(mu=px_["rate"], theta=px_["r"])
                .log_prob(x)
                .sum(dim=-1)
            )

        py_conditional = NegativeBinomialMixture(
            mu1=py_["rate_back"],
            mu2=py_["rate_fore"],
            theta1=py_["r"],
            mixture_logits=py_["mixing"],
        )
        reconst_loss_protein_full = -py_conditional.log_prob(y)
        if pro_batch_mask_minibatch is not None:
            temp_pro_loss_full = torch.zeros_like(reconst_loss_protein_full)
            temp_pro_loss_full.masked_scatter_(
                pro_batch_mask_minibatch.bool(), reconst_loss_protein_full
            )

            reconst_loss_protein = temp_pro_loss_full.sum(dim=-1)
        else:
            reconst_loss_protein = reconst_loss_protein_full.sum(dim=-1)

        return reconst_loss_gene, reconst_loss_protein

    def inference(
        self,
        x: torch.Tensor,
        y: torch.Tensor,
        batch_index: Optional[torch.Tensor] = None,
        label: Optional[torch.Tensor] = None,
        n_samples=1,
        transform_batch: Optional[int] = None,
    ) -> Dict[str, Union[torch.Tensor, Dict[str, torch.Tensor]]]:
        """
        Internal helper function to compute necessary inference quantities.

        We use the dictionary ``px_`` to contain the parameters of the ZINB/NB for genes.
        The rate refers to the mean of the NB, dropout refers to Bernoulli mixing parameters.
        `scale` refers to the quanity upon which differential expression is performed. For genes,
        this can be viewed as the mean of the underlying gamma distribution.

        We use the dictionary ``py_`` to contain the parameters of the Mixture NB distribution for proteins.
        `rate_fore` refers to foreground mean, while `rate_back` refers to background mean. ``scale`` refers to
        foreground mean adjusted for background probability and scaled to reside in simplex.
        ``back_alpha`` and ``back_beta`` are the posterior parameters for ``rate_back``.  ``fore_scale`` is the scaling
        factor that enforces `rate_fore` > `rate_back`.

        ``px_["r"]`` and ``py_["r"]`` are the inverse dispersion parameters for genes and protein, respectively.
        """
        x_ = x
        y_ = y
        if self.use_observed_lib_size:
            library_gene = x.sum(1).unsqueeze(1)
        if self.log_variational:
            x_ = torch.log(1 + x_)
            y_ = torch.log(1 + y_)

        # Sampling - Encoder gets concatenated genes + proteins
        qz_m, qz_v, ql_m, ql_v, latent, untran_latent = self.encoder(
            torch.cat((x_, y_), dim=-1), batch_index
        )
        z = latent["z"]
        untran_z = untran_latent["z"]
        untran_l = untran_latent["l"]
        if not self.use_observed_lib_size:
            library_gene = latent["l"]

        if n_samples > 1:
            qz_m = qz_m.unsqueeze(0).expand((n_samples, qz_m.size(0), qz_m.size(1)))
            qz_v = qz_v.unsqueeze(0).expand((n_samples, qz_v.size(0), qz_v.size(1)))
            untran_z = Normal(qz_m, qz_v.sqrt()).sample()
            z = self.encoder.z_transformation(untran_z)
            ql_m = ql_m.unsqueeze(0).expand((n_samples, ql_m.size(0), ql_m.size(1)))
            ql_v = ql_v.unsqueeze(0).expand((n_samples, ql_v.size(0), ql_v.size(1)))
            untran_l = Normal(ql_m, ql_v.sqrt()).sample()
            if self.use_observed_lib_size:
                library_gene = library_gene.unsqueeze(0).expand(
                    (n_samples, library_gene.size(0), library_gene.size(1))
                )
            else:
                library_gene = self.encoder.l_transformation(untran_l)

        if self.gene_dispersion == "gene-label":
            # px_r gets transposed - last dimension is nb genes
            px_r = F.linear(one_hot(label, self.n_labels), self.px_r)
        elif self.gene_dispersion == "gene-batch":
            px_r = F.linear(one_hot(batch_index, self.n_batch), self.px_r)
        elif self.gene_dispersion == "gene":
            px_r = self.px_r
        px_r = torch.exp(px_r)

        if self.protein_dispersion == "protein-label":
            # py_r gets transposed - last dimension is n_proteins
            py_r = F.linear(one_hot(label, self.n_labels), self.py_r)
        elif self.protein_dispersion == "protein-batch":
            py_r = F.linear(one_hot(batch_index, self.n_batch), self.py_r)
        elif self.protein_dispersion == "protein":
            py_r = self.py_r
        py_r = torch.exp(py_r)

        # Background regularization
        if self.n_batch > 0:
            py_back_alpha_prior = F.linear(
                one_hot(batch_index, self.n_batch), self.background_pro_alpha
            )
            py_back_beta_prior = F.linear(
                one_hot(batch_index, self.n_batch),
                torch.exp(self.background_pro_log_beta),
            )
        else:
            py_back_alpha_prior = self.background_pro_alpha
            py_back_beta_prior = torch.exp(self.background_pro_log_beta)
        self.back_mean_prior = Normal(py_back_alpha_prior, py_back_beta_prior)

        if transform_batch is not None:
            batch_index = torch.ones_like(batch_index) * transform_batch
        px_, py_, log_pro_back_mean = self.decoder(z, library_gene, batch_index, label)
        px_["r"] = px_r
        py_["r"] = py_r

        return dict(
            px_=px_,
            py_=py_,
            qz_m=qz_m,
            qz_v=qz_v,
            z=z,
            untran_z=untran_z,
            ql_m=ql_m,
            ql_v=ql_v,
            library_gene=library_gene,
            untran_l=untran_l,
            log_pro_back_mean=log_pro_back_mean,
        )

    def forward(
        self,
        x: torch.Tensor,
        y: torch.Tensor,
        local_l_mean_gene: torch.Tensor,
        local_l_var_gene: torch.Tensor,
        batch_index: Optional[torch.Tensor] = None,
        label: Optional[torch.Tensor] = None,
    ) -> Tuple[
        torch.FloatTensor, torch.FloatTensor, torch.FloatTensor, torch.FloatTensor
    ]:
        """
        Returns the reconstruction loss and the Kullback divergences.

        Parameters
        ----------
        x
            tensor of values with shape ``(batch_size, n_input_genes)``
        y
            tensor of values with shape ``(batch_size, n_input_proteins)``
        local_l_mean_gene
            tensor of means of the prior distribution of latent variable l
            with shape ``(batch_size, 1)````
        local_l_var_gene
            tensor of variancess of the prior distribution of latent variable l
            with shape ``(batch_size, 1)``
        batch_index
            array that indicates which batch the cells belong to with shape ``batch_size``
        label
            tensor of cell-types labels with shape (batch_size, n_labels)

        Returns
        -------
        type
            the reconstruction loss and the Kullback divergences
        """
        # Parameters for z latent distribution

        outputs = self.inference(x, y, batch_index, label)
        qz_m = outputs["qz_m"]
        qz_v = outputs["qz_v"]
        ql_m = outputs["ql_m"]
        ql_v = outputs["ql_v"]
        px_ = outputs["px_"]
        py_ = outputs["py_"]

        if self.protein_batch_mask is not None:
            pro_batch_mask_minibatch = torch.zeros_like(y)
            for b in torch.unique(batch_index):
                b_indices = (batch_index == b).reshape(-1)
                pro_batch_mask_minibatch[b_indices] = torch.tensor(
                    self.protein_batch_mask[b.item()].astype(np.float32),
                    device=y.device,
                )
        else:
            pro_batch_mask_minibatch = None

        reconst_loss_gene, reconst_loss_protein = self.get_reconstruction_loss(
            x, y, px_, py_, pro_batch_mask_minibatch
        )

        # KL Divergence
        kl_div_z = kl(Normal(qz_m, torch.sqrt(qz_v)), Normal(0, 1)).sum(dim=1)
        if not self.use_observed_lib_size:
            kl_div_l_gene = kl(
                Normal(ql_m, torch.sqrt(ql_v)),
                Normal(local_l_mean_gene, torch.sqrt(local_l_var_gene)),
            ).sum(dim=1)
        else:
            kl_div_l_gene = 0.0

        kl_div_back_pro_full = kl(
            Normal(py_["back_alpha"], py_["back_beta"]), self.back_mean_prior
        )
        if pro_batch_mask_minibatch is not None:
            kl_div_back_pro = (pro_batch_mask_minibatch * kl_div_back_pro_full).sum(
                dim=1
            )
        else:
            kl_div_back_pro = kl_div_back_pro_full.sum(dim=1)

        return (
            reconst_loss_gene,
            reconst_loss_protein,
            kl_div_z,
            kl_div_l_gene,
            kl_div_back_pro,
        )

redpajama_set_name: RedPajamaGithub


text:
{% extends '_dashboard.html' %}
{% load custom_tags %}

{% block dashboard_script %}

{% endblock dashboard_script %}

{% block dashboard %}

                    0

 Total Authorized Expenditure

                    0

 Total Gap

        {% with var=widgets_data|return_item:'Work in Progress' %}

{{ var|return_item:'title' }}

                    Count
                    0

        {% endwith %}

        {% with var=widgets_data|return_item:'PCC to be Issued' %}

{{ var|return_item:'title' }}

                    COUNT
                    0

        {% endwith %}

        {% with var=widgets_data|return_item:'PCC Issued' %}

{{ var|return_item:'title' }}

                    COUNT
                    0

        {% endwith %}

        {% with var=widgets_data|return_item:'Work in Progress' %}

{{ var|return_item:'title' }}

                    Count
                    0

        {% endwith %}

        {% with var=widgets_data|return_item:'PCC to be Issued' %}

{{ var|return_item:'title' }}

                    COUNT
                    0

        {% endwith %}

        {% with var=widgets_data|return_item:'PCC Issued' %}

{{ var|return_item:'title' }}

                    COUNT
                    0

        {% endwith %}

{% endblock dashboard %}


text:
from __future__ import absolute_import, division, print_function, unicode_literals

import pytest ; pytest

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Standard library imports

# External imports

# Bokeh imports
from bokeh.document import Document
from bokeh.io.state import curstate

# Module under test
import bokeh.io.doc as bid

#-----------------------------------------------------------------------------
# Setup
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# General API
#-----------------------------------------------------------------------------

def test_curdoc_from_curstate():
    assert bid.curdoc() is curstate().document

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

def test_set_curdoc_sets_curstate():
    d = Document()
    bid.set_curdoc(d)
    assert curstate().document is d

#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------


text:
import Vue from 'vue'
import VueRouter from 'vue-router'
import moment from 'moment'

import App from './App'
import Sarif from './sarif/service'
import Connect from './components/Connect'
import Overview from './components/Overview'
import Chat from './components/Chat'
import Calendar from './components/Calendar'
import Daily from './components/Daily'
import Cards from './components/Cards'
import Debug from './components/Debug'

import './assets/css/dark.theme.css'

Vue.use(VueRouter)
Vue.config.productionTip = false

Vue.filter('jsonFormat', function (v) {
  return JSON.stringify(v, null, 2)
})

Vue.filter('prettyName', function (v) {
  if (!v) {
    return ''
  }
  return v.replace(/^([a-z])|_([a-z])/g, (g, p1, p2) => {
    if (p1) {
      return p1.toUpperCase()
    }
    return ' ' + p2.toUpperCase()
  })
})

Vue.filter('prettyText', function (v) {
  if (!v) {
    return ''
  }
  var nl = v.indexOf('\n')
  if (nl >= 0) {
    v = v.substring(0, nl) + ' [...]'
  }
  return v
})

Vue.filter('prettyObject', function (v) {
  if (!v) {
    return ''
  }
  if (v.text) {
    if (v.text.length > 30) {
      return '{ "' + v.text.substring(0, 26) + ' ..." }'
    }
    return '{ "' + v.text + '" }'
  }

  var keys = Object.keys(v)
  if (keys.length > 5) {
    return '{ ' + keys.slice(0, 5).join(', ') + ', [...] }'
  }
  return '{ ' + keys.join(', ') + ' }'
})

Vue.filter('date', function (value, format) {
  if (value) {
    return moment(value).format(format || 'l')
  }
})

Vue.filter('time', function (value, format) {
  if (value) {
    return moment(String(value)).format(format || 'llll')
  }
})

var router = new VueRouter({
  routes: [
    { path: '/connect/:host*', component: Connect },
    { path: '/overview', component: Overview },
    { path: '/chat', component: Chat },
    { path: '/calendar', component: Calendar },
    { path: '/daily', component: Daily },
    { path: '/cards', component: Cards },
    { path: '/debug', component: Debug },
    { path: '*', redirect: '/overview' }
  ]
})

router.beforeEach((to, from, next) => {
  if (to.path.startsWith('/connect') || Sarif.isConnected()) {
    next()
  } else {
    next('/connect')
  }
})

var app = new Vue({
  el: '#app-container',
  router,
  render: h => h(App)
})
app.eslint_no_new = true


text:
title: Only One Wing
playwright:
season: Edinburgh
season_sort: 500
period: Edinburgh
venue: The Zoo
venue_sort: ZOO
date_start: 2010-08-06
date_end: 2010-08-21

cast:
 - role: Esther
   name: Lauren Grant

crew:
  - role: Director
    name: Lizzie Bourne
  - role: Original Score
    name: Angus MacRae

assets:
  - type: poster
    image: nvbNwm5

links:
  - type: Review
    href: http://broadwaybaby.com/shows/only-one-wing/21221
    snapshot: UB36S
    publisher: Broadway Baby
    author: Theo Barnes
    title: "Only One Wing"
    date: 2010-08-13
    rating: 4/5
    quote: "You will feel haunted and downhearted, but ultimately that valuable glimmer of hope lets you carry on your day quite fulfilled. "
---


text: module.exports = require("bluebird/js/main/promise")();


text:
(function() {
    "use strict";
    var name = "dumprestore7";

    var step = (function() {
        var n = 0;
        return function(msg) {
            msg = msg || "";
            print('\n' + name + ".js step " + (++n) + ' ' + msg);
        };
    })();

    step("starting the replset test");

    var replTest = new ReplSetTest({name: name, nodes: 1});
    var nodes = replTest.startSet();
    replTest.initiate();

    step("inserting first chunk of data");
    var foo = replTest.getPrimary().getDB("foo");
    for (var i = 0; i < 20; i++) {
        foo.bar.insert({x: i, y: "abc"});
    }

    step("waiting for replication");
    replTest.awaitReplication();
    assert.eq(foo.bar.count(), 20, "should have inserted 20 documents");

    // The time of the last oplog entry.
    var time = replTest.getPrimary()
                   .getDB("local")
                   .getCollection("oplog.rs")
                   .find()
                   .limit(1)
                   .sort({$natural: -1})
                   .next()
                   .ts;
    step("got time of last oplog entry: " + time);

    step("inserting second chunk of data");
    for (var i = 30; i < 50; i++) {
        foo.bar.insert({x: i, y: "abc"});
    }
    assert.eq(foo.bar.count(), 40, "should have inserted 40 total documents");

    step("try mongodump with $timestamp");

    var data = MongoRunner.dataDir + "/dumprestore7-dump1/";
    var query = {ts: {$gt: time}};
    print("mongodump query: " + tojson(query));

    var testQueryCount =
        replTest.getPrimary().getDB("local").getCollection("oplog.rs").find(query).itcount();
    assert.eq(testQueryCount, 20, "the query should match 20 documents");

    var exitCode = MongoRunner.runMongoTool("mongodump", {
        host: "127.0.0.1:" + replTest.ports[0],
        db: "local",
        collection: "oplog.rs",
        query: tojson(query),
        out: data,
    });
    assert.eq(0, exitCode, "monogdump failed to dump the oplog");

    step("try mongorestore from $timestamp");

    var restoreMongod = MongoRunner.runMongod({});
    exitCode = MongoRunner.runMongoTool("mongorestore", {
        host: "127.0.0.1:" + restoreMongod.port,
        dir: data,
        writeConcern: 1,
    });
    assert.eq(0, exitCode, "mongorestore failed to restore the oplog");

    var count = restoreMongod.getDB("local").getCollection("oplog.rs").count();
    if (count != 20) {
        print("mongorestore restored too many documents");
        restoreMongod.getDB("local").getCollection("oplog.rs").find().pretty().shellPrint();
        assert.eq(count, 20, "mongorestore should only have inserted the latter 20 entries");
    }

    step("stopping replset test");
    replTest.stopSet();
})();


text:
namespace SuperHaxagon {
	class Twist;
	class Pattern {
	public:
		Pattern(std::vector<Wall>& walls, int sides);

		const std::vector<Wall>& getWalls() const {return _walls;}
		int getSides() const {return _sides;}

		float getFurthestWallDistance() const;
		float getClosestWallDistance() const;
		void advance(float speed);

	private:
		std::vector<Wall> _walls;
		int _sides;
	};
}

#endif //SUPER_HAXAGON_PATTERN_HPP


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="@drawable/item_main_list_bg"
              android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/icon_iv"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:padding="5dp"
            android:scaleType="fitXY"
            android:src="@drawable/common_full_open_on_phone"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/new_post_number_tv"
            android:layout_toRightOf="@+id/icon_iv"
            android:orientation="vertical">

            <TextView
                android:id="@+id/forum_name_tv"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="left|center_vertical"
                android:paddingBottom="3dp"
                android:paddingTop="5dp"
                android:text="分论坛名"
                android:textColor="@color/main_darkblue"
                android:textSize="18sp"/>

            <TextView
                android:id="@+id/forum_description_tv"
                android:layout_width="fill_parent"
                android:layout_height="match_parent"
                android:layout_below="@+id/forum_name_tv"
                android:layout_weight="1"
                android:gravity="left"
                android:text="描述信息……"
                android:textColor="@color/select_text"
                android:textSize="13sp"/>
        </LinearLayout>

        <TextView
            android:id="@+id/new_post_number_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:padding="10dp"
            android:text="32"
            android:textColor="@color/main_blue"/>
    </RelativeLayout>
</LinearLayout>


text:
package org.jivesoftware.smackx.bytestreams.socks5;

import java.io.DataInputStream;
import java.io.IOException;

import org.jivesoftware.smack.SmackException.SmackMessageException;
import org.jivesoftware.smack.util.SHA1;

import org.jxmpp.jid.Jid;

/**
 * A collection of utility methods for SOcKS5 messages.
 *
 * @author Henning Staib
 */
public class Socks5Utils {

    /**
     * Returns a SHA-1 digest of the given parameters as specified in XEP-0065.
     *
     * @param sessionID for the SOCKS5 Bytestream
     * @param initiatorJID JID of the initiator of a SOCKS5 Bytestream
     * @param targetJID JID of the target of a SOCKS5 Bytestream
     * @return SHA-1 digest of the given parameters
     */
    public static String createDigest(String sessionID, Jid initiatorJID, Jid targetJID) {
        StringBuilder b = new StringBuilder();
        b.append(sessionID).append(initiatorJID).append(targetJID);
        return SHA1.hex(b.toString());
    }

    /**
     * Reads a SOCKS5 message from the given InputStream. The message can either be a SOCKS5 request
     * message or a SOCKS5 response message.
     *

     * (see RFC1928)
     *
     * @param in the DataInputStream to read the message from
     * @return the SOCKS5 message
     * @throws IOException if a network error occurred
     * @throws SmackMessageException if the SOCKS5 message contains an unsupported address type
     */
    public static byte[] receiveSocks5Message(DataInputStream in) throws IOException, SmackMessageException {
        byte[] header = new byte[5];
        in.readFully(header, 0, 5);

        if (header[3] != (byte) 0x03) {
            throw new SmackMessageException("Unsupported SOCKS5 address type: " + header[3] + " (expected: 0x03)");
        }

        int addressLength = header[4];

        byte[] response = new byte[7 + addressLength];
        System.arraycopy(header, 0, response, 0, header.length);

        in.readFully(response, header.length, addressLength + 2);

        return response;
    }

}


text:
const gulp = require('gulp');
const spawn = require('child_process').spawn;
const remoteGitTags = require('remote-git-tags');
const del = require('del');
const path = require('path');
const fs = require('fs');
const findup = require('findup-sync');
const meow = require('meow');
const chokidar = require('chokidar');
const semver = require('semver');
const fsExtra = require('fs-extra');

const exitLifeCycle = require('./utils/exit-lifecycle');

const REFERENCE_DOCS_DIR = 'reference-docs';
const GIT_REPO = 'github.com/GoogleChrome/workbox';
const TMP_PATH = path.join(__dirname, '..', 'tmp-' + Date.now());

const downloadTaggedRelease = (tagName) => {
  console.log(`    Downloading tagged release: ${tagName}`);

  const docPath = path.join(TMP_PATH, tagName);
  return new Promise((resolve, reject) => {
    const params = [
      'clone',
      '--branch', tagName,
      '--depth', '1',
      `http://${GIT_REPO}.git`,
      docPath,
    ];
    const gitDownload = spawn('git', params, {
      stdio: 'inherit',
    });

    gitDownload.on('error', (err) => {
      console.error('Unable to retrieve tags for Git.');
      console.error(err);
    });

    gitDownload.on('close', (code) => {
      if (code === 0) {
        resolve(docPath);
      } else {
        reject(`Error ${code} returned from: git ${params.join(' ')}`);
      }
    });
  });
};

const generateReferenceDocs = (tagName) => {
  return downloadTaggedRelease(tagName);
};

const buildJSDocs = (docPath, version) => {
  console.log(`    Building JSDocs @ '${docPath}'. Version: ${version}`);

  const jsdocConf = path.join(process.cwd(), 'jsdoc.conf');

    try {
      fs.accessSync(jsdocConf, fs.F_OK);
    } catch (err) {
      console.log('Skipping JSDocs due to no jsdoc.conf');
      return;
    }

    const outputPath = path.join(__dirname, '..', 'src',
      REFERENCE_DOCS_DIR, version);
    const jsDocParams = [
      '-c', jsdocConf,
      '--template', path.join(__dirname, '..', 'src', 'themes', '_jsdoc'),
      '-d', outputPath,
    ];

    const jsdocPath = findup(path.join('node_modules', '.bin', 'jsdoc'));

    return new Promise((resolve, reject) => {
      console.log(`        JSDoc path: ${jsdocPath}`);
      console.log(`        JSDoc params: ` +
        `${JSON.stringify(jsDocParams, null, 2)}`);

      const jsdocProcess = spawn(jsdocPath, jsDocParams, {
        cwd: docPath,
        stdio: 'inherit',
      });

      jsdocProcess.on('error', (err) => {
        console.error('Unable to run jsdoc.');
        console.error(err);
      });

      jsdocProcess.on('close', (code) => {
        if (code === 0) {
          resolve(outputPath);
        } else {
          reject(outputPath);
        }
      });
    });
};

gulp.task('ref-docs:watch', () => {
  let fileWatchers = [];

  const cli = meow();
  if (!cli.flags.code) {
    console.warn(`

      If you want to build the latest refernce docs
      please run serve with the "--code" flag, passing
      in the path to the workbox repo.

          gulp serve --code ../workbox/

      `);
    return Promise.resolve();
  }

  global.jekyll = global.jekll || {};
  global.jekyll.debug = true;

  const DEVELOPMENT_TAG = 'v0.0.0';
  const codePath = path.join(process.cwd(), cli.flags.code);
  let outputPath;

  exitLifeCycle.addEventListener('exit', () => {
    if (fileWatchers && fileWatchers.length > 0) {
      fileWatchers.forEach((watcher) => {
        watcher.close();
      });
    }

    // This must be sync, otherwise the exit lifecycle
    // process.exit() will prevent the files from
    // actually deleting.
    del.sync(outputPath);
  });

  return buildJSDocs(codePath, DEVELOPMENT_TAG)
  .catch((jsdocPath) => jsdocPath)
  .then((jsdocPath) => {
    outputPath = jsdocPath;
    const watcher = chokidar.watch([
      path.join(codePath, '**', '*.*'),
      path.join(__dirname, 'src', 'themes', '**', '*.*'),
    ], {
      recursive: true,
    });
    watcher.on('change', () => {
      return buildJSDocs(codePath, DEVELOPMENT_TAG);
    });
    fileWatchers.push(watcher);
  });
});

const refDocsProd = () => {
  let allTags = [];
  let error = null;
  return remoteGitTags(GIT_REPO)
  .then((tags) => {
    const tagObject = {};
    tags.forEach((value, key) => {
      tagObject[key] = value;
      allTags.push(key);
    });

    return Object.keys(tagObject).filter((tag) => {
      const refPath = path.join(__dirname, '..', 'src',
        REFERENCE_DOCS_DIR, tag);
      try {
        fs.accessSync(refPath, fs.F_OK);

        console.log(`    Skipping build reference docs for ${tag}`);
        return false;
      } catch (err) {
        console.log(`    Building reference docs for ${tag}`);
        return true;
      }
    });
  })
  .then((tags) => {
    let promiseChain = Promise.resolve();
    tags.forEach((tag) => {
      promiseChain = promiseChain.then(() => {
        return generateReferenceDocs(tag);
      })
      .then((docPath) => {
        // TODO: Run JSDoc on docPath
        return buildJSDocs(docPath, tag);
      });
    });
    return promiseChain
    .then(() => {
      if(allTags.length === 0) {
        return;
      }

      allTags.sort(semver.rcompare);
      let latestTag = allTags[0];
      let tagPath = path.join(
        __dirname, '..', 'src', 'reference-docs', latestTag
      );
      let latestPath = path.join(
        __dirname, '..', 'src', 'reference-docs', 'latest'
      );
      return del(latestPath)
      .then(() => {
        fsExtra.copySync(tagPath, latestPath);
      });
    });
  })
  .catch((err) => {
    console.error('Problem pulling reference docs and generating them.');
    console.error(err);
    error = err;
  })
  .then(() => {
     return del(TMP_PATH);
  })
  .then(() => {
    if (error) {
      throw error;
    }
  });
};

const refDocsDev = () => {
  const cli = meow();

  global.jekyll = global.jekll || {};
  global.jekyll.debug = true;

  const DEVELOPMENT_TAG = 'v0.0.0';
  const codePath = path.join(process.cwd(), cli.flags.code);

  return buildJSDocs(codePath, DEVELOPMENT_TAG);
};

gulp.task('ref-docs', () => {
  if (process.env.TRAVIS) {
    console.warn('Unable to build docs on Travis so skipping.');
    return Promise.resolve();
  }
  const cli = meow();
  if (!cli.flags.code) {
    console.warn(`

      If you want to build the latest refernce docs
      please run serve with the "--code" flag, passing
      in the path to the workbox repo.

          gulp serve --code ../workbox/

      `);
    return refDocsProd();
  }

  return refDocsDev();
});


text:
//
//  UAIAMListUserPoliciesResponse.h
//  AWS iOS SDK
//
//  Copyright © Unsigned Apps 2014. See License file.
//  Created by Rob Amos.
//
//

#import "UAIAMResponse.h"

@interface UAIAMListUserPoliciesResponse : UAIAMResponse

@property (nonatomic, copy) NSArray *policyNames;
@property (nonatomic) BOOL isTruncated;
@property (nonatomic, copy) NSString *marker;

/**
 * Retrieves the NSString at the specified index.
**/
- (NSString *)policyNameAtIndex:(NSUInteger)index;

/**
 * Adds a PolicyName to the policyNames property.
 *
 * This will initialise policyNames with an empty mutable array if necessary.
**/
- (void)addPolicyName:(NSString *)policyName;

@end


text:
Ionic side menu sample written in lexah.

You'll need [lexah](github.com/peekmo/lexah) in order to transpile the project.
Also need [ionic.haxe](https://github.com/JJayet/ionic.haxe) and [angular.haxe](https://github.com/frabbit/angular.haxe)

After, just run ```haxe build.hxml``` to build the ```index.js```


text:
from survey.models import BaseModel
from django.db import models

class QuestionModule(BaseModel):
    name = models.CharField(max_length=255)
    description = models.TextField(null=True, blank=True)

    def remove_related_questions(self):
        self.question_templates.all().delete()

    def __unicode__(self):
        return self.name


text:
The **Bulma website** has moved to the `/docs` folder of the `jgthms/bulma` repo:
https://github.com/jgthms/bulma


text:
"""
Created on Mon Apr 20 15:01:13 2015

@author: pick
"""

import odml
from odmltables.odml_csv_table import OdmlCsvTable, OdmlTable
from .create_test_odmls import (create_showall_test_odml, create_2samerows_test_odml)
import os
import csv

import unittest

class TestOdmlCsvTable(unittest.TestCase):
    """
    """

    def setUp(self):
        self.test_csv_table = OdmlCsvTable()
        self.filename = 'test.csv'

    def tearDown(self):
        if os.path.exists(self.filename):
            os.remove(self.filename)

    def test_empty_rows(self):
        """
        test if a row that would be empty will appear in the table
        """

        expected = [['Document Information', 'author', '', 'date', None, 'repository', '',
                     'version', ''],
                    ['Path to Section', 'Section Name', 'Property Name', '', '', '', '', '', ''],
                    ['/section1', 'section1', 'property1', '', '', '', '', '', ''],
                    ['/section2', 'section2', 'property1', '', '', '', '', '', '']]

        self.test_csv_table.load_from_function(create_2samerows_test_odml)

        self.test_csv_table.change_header(Path=1, SectionName=2, PropertyName=3, )

        self.test_csv_table.show_all_sections = False
        self.test_csv_table.show_all_properties = False

        self.test_csv_table.write2file(self.filename)

        with open(self.filename, 'r') as csvfile:
            csvreader = csv.reader(csvfile)
            row_num = 0
            for row in csvreader:
                if None in expected[row_num]:
                    for id in range(len(expected[row_num])):
                        if expected[row_num][id] is not None:
                            self.assertEqual(row[id], expected[row_num][id])
                else:
                    self.assertEqual(row, expected[row_num])
                row_num += 1

    def test_saveload_empty_value(self):
        doc = odml.Document()
        doc.append(odml.Section('sec'))
        doc[0].append(odml.Property('prop', values=[]))

        table = OdmlCsvTable()
        table.load_from_odmldoc(doc)
        table.change_header('full')
        table.write2file(self.filename)

        table2 = OdmlTable()
        table2.load_from_csv_table(self.filename)

        # comparing values which are written to xls by default
        self.assertEqual(len(table._odmldict), len(table2._odmldict))
        self.assertEqual(len(table._odmldict), 1)
        self.assertDictEqual(table._odmldict[0], table2._odmldict[0])

class TestShowallOdmlCsvTable(unittest.TestCase):
    """
    test possible combinations of the attributes showall_sections,
    showall_properties and showall_valueinformation to see wether the same
    values are not printed again, unless it is the start of a new section or
    property
    """

    def setUp(self):
        self.test_csv_table = OdmlCsvTable()
        self.test_csv_table.load_from_function(create_showall_test_odml)
        self.test_csv_table.change_header(Path=1,
                                          SectionName=2,
                                          SectionDefinition=3,
                                          PropertyName=4,
                                          PropertyDefinition=5,
                                          Value=6,
                                          DataUnit=7,
                                          DataUncertainty=8,
                                          odmlDatatype=9)
        self.filename = 'testfile.csv'

    def tearDown(self):
        os.remove(self.filename)

    def test_tt(self):
        """
        showall_sections=True
        showall_properties=True
        """

        expected = [
            ['Document Information', 'author', '', 'date', None, 'repository', '', 'version', ''],
            ['Path to Section', 'Section Name', 'Section Definition', 'Property Name',
             'Property Definition', 'Value', 'Data Unit', 'Data Uncertainty', 'odML Data Type'],
            ['/section1', 'section1', 'sec1', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['/section1', 'section1', 'sec1', 'property1', 'prop1', 'value2', 'g', '1', 'string'],
            ['/section1', 'section1', 'sec1', 'property1', 'prop1', 'value3', 'g', '1', 'string'],
            ['/section1', 'section1', 'sec1', 'property2', 'prop2', 'value1', 'g', '1', 'text'],
            ['/section1', 'section1', 'sec1', 'property3', 'prop3', 'value1', 'g', '1', 'text'],
            ['/section2', 'section2', 'sec2', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['/section3', 'section3', 'sec3', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['/section3', 'section3', 'sec3', 'property1', 'prop1', 'value2', 'g', '1', 'string']]

        self.test_csv_table.show_all_sections = True
        self.test_csv_table.show_all_properties = True

        self.test_csv_table.write2file(self.filename)

        with open(self.filename, 'r') as csvfile:
            csvreader = csv.reader(csvfile)
            row_num = 0
            for row in csvreader:
                if None in expected[row_num]:
                    for id in range(len(expected[row_num])):
                        if expected[row_num][id] is not None:
                            self.assertEqual(row[id], expected[row_num][id])
                else:
                    self.assertEqual(row, expected[row_num])
                row_num += 1

    def test_ff(self):
        """
        showall_sections=False
        showall_properties=False
        """
        expected = [
            ['Document Information', 'author', '', 'date', None, 'repository', '', 'version', ''],
            ['Path to Section', 'Section Name', 'Section Definition', 'Property Name',
             'Property Definition', 'Value', 'Data Unit', 'Data Uncertainty', 'odML Data Type'],
            ['/section1', 'section1', 'sec1', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['', '', '', '', '', 'value2', '', '', ''],
            ['', '', '', '', '', 'value3', '', '', ''],
            ['', '', '', 'property2', 'prop2', 'value1', 'g', '1', 'text'],
            ['', '', '', 'property3', 'prop3', 'value1', 'g', '1', 'text'],
            ['/section2', 'section2', 'sec2', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['/section3', 'section3', 'sec3', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['', '', '', '', '', 'value2', '', '', '']]

        self.test_csv_table.show_all_sections = False
        self.test_csv_table.show_all_properties = False

        self.test_csv_table.write2file(self.filename)

        with open(self.filename, 'r') as csvfile:
            csvreader = csv.reader(csvfile)
            row_num = 0
            for row in csvreader:
                if None in expected[row_num]:
                    for id in range(len(expected[row_num])):
                        if expected[row_num][id] is not None:
                            self.assertEqual(row[id], expected[row_num][id])
                else:
                    self.assertEqual(row, expected[row_num])
                row_num += 1

    def test_ft(self):
        """
        showall_sections=False
        showall_properties=True
        """
        expected = [
            ['Document Information', 'author', '', 'date', None, 'repository', '', 'version', ''],
            ['Path to Section', 'Section Name', 'Section Definition', 'Property Name',
             'Property Definition', 'Value', 'Data Unit', 'Data Uncertainty', 'odML Data Type'],
            ['/section1', 'section1', 'sec1', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['', '', '', 'property1', 'prop1', 'value2', 'g', '1', 'string'],
            ['', '', '', 'property1', 'prop1', 'value3', 'g', '1', 'string'],
            ['', '', '', 'property2', 'prop2', 'value1', 'g', '1', 'text'],
            ['', '', '', 'property3', 'prop3', 'value1', 'g', '1', 'text'],
            ['/section2', 'section2', 'sec2', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['/section3', 'section3', 'sec3', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['', '', '', 'property1', 'prop1', 'value2', 'g', '1', 'string']]

        self.test_csv_table.show_all_sections = False
        self.test_csv_table.show_all_properties = True

        self.test_csv_table.write2file(self.filename)

        with open(self.filename, 'r') as csvfile:
            csvreader = csv.reader(csvfile)
            row_num = 0
            for row in csvreader:
                if None in expected[row_num]:
                    for id in range(len(expected[row_num])):
                        if expected[row_num][id] is not None:
                            self.assertEqual(row[id], expected[row_num][id])
                else:
                    self.assertEqual(row, expected[row_num])
                row_num += 1

    def test_tf(self):
        """
        showall_sections=True
        showall_properties=False
        """
        expected = [
            ['Document Information', 'author', '', 'date', None, 'repository', '', 'version', ''],
            ['Path to Section', 'Section Name', 'Section Definition', 'Property Name',
             'Property Definition', 'Value', 'Data Unit', 'Data Uncertainty', 'odML Data Type'],
            ['/section1', 'section1', 'sec1', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['/section1', 'section1', 'sec1', '', '', 'value2', '', '', ''],
            ['/section1', 'section1', 'sec1', '', '', 'value3', '', '', ''],
            ['/section1', 'section1', 'sec1', 'property2', 'prop2', 'value1', 'g', '1', 'text'],
            ['/section1', 'section1', 'sec1', 'property3', 'prop3', 'value1', 'g', '1', 'text'],
            ['/section2', 'section2', 'sec2', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['/section3', 'section3', 'sec3', 'property1', 'prop1', 'value1', 'g', '1', 'string'],
            ['/section3', 'section3', 'sec3', '', '', 'value2', '', '', '']]

        self.test_csv_table.show_all_sections = True
        self.test_csv_table.show_all_properties = False

        self.test_csv_table.write2file(self.filename)

        with open(self.filename, 'r') as csvfile:
            csvreader = csv.reader(csvfile)
            row_num = 0
            for row in csvreader:
                if None in expected[row_num]:
                    for id in range(len(expected[row_num])):
                        if expected[row_num][id] is not None:
                            self.assertEqual(row[id], expected[row_num][id])
                else:
                    self.assertEqual(row, expected[row_num])
                row_num += 1

if __name__ == '__main__':
    unittest.main()


text:
>In this exercise, we will use advanced features with Descartes to solve a complex path for part being held by the robot which gets processed by a stationary tool.

## Motivation
MoveIt! is a framework meant primarily for performing "free-space" motion where the objective is to move a robot from point A to point B and you don't particularly care about how that gets done. These types of problems are only a subset of frequently performed tasks. Imagine any manufacturing ''process'' like welding or painting. You very much care about where that tool is pointing the entire time the robot is at work.

This tutorial introduces you to Descartes, a ''Cartesian'' motion planner meant for moving a robot along some process path. It's only one of a number of ways to solve this kind of problem, but it's got some neat properties:
 * It's deterministic and globally optimum (to a certain search resolution).
 * It can search redundant degrees of freedom in your problem (say you have 7 robot joints or you have a process where the tool's Z-axis rotation doesn't matter).

## Reference Example
[Descartes Tutorial](http://wiki.ros.org/descartes/Tutorials/Getting%20Started%20with%20Descartes)

## Further Information and Resources
[Descartes Wiki](http://wiki.ros.org/descartes)

APIs:
 * [descartes_core::PathPlannerBase](http://docs.ros.org/indigo/api/descartes_core/html/classdescartes__core_1_1PathPlannerBase.html)
 * [descartes_planner::DensePlanner](http://docs.ros.org/indigo/api/descartes_planner/html/classdescartes__planner_1_1DensePlanner.html)
 * [descartes_planner::SparsePlanner](http://docs.ros.org/indigo/api/descartes_planner/html/classdescartes__planner_1_1SparsePlanner.html)

## Scan-N-Plan Application: Problem Statement
In this exercise, you will add two new nodes, two xacro, and config file to your Scan-N-Plan application, that:
 1. Takes the config file `puzzle_bent.csv` and creates a descartes trajectory where the part is held by the robot and manipulated around a stationary tool.
 1. Produces a joint trajectory that commands the robot to trace the perimeter of the marker (as if it is dispensing adhesive).

## Scan-N-Plan Application: Guidance
In the interest of time, we've included several files:
 1. The first is a template node `adv_descartes_node.cpp` where most of the exercise is spent creating the complicated trajectory for deburring a complicated part.
 1. The second node, `adv_myworkcell_node.cpp`, is a duplicate of the `myworkcell_node.cpp` that has been updated to call the `adv_plan_path` service provided by `adv_descartes_node.cpp`.
 1. The config file `puzzle_bent.csv` which contains the path relative to the part coordinate system.
 1. The two xacro files `puzzle_mount.xacro` and `grinder.xacro` which are used to update the urdf/xacro `workcell.xacro` file.

Left to you are the details of:
 1. Updating the workcell.xacro file to include the two new xacro files.
 1. Updating the moveit_config package to define a new Planning Group for this exercise, including the new end-effector links.
 1. Defining a series of Cartesian poses that comprise a robot "path".
 1. Translating those paths into something Descartes can understand.

### Setup workspace
 1. This exercise uses the same workspace from the Basic Training course.  If you don't have this workspace (completed through Exercise 4.1), copy the completed reference code and pull in other required dependencies as shown below. Otherwise move to the next step.

    ```bash
    mkdir ~/catkin_ws
    cd ~/catkin_ws
    cp -r ~/industrial_training/exercises/4.1/src .
    cd src
    git clone https://github.com/jmeyer1292/fake_ar_publisher.git
    git clone -b kinetic-devel https://github.com/ros-industrial-consortium/descartes.git
    sudo apt install ros-kinetic-ur-kinematics
    sudo apt install ros-kinetic-ur-description
    ```

 1. Copy over the `adv_descartes_node_unfinished.cpp` into your core package's src/ folder and rename it `adv_descartes_node.cpp`.

    ```bash
    cp ~/industrial_training/exercises/5.0/src/adv_descartes_node_unfinished.cpp myworkcell_core/src/adv_descartes_node.cpp
    ```

 1. Create rules in the `myworkcell_core` package's `CMakeLists.txt` to build a new node called `adv_descartes_node`.  As in previous exercises, add these lines near similar lines in the template file (not as a block as shown below).

    ```cmake
    add_executable(adv_descartes_node src/adv_descartes_node.cpp)
    add_dependencies(adv_descartes_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(adv_descartes_node ${catkin_LIBRARIES})
    ```

 1. Copy over the `adv_myworkcell_node.cpp` into your core package's src/ folder.

    ```bash
    cp ~/industrial_training/exercises/5.0/src/myworkcell_core/src/adv_myworkcell_node.cpp myworkcell_core/src/
    ```

 1. Create rules in the `myworkcell_core` package's `CMakeLists.txt` to build a new node called `adv_myworkcell_node`.  As in previous exercises, add these lines near similar lines in the template file (not as a block as shown below).

    ```cmake
    add_executable(adv_myworkcell_node src/adv_myworkcell_node.cpp)
    add_dependencies(adv_myworkcell_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    target_link_libraries(adv_myworkcell_node ${catkin_LIBRARIES})
    ```

 1. Copy over the necessesary config file:
    ``` bash
    mkdir ~/catkin_ws/src/myworkcell_core/config
    cp ~/industrial_training/exercises/5.0/src/myworkcell_core/config/puzzle_bent.csv myworkcell_core/config/
    cp ~/industrial_training/exercises/5.0/src/myworkcell_support/urdf/grinder.xacro myworkcell_support/urdf/
    cp ~/industrial_training/exercises/5.0/src/myworkcell_support/urdf/puzzle_mount.xacro myworkcell_support/urdf/
    mkdir ~/catkin_ws/src/myworkcell_support/meshes
    cp ~/industrial_training/exercises/5.0/src/myworkcell_support/meshes/* myworkcell_support/meshes/
    ```

 1. Add new package dependencies:
    * Add `tf_conversions` to `CMakeLists.txt` (2 places) and `package.xml` (1 place)

### Update your workcell.xacro file.
 1. Add two `<include>` tags for the new `grinder.xacro` and `puzzle_mount.xacro` files.
 1. Attach the grinder to the **world** link with the following offset:
    ``` xml
    <origin xyz="0.0 -0.4 0.6" rpy="0 3.14159 0"/>
    ```
    * Look in the `grinder.xacro` file to locate the appropriate `<child_link>` name.
    * Copy one of the other `<joint>` tag definitions and modify as appropriate.
 1. Attach the puzzle mount to the robot's **tool0** frame with the following offset:
    ``` xml
    <origin xyz="0 0 0" rpy="1.5708 0 0"/>
    ```
    * Look in the `puzzle_mount.xacro` file to locate the appropriate `<child_link>` name.  You may need to study its various `<link>` and `<joint>` definitions to find the root link of this part.
    * The `tool0` frame is standardized across most ROS-I URDFs to be the robot's end-effector mounting flange.

 1. Launch the demo.launch file within your moveit_config package to verify the workcell. There should be a grinder sticking out of the table and a puzzle-shaped part attached to the robot.
    ``` bash
    roslaunch myworkcell_moveit_config demo.launch
    ```

### Add new planning group to your moveit_config package.
 1. Re-run the MoveIt! Setup Assistant and create a new Planning Group named **puzzle**.  Define the kinematic chain to extend from the **base_link** to the new **part** link.
    ``` bash
    roslaunch myworkcell_moveit_config setup_assistant.launch
    ```
    * _Note: Since you added geometry, you should also regenerate the allowed collision matrix._

### Complete Advanced Descartes Node
 1. First, the function `makePuzzleToolPoses()` needs to be completed. The file path for **puzzle_bent.csv** is needed. For portability, don't hardcode the full path. Please use the ROS tool `ros::package::getPath()` to retrieve the root path of the relevant package.
    * reference [getPath()](http://docs.ros.org/kinetic/api/roslib/html/c++/namespaceros_1_1package.html#ae9470dd201aa4e66abb833e710d812a4) API
 1. Next, the function `makeDescartesTrajectory()` needs to be completed. The transform between **world** and **grinder_frame** needs to be found. Also Each point needs to have the orientation tolerance set for the z-axis to +/- PI;
    * reference [lookupTransform()](http://docs.ros.org/kinetic/api/tf/html/c++/classtf_1_1Transformer.html#ac01a9f8709a828c427f1a5faa0ced42b) API
    * reference [tf::conversions](http://docs.ros.org/kinetic/api/tf_conversions/html/c++/tf__eigen_8h.html) namespace
    * reference [TolerancedFrame](https://github.com/ros-industrial-consortium/descartes/blob/kinetic-devel/descartes_trajectory/include/descartes_trajectory/cart_trajectory_pt.h#L156) definition
    * reference [OrientationTolerance](https://github.com/ros-industrial-consortium/descartes/blob/kinetic-devel/descartes_trajectory/include/descartes_trajectory/cart_trajectory_pt.h#L139) definition

### Update the setup.launch file.
 1. Update the file to take a boolean argument named **adv** so that either the basic or advanced descartes node can be launched.  Use `<if>` and `<unless>` modifiers to control which node is launched.
    * reference [roslaunch XML](http://wiki.ros.org/roslaunch/XML) wiki

### Test Full Application

 1. Run the new setup file, then your main advanced workcell node:

    ``` bash
    roslaunch myworkcell_support setup.launch adv:=true
    rosrun myworkcell_core adv_myworkcell_node
    ```

    * Descartes can take **several minutes** to plan this complex path, so be patient.
    * It's difficult to see what's happening with the rviz planning-loop animation always running.  Disable this loop animation in rviz (Displays -> Planned Path -> Loop Animation) before running `adv_myworkcell_node`.


text: Module in JavaScript for downloading courses.


text:
package tw.com.unit;

import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
import org.easymock.EasyMockSupport;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.services.cloudformation.model.CloudFormationException;
import software.amazon.awssdk.services.cloudformation.model.StackEvent;
import software.amazon.awssdk.services.cloudformation.model.StackStatus;
import tw.com.PollingStackMonitor;
import tw.com.SetsDeltaIndex;
import tw.com.StackMonitor;
import tw.com.entity.DeletionsPending;
import tw.com.entity.StackNameAndId;
import tw.com.exceptions.WrongNumberOfStacksException;
import tw.com.exceptions.WrongStackStatus;
import tw.com.repository.CloudFormRepository;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

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

@RunWith(EasyMockRunner.class)
public class TestPollingStackMonitor extends EasyMockSupport implements SetsDeltaIndex {

	private CloudFormRepository cfnRepository;
	private PollingStackMonitor monitor;
	private String stackName;
	private StackNameAndId stackId;
	private int lastDeltaIndex;

	@Before
	public void beforeEachTestRuns() {
		cfnRepository = createMock(CloudFormRepository.class);
		monitor = new PollingStackMonitor(cfnRepository);

		stackName = "stackName";
		stackId = new StackNameAndId(stackName, "stackId");
	}

	@Test
	public void shouldWaitForCreationToComplete() throws WrongNumberOfStacksException, WrongStackStatus, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.CREATE_ABORTS);
		StackStatus initialStatus = StackStatus.CREATE_IN_PROGRESS;
		StackStatus targetStatus = StackStatus.CREATE_COMPLETE;

		setRepoExcpetationsForSuccess(aborts, initialStatus, targetStatus);

		replayAll();
		StackStatus status = monitor.waitForCreateFinished(stackId);
		assertEquals(targetStatus, status);
		verifyAll();
	}

	@Test
	public void shouldWaitForDeleteToComplete() throws WrongNumberOfStacksException, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.DELETE_ABORTS);
		StackStatus initialStatus = StackStatus.DELETE_IN_PROGRESS;
		StackStatus targetStatus = StackStatus.DELETE_COMPLETE;

		setRepoExcpetationsForSuccess(aborts, initialStatus, targetStatus);

		replayAll();
		StackStatus status = monitor.waitForDeleteFinished(stackId);
		assertEquals(targetStatus, status);
		verifyAll();
	}

	@Test
	public void shouldWaitForUpdateToComplete() throws WrongNumberOfStacksException, WrongStackStatus, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.UPDATE_ABORTS);
		StackStatus initialStatus = StackStatus.UPDATE_IN_PROGRESS;
		StackStatus targetStatus = StackStatus.UPDATE_COMPLETE;

		setRepoExcpetationsForSuccess(aborts, initialStatus, targetStatus);

		replayAll();
		StackStatus status = monitor.waitForUpdateFinished(stackId);
		assertEquals(targetStatus, status);
		verifyAll();
	}

	@Test
	public void shouldWaitForUpdateToCompleteWithCleanUp() throws WrongNumberOfStacksException, WrongStackStatus, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.UPDATE_ABORTS);
		StackStatus initialStatus = StackStatus.UPDATE_IN_PROGRESS;
		StackStatus targetStatus = StackStatus.UPDATE_COMPLETE;

		setRepoExcpetationsForSuccess(aborts, initialStatus, StackStatus.UPDATE_COMPLETE_CLEANUP_IN_PROGRESS);
		setRepoExcpetationsForSuccess(aborts, StackStatus.UPDATE_COMPLETE_CLEANUP_IN_PROGRESS, targetStatus);

		replayAll();
		StackStatus status = monitor.waitForUpdateFinished(stackId);
		assertEquals(targetStatus, status);
		verifyAll();
	}

	@Test
	public void shouldWaitForRollbackToComplete() throws WrongNumberOfStacksException, WrongStackStatus, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.ROLLBACK_ABORTS);
		StackStatus initialStatus = StackStatus.ROLLBACK_IN_PROGRESS;
		StackStatus targetStatus = StackStatus.ROLLBACK_COMPLETE;

		setRepoExcpetationsForSuccess(aborts, initialStatus, targetStatus);

		replayAll();
		StackStatus status = monitor.waitForRollbackComplete(stackId);
		assertEquals(targetStatus, status);
		verifyAll();
	}

	@Test
	public void shouldThrowForCreationFailure() throws WrongNumberOfStacksException, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.CREATE_ABORTS);
		setRepoExcpetationsForFailure(aborts, StackStatus.CREATE_IN_PROGRESS, StackStatus.CREATE_FAILED);

		replayAll();
		try {
			monitor.waitForCreateFinished(stackId);
			fail("exception expected");
		}
		catch(WrongStackStatus expectedException) {
			// noop
		}
		verifyAll();
	}

	@Test
	public void shouldThrowForCreationFailureDueToRollback() throws WrongNumberOfStacksException, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.CREATE_ABORTS);
		setRepoExcpetationsForFailure(aborts, StackStatus.CREATE_IN_PROGRESS, StackStatus.ROLLBACK_IN_PROGRESS);

		replayAll();
		try {
			monitor.waitForCreateFinished(stackId);
			fail("exception expected");
		}
		catch(WrongStackStatus expectedException) {
			// noop
		}
		verifyAll();
	}

	@Test
	public void shouldThrowForUpdateFailure() throws WrongNumberOfStacksException, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.UPDATE_ABORTS);
		setRepoExcpetationsForFailure(aborts, StackStatus.UPDATE_IN_PROGRESS, StackStatus.UPDATE_ROLLBACK_COMPLETE);

		replayAll();
		try {
			monitor.waitForUpdateFinished(stackId);
			fail("exception expected");
		}
		catch(WrongStackStatus expectedException) {
			// noop
		}
		verifyAll();
	}

	@Test
	public void shouldThrowForRollbackFailure() throws WrongNumberOfStacksException, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.ROLLBACK_ABORTS);
		setRepoExcpetationsForFailure(aborts, StackStatus.ROLLBACK_IN_PROGRESS, StackStatus.ROLLBACK_FAILED);

		replayAll();
		try {
			monitor.waitForRollbackComplete(stackId);
			fail("exception expected");
		}
		catch(WrongStackStatus expectedException) {
			// noop
		}
		verifyAll();
	}

	@Test
	public void shouldReturnStatusDeletionFailure() throws WrongNumberOfStacksException, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.DELETE_ABORTS);
		setRepoExcpetationsForFailure(aborts, StackStatus.DELETE_IN_PROGRESS, StackStatus.DELETE_FAILED);

		replayAll();
		StackStatus result = monitor.waitForDeleteFinished(stackId);
		assertEquals(StackStatus.DELETE_FAILED, result);
		verifyAll();
	}

	@Test
	public void shouldMonitorMultiplePendingDeletes() throws WrongNumberOfStacksException, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.DELETE_ABORTS);
		StackStatus targetStatus = StackStatus.DELETE_COMPLETE;

		DeletionsPending pending = new DeletionsPending();
		pending.add(3, new StackNameAndId("stackC", "id3"));
		pending.add(2, new StackNameAndId("stackB", "id2"));
		pending.add(1, new StackNameAndId("stackA", "id1"));

		EasyMock.expect(cfnRepository.waitForStatusToChangeFrom("stackC", StackStatus.DELETE_IN_PROGRESS, aborts))
			.andReturn(targetStatus);
		EasyMock.expect(cfnRepository.waitForStatusToChangeFrom("stackB", StackStatus.DELETE_IN_PROGRESS, aborts))
		.andReturn(targetStatus);
		EasyMock.expect(cfnRepository.waitForStatusToChangeFrom("stackA", StackStatus.DELETE_IN_PROGRESS, aborts))
		.andReturn(targetStatus);

		replayAll();
		monitor.waitForDeleteFinished(pending, this);
		assertEquals(0, lastDeltaIndex);
		verifyAll();
	}

	@Test
	public void shouldMonitorMultiplePendingDeletesAndLeaveIndexCorrectOnFailure() throws WrongNumberOfStacksException, InterruptedException {
		List<StackStatus> aborts =  Arrays.asList(StackMonitor.DELETE_ABORTS);
		StackStatus targetStatus = StackStatus.DELETE_COMPLETE;

		DeletionsPending pending = new DeletionsPending();
		pending.add(3, new StackNameAndId("stackC", "id3"));
		pending.add(2, new StackNameAndId("stackB", "id2"));
		pending.add(1, new StackNameAndId("stackA", "id1"));

		EasyMock.expect(cfnRepository.waitForStatusToChangeFrom("stackC", StackStatus.DELETE_IN_PROGRESS, aborts))
			.andReturn(targetStatus);
		EasyMock.expect(cfnRepository.waitForStatusToChangeFrom("stackB", StackStatus.DELETE_IN_PROGRESS, aborts))
			.andReturn(StackStatus.DELETE_FAILED);
		List<StackEvent> events = new LinkedList<>();
		EasyMock.expect(cfnRepository.getStackEvents("stackB")).andReturn(events);

		replayAll();
		monitor.waitForDeleteFinished(pending, this);
		assertEquals(2, lastDeltaIndex);
		verifyAll();
	}

	private void setRepoExcpetationsForSuccess(List<StackStatus> aborts,
			StackStatus initialStatus, StackStatus targetStatus)
			throws WrongNumberOfStacksException, InterruptedException {
		EasyMock.expect(cfnRepository.waitForStatusToChangeFrom(stackName, initialStatus, aborts))
			.andReturn(targetStatus);
	}

	private void setRepoExcpetationsForFailure(List<StackStatus> aborts,
			StackStatus initialStatus, StackStatus failureStatus) throws WrongNumberOfStacksException, InterruptedException {
		EasyMock.expect(cfnRepository.waitForStatusToChangeFrom(stackName, initialStatus, aborts)).
				andReturn(failureStatus);
		List<StackEvent> events = new LinkedList<>();
		EasyMock.expect(cfnRepository.getStackEvents(stackName)).andReturn(events);
	}

	@Override
	public void setDeltaIndex(Integer newDelta) {
		this.lastDeltaIndex = newDelta;

	}

}


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Deutsche Schwämme 8: 3, no. 184 (1818)

#### Original name
Chaetomium elatum Kunze, 1818

### Remarks
null