text:
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "esp_slave.h"
#include "esp_log.h"
#include "freertos/task.h"
#include "soc/host_reg.h"

static const char TAG[] = "esp_slave";

#define ESP_SLAVE_CMD53_END_ADDR    0x1f800

#define TX_BUFFER_MAX   0x1000
#define TX_BUFFER_MASK  0xFFF
#define RX_BYTE_MAX     0x100000
#define RX_BYTE_MASK    0xFFFFF

#define FUNC1_EN_MASK   (BIT(1))

esp_err_t esp_slave_init_io(esp_slave_context_t *context)
{
    esp_err_t err;
    uint8_t ioe;
    sdmmc_card_t* card = context->card;

    err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_ENABLE, &ioe);
    if (err != ESP_OK) return err;
    ESP_LOGD(TAG, "IOE: 0x%02x", ioe);

    uint8_t ior = 0;
    err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
    if (err != ESP_OK) return err;
    ESP_LOGD(TAG, "IOR: 0x%02x", ior);

    // enable function 1
    ioe |= FUNC1_EN_MASK;
    err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_FN_ENABLE, ioe, &ioe);
    if (err != ESP_OK) return err;
    ESP_LOGD(TAG, "IOE: 0x%02x", ioe);

    // wait for the card to become ready
    while ((ior & FUNC1_EN_MASK) == 0) {
        err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
        if (err != ESP_OK) return err;
        ESP_LOGD(TAG, "IOR: 0x%02x", ior);
    }

    // get interrupt status
    uint8_t ie;
    err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_INT_ENABLE, &ie);
    if (err != ESP_OK) return err;
    ESP_LOGD(TAG,"IE: 0x%02x", ie);

    // enable interrupts for function 1&2 and master enable
    ie |= BIT(0) | FUNC1_EN_MASK;
    err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_INT_ENABLE, ie, &ie);
    if (err != ESP_OK) return err;
    ESP_LOGD(TAG, "IE: 0x%02x", ie);

    // get bus width register
    uint8_t bus_width;
    err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BUS_WIDTH, &bus_width);
    if (err != ESP_OK) return err;
    ESP_LOGD(TAG,"BUS_WIDTH: 0x%02x", bus_width);

    // enable continuous SPI interrupts
    bus_width |= CCCR_BUS_WIDTH_ECSI;
    err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BUS_WIDTH, bus_width, &bus_width);
    if (err != ESP_OK) return err;
    ESP_LOGD(TAG, "BUS_WIDTH: 0x%02x", bus_width);

    uint16_t bs = 512;
    const uint8_t* bs_u8 = (const uint8_t*) &bs;
    uint16_t bs_read = 0;
    uint8_t* bs_read_u8 = (uint8_t*) &bs_read;
    // Set block sizes for functions 0 to 512 bytes
    ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
    ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
    ESP_LOGI(TAG, "Function 0 BS: %04x", (int) bs_read);

    ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BLKSIZEL, bs_u8[0], NULL));
    ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BLKSIZEH, bs_u8[1], NULL));
    ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
    ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
    ESP_LOGI(TAG, "Function 0 BS: %04x", (int) bs_read);

    // Set block sizes for functions 1 to given value (default value = 512).
    if (context->block_size > 0 || context->block_size <= 2048) {
        bs = context->block_size;
    } else {
        bs = 512;
    }
    size_t offset = SD_IO_FBR_START * 1;
    ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
    ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
    ESP_LOGI(TAG, "Function 1 BS: %04x", (int) bs_read);

    ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, bs_u8[0], NULL));
    ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, bs_u8[1], NULL));
    ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
    ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
    ESP_LOGI(TAG, "Function 1 BS: %04x", (int) bs_read);

    if (bs_read != context->block_size) {
        ESP_LOGW(TAG, "Function1 block size %d different than set value %d", bs_read, context->block_size);
        context->block_size = bs_read;
    }
    return ESP_OK;
}

esp_err_t esp_slave_wait_for_ioready(esp_slave_context_t *context)
{
    ESP_LOGV(TAG, "wait_for_ioready");
    esp_err_t err;
    sdmmc_card_t *card = context->card;
    // wait for the card to become ready
    uint8_t ior = 0;
    while ((ior & FUNC1_EN_MASK) == 0) {
        err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
        if (err != ESP_OK) return err;
        ESP_LOGI(TAG, "IOR: 0x%02x", ior);
    }
    return ESP_OK;
}

static inline esp_err_t esp_slave_write_byte(esp_slave_context_t *context, uint32_t addr, uint8_t val, uint8_t *val_o)
{
   return sdmmc_io_write_byte(context->card, 1, addr&0x3FF, val, val_o);
}

static inline esp_err_t esp_slave_write_bytes(esp_slave_context_t *context, uint32_t addr, uint8_t *val, int len)
{
   return sdmmc_io_write_bytes(context->card, 1, addr&0x3FF, val, len);
}

static inline esp_err_t esp_slave_read_byte(esp_slave_context_t *context, uint32_t addr, uint8_t *val_o)
{
   return sdmmc_io_read_byte(context->card, 1, addr&0x3FF, val_o);
}

static inline esp_err_t esp_slave_read_bytes(esp_slave_context_t *context, uint32_t addr, uint8_t *val_o, int len)
{
   return sdmmc_io_read_bytes(context->card, 1, addr&0x3FF, val_o, len);
}

esp_err_t esp_slave_send_packet(esp_slave_context_t *context, const void* start, size_t length, uint32_t wait_ms)
{
    sdmmc_card_t *card = context->card;
    uint16_t buffer_size = context->buffer_size;
    int buffer_used = (length + buffer_size - 1)/buffer_size;
    esp_err_t err;
    const uint32_t wait_ticks = wait_ms/portTICK_PERIOD_MS;
    uint32_t pre = xTaskGetTickCount();

    assert(length>0);
    for(;;) {
        uint32_t num = 0;
        err = esp_slave_get_tx_buffer_num(context, &num);
        if (err == ESP_OK && num * buffer_size >= length) break;
        if (err != ESP_OK && err != ESP_ERR_TIMEOUT) return err;
        //not error and buffer not enough, retry ``timeout_cnt`` times
        uint32_t now = xTaskGetTickCount();
        if (now-pre >= wait_ticks) {
            ESP_LOGD(TAG, "buffer is not enough: %d, %d required.", num, buffer_used);
            return ESP_ERR_TIMEOUT;
        } else {
            ESP_LOGV(TAG, "buffer is not enough: %d, %d required. Retry...", num, buffer_used);
        }
        vTaskDelay(1);
    }

    ESP_LOGV(TAG, "send_packet: len: %d", length);
    uint8_t *start_ptr = (uint8_t*)start;
    uint32_t len_remain = length;
    do {
        const int block_size = 512;
        /* Though the driver supports to split packet of unaligned size into
         * length of 4x and 1~3, we still send aligned size of data to get
         * higher effeciency. The length is determined by the SDIO address, and
         * the remainning will be discard by the slave hardware.
         */
        int block_n = len_remain/block_size;
        int len_to_send;
        if (block_n) {
            len_to_send = block_n * block_size;
            err = sdmmc_io_write_blocks(card, 1, ESP_SLAVE_CMD53_END_ADDR - len_remain, start_ptr, len_to_send);
        } else {
            len_to_send = len_remain;
            err = sdmmc_io_write_bytes(card, 1, ESP_SLAVE_CMD53_END_ADDR - len_remain, start_ptr, (len_to_send + 3) & (~3));
        }
        if (err != ESP_OK) return err;
        start_ptr += len_to_send;
        len_remain -= len_to_send;
    } while (len_remain);

    context->tx_sent_buffers += buffer_used;
    return ESP_OK;
}

esp_err_t esp_slave_get_packet(esp_slave_context_t *context, void* out_data, size_t size, size_t *out_length, uint32_t wait_ms)
{
    sdmmc_card_t *card = context->card;
    esp_err_t err;
    esp_err_t ret = ESP_OK;
    uint32_t len;
    const uint32_t wait_ticks = wait_ms/portTICK_PERIOD_MS;
    uint32_t pre = xTaskGetTickCount();

    assert (size>0);
    for (;;) {
        err = esp_slave_get_rx_data_size(context, &len);
        if (err == ESP_OK && len > 0) break;
        if (err != ESP_OK && err != ESP_ERR_TIMEOUT) return err;
        //not error and no data, retry ``timeout_cnt`` times.
        uint32_t now = xTaskGetTickCount();
        if (now-pre >= wait_ticks) return ESP_ERR_NOT_FOUND;
        vTaskDelay(1);
    }

    ESP_LOGV(TAG, "get_packet: slave len=%d, max read size=%d", len, size);
    if (len > size) {
       len = size;
       ret = ESP_ERR_NOT_FINISHED;
    }

    uint8_t *start = out_data;
    uint32_t len_remain = len;
    do {
        const int block_size = 512; //currently our driver don't support block size other than 512
        int len_to_send;

        int block_n = len_remain/block_size;
        if (block_n != 0) {
            len_to_send = block_n * block_size;
            err = sdmmc_io_read_blocks(card, 1, ESP_SLAVE_CMD53_END_ADDR - len_remain, start, len_to_send);
        } else {
            len_to_send = len_remain;
            /* though the driver supports to split packet of unaligned size into length
             * of 4x and 1~3, we still get aligned size of data to get higher
             * effeciency. The length is determined by the SDIO address, and the
             * remainning will be ignored by the slave hardware.
             */
            err = sdmmc_io_read_bytes(card, 1, ESP_SLAVE_CMD53_END_ADDR - len_remain, start, (len_to_send + 3) & (~3));
        }
        if (err != ESP_OK) return err;
        start += len_to_send;
        len_remain -= len_to_send;
    } while(len_remain!=0);

    context->rx_got_bytes += len;
    *out_length = len;
    return ret;
}

esp_err_t esp_slave_get_tx_buffer_num(esp_slave_context_t *context, uint32_t* tx_num)
{
    uint32_t len;
    esp_err_t err;

    ESP_LOGV(TAG, "get_tx_buffer_num");
    err = esp_slave_read_bytes(context, HOST_SLC0HOST_TOKEN_RDATA_REG, (uint8_t*)&len, 4);
    if (err != ESP_OK) return err;
    len = (len>>16)&TX_BUFFER_MASK;
    len = (len + TX_BUFFER_MAX - context->tx_sent_buffers)%TX_BUFFER_MAX;
    *tx_num = len;
    return ESP_OK;
}

esp_err_t esp_slave_get_rx_data_size(esp_slave_context_t *context, uint32_t* rx_size)
{
    uint32_t len;
    esp_err_t err;

    ESP_LOGV(TAG, "get_rx_data_size: got_bytes: %d", context->rx_got_bytes);
    err = esp_slave_read_bytes(context, HOST_SLCHOST_PKT_LEN_REG, (uint8_t*)&len, 4);
    if (err != ESP_OK) return err;
    len &= RX_BYTE_MASK;
    len = (len + RX_BYTE_MAX - context->rx_got_bytes)%RX_BYTE_MAX;
    *rx_size = len;
    return ESP_OK;
}

esp_err_t esp_slave_clear_intr(esp_slave_context_t *context, uint32_t intr_mask)
{
    ESP_LOGV(TAG, "clear_intr: %08X", intr_mask);
    return esp_slave_write_bytes(context, HOST_SLC0HOST_INT_CLR_REG, (uint8_t*)&intr_mask, 4);
}

esp_err_t esp_slave_get_intr(esp_slave_context_t *context, uint32_t *intr_raw, uint32_t *intr_st)
{
    esp_err_t r;
    ESP_LOGV(TAG, "get_intr");
    if (intr_raw == NULL && intr_st == NULL) return ESP_ERR_INVALID_ARG;

    if (intr_raw != NULL) {
        r= esp_slave_read_bytes(context, HOST_SLC0HOST_INT_RAW_REG, (uint8_t*)intr_raw, 4);
        if (r != ESP_OK) return r;
    }
    if (intr_st != NULL) {
        r = esp_slave_read_bytes(context, HOST_SLC0HOST_INT_ST_REG, (uint8_t*)intr_st, 4);
        if (r != ESP_OK) return r;
    }
    return ESP_OK;
}

esp_err_t esp_slave_set_intr_ena(esp_slave_context_t *context, uint32_t ena_mask)
{
    ESP_LOGV(TAG, "set_intr_ena: %08X", ena_mask);
    return esp_slave_write_bytes(context, HOST_SLC0HOST_INT_ENA_REG, (uint8_t*)&ena_mask, 4);
}

esp_err_t esp_slave_get_intr_ena(esp_slave_context_t *context, uint32_t *ena_mask_o)
{
    ESP_LOGV(TAG, "get_intr_ena");
    esp_err_t ret = esp_slave_read_bytes(context, HOST_SLC0HOST_INT_ENA_REG, (uint8_t*)ena_mask_o, 4);
    ESP_LOGV(TAG, "ena: %08X", *ena_mask_o);
    return ret;
}

esp_err_t esp_slave_write_reg(esp_slave_context_t *context, uint8_t addr, uint8_t value, uint8_t* value_o)
{
    ESP_LOGV(TAG, "write_reg: %08X", value);
    // addrress over range
    if (addr >= 64) return ESP_ERR_INVALID_ARG;
    // reserved for interrupts
    if (addr >= 28 && addr <= 31) return ESP_ERR_INVALID_ARG;
    return esp_slave_write_byte(context, HOST_SLCHOST_CONF_W_REG(addr), value, value_o);
}

esp_err_t esp_slave_read_reg(esp_slave_context_t *context, uint8_t add, uint8_t *value_o)
{
    ESP_LOGV(TAG, "read_reg");
    // address over range
    if (add >= 64) return ESP_ERR_INVALID_ARG;
    esp_err_t ret = esp_slave_read_byte(context, HOST_SLCHOST_CONF_W_REG(add), value_o);
    ESP_LOGV(TAG, "reg: %08X", *value_o);
    return ret;
}

esp_err_t esp_slave_send_slave_intr(esp_slave_context_t *context, uint8_t intr_mask)
{
    ESP_LOGV(TAG, "send_slave_intr: %02x", intr_mask);
    return esp_slave_write_byte(context, HOST_SLCHOST_CONF_W7_REG+0, intr_mask, NULL);
}


text:
import persistent
from .component import Component
#------------------------------------------------------------------------------#
class User(persistent.Persistent):
    #--------------------------------------------------------------------------#
    def __init__(self, user_id):
        persistent.Persistent.__init__(self)
        self._user_id = user_id

    #--------------------------------------------------------------------------#
    def has_id(self, some_id):
        return self._user_id == some_id

    #--------------------------------------------------------------------------#
    def __eq__(self, that):
        return self._user_id == that._user_id

    #--------------------------------------------------------------------------#
    def __lt__(self, that):
        return self._user_id < that._user_id

#------------------------------------------------------------------------------#
class Users(Component):
    #--------------------------------------------------------------------------#
    def __init__(self):
        Component.__init__(self)
        self._users = list()
        self._users.append(User("root"))

    #--------------------------------------------------------------------------#
    @staticmethod
    def unique_id(): return "Users"

    #--------------------------------------------------------------------------#
    def find(self, user_id):
        for user in self._users:
            if user.has_id(user_id):
                return user

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

redpajama_set_name: RedPajamaGithub


text:
#pragma warning disable 0436
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;

namespace Forge
{

	public class Board : MonoBehaviour {

		public static float maxMovableHeight = .1f;
		public Player player = null;
		public Camera gamecamera;

		public float cameraHeight = 3.0f;

		public int boardSize = 9;
		public Material boardMaterial = null;
		public Material wallMaterial = null;

		public string mapName = null;

		/* boardTiles is an structure that represents the board we are on.

		*/
		public BoardTile[] boardTiles = null ;

		public BoardTile GetTileByPosition(Vector3 position){

			//TODO: Better way to find our tile than a loop
			for(var boardCheck = 0; boardCheck < boardTiles.Length; boardCheck++){

				if(boardTiles[boardCheck].x == position.x && boardTiles[boardCheck].z == position.z){
					return boardTiles[boardCheck];
				}

			}

			return null;

		}

		// Use this for initialization
		void Start () {

			if(mapName == null){
				GenerateMap();
			}else{
				LoadMap(mapName);
			}

			DrawMap();
			cameraHeight = (boardSize * 1.1f);
			gamecamera.transform.position = new Vector3(boardSize/2 - .5f,cameraHeight, boardSize/2 - .5f);
			player.SetPlayerStart();
		}

		void DrawMap(){

			for(var boardItemCount = 0; boardItemCount < boardTiles.Length; boardItemCount++){

				GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
				var renderer = cube.GetComponent<Renderer>();
				Material[] mats = renderer.materials;
				mats[0] = boardTiles[boardItemCount].y > Board.maxMovableHeight ? wallMaterial : boardMaterial;
				renderer.materials = mats;
				cube.transform.position = new Vector3(boardTiles[boardItemCount].x, 0F, boardTiles[boardItemCount].z);
				cube.transform.localScale = new Vector3(1, boardTiles[boardItemCount].y, 1);
				cube.transform.parent = gameObject.transform;
				boardTiles[boardItemCount].physicalTile = cube;

			}

		}

		void GenerateMap(){

			var boardItemCount = 0;
			boardTiles = new BoardTile[boardSize*boardSize];

			for(var xPos = 0; xPos < boardSize; xPos++){

				for(var zPos = 0; zPos < boardSize; zPos++){

					var yPos = .1f;
					if(xPos == 0 || xPos == (boardSize -1) || zPos == 0 || (zPos == boardSize - 1)){
						yPos = 1f;
					}
					else if(xPos < 3  || zPos  < 3){
						yPos = 1f;
					}

					boardTiles[boardItemCount] = new BoardTile(){ x = xPos, y = yPos, z = zPos};
					boardItemCount++;
				}
			}

		}

		void LoadMap(string mapName)
		{
			string path = "Assets/Data/Maps/" + mapName + ".map";
			Debug.Log(path);
			//Reads a map and converts it into a BoardTile array to be drawn
			StreamReader reader = new StreamReader(path);

			var boardItemCount = 0;

			string line = reader.ReadLine();
			boardSize = line.Length;
			var zPos = boardSize-1;
			boardTiles = new BoardTile[boardSize*boardSize];

			do{

				for(var xPos = line.Length -1; xPos >= 0; xPos--){

					var yPos = .1f;
					var lineChar = line[xPos];
					if(lineChar == '#'){
						yPos = 1f;
					}

					boardTiles[boardItemCount] = new BoardTile(){ x = xPos, y = yPos, z = zPos};
					boardItemCount++;
				}

				zPos--;
				line = reader.ReadLine();

			}while(line != null);

			reader.Close();

		}

	}
}


text:
modules = sonLib jobTree bwa lastz last cactus samtools-0.1.19
#hdf5 blasr
.PHONY: all %.all clean %.clean

export HDF5INCLUDEDIR=$(PWD)/hdf5/hdf5/include
export HDF5LIBDIR=$(PWD)/hdf5/hdf5/lib

all : ${modules:%=all.%}

all.%:
	cd $* && make

#This is needed for blasr, but currently blasr won't compile on either hgwdev or os x
hdf5Rule :
	cd hdf5 && ./configure --enable-cxx && make && make install

clean:  ${modules:%=clean.%}
	rm -rf lib/*.h bin/*.dSYM
	cd hdf5 && make clean

clean.%:
	cd $* && make clean


text:
<?php

declare(strict_types=1);

namespace BEAR\QueryRepository;

use BEAR\RepositoryModule\Annotation\AbstractCommand;
use BEAR\RepositoryModule\Annotation\Purge;
use BEAR\RepositoryModule\Annotation\Refresh;
use BEAR\Resource\ResourceInterface;
use BEAR\Resource\ResourceObject;
use BEAR\Resource\Uri;
use Ray\Aop\MethodInvocation;

use function is_array;

final class RefreshAnnotatedCommand implements CommandInterface
{
    /** @var QueryRepositoryInterface */
    private $repository;

    /** @var ResourceInterface */
    private $resource;

    public function __construct(
        QueryRepositoryInterface $repository,
        ResourceInterface $resource
    ) {
        $this->repository = $repository;
        $this->resource = $resource;
    }

    /**
     * @return void
     */
    public function command(MethodInvocation $invocation, ResourceObject $ro)
    {
        $method = $invocation->getMethod();
        $annotations = $method->getAnnotations();
        foreach ($annotations as $annotation) {
            $this->request($ro, $annotation);
        }
    }

    private function getUri(ResourceObject $ro, AbstractCommand $annotation): string
    {
        $body = is_array($ro->body) ? $ro->body : [];
        $query = $body + $ro->uri->query;

        return uri_template($annotation->uri, $query);
    }

    /**
     * @return void
     */
    private function request(ResourceObject $ro, object $annotation)
    {
        if (! $annotation instanceof AbstractCommand) {
            return;
        }

        $uri = new Uri($this->getUri($ro, $annotation));
        if ($annotation instanceof Purge) {
            $this->repository->purge($uri);
        }

        if ($annotation instanceof Refresh) {
            $this->repository->purge($uri);
            $ro = $this->resource->get((string) $uri);
            $this->repository->put($ro);
        }
    }
}


text:
/*
 * @(#)Phone.java	1.5 06/02/11
 */

package com.sun.ts.tests.ejb30.persistence.query.language.schema30;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;

/*
 * Phone
 */

@Entity
@Table(name="PHONE_TABLE")
public class Phone implements java.io.Serializable {

    // Instance variables
    private String id;
    private String area;
    private String number;
    private Address address;

    public Phone()
    {
    }

    public Phone(String v1, String v2, String v3)
    {
	id = v1;
	area = v2;
	number = v3;
    }

    public Phone(String v1, String v2, String v3, Address v4)
    {
	id = v1;
	area = v2;
	number = v3;
	address = v4;
    }

    // getters and setters for state fields
    @Id
    @Column(name="ID")
    public String getId()
    {
	return id;
    }
    public void setId(String v)
    {
	id = v;
    }

    @Column(name="AREA")
    public String getArea()
    {
	return area;
    }
    public void setArea(String v)
    {
	area = v;
    }

    @Column(name="PHONE_NUMBER")
    public String getNumber()
    {
	return number;
    }
    public void setNumber(String v)
    {
	number = v;
    }
    // ===========================================================
    // getters and setters for Association fields

    // Manyx1

    @ManyToOne
    @JoinColumn(
	name="FK_FOR_ADDRESS")
    public Address getAddress()
    {
	return address;
    }
    public void setAddress(Address a)
    {
	address = a;
    }

}


text:
title: Palvelut
layout: default
---

Toteutan asiakkaille räätälöityjä ohjelmistoja, mobiiliohjelmia sekä WWW-sivuja ammattitaidolla ja laadulla. Päätämme oikean toteutustavan yhdessä asiakkaan kanssa.

Esimerkkinä räätälöidystä ohjelmasta on Koordinaattimuunnin. Toteutin Kemin kaupungin maankäyttö- ja mittaustoimen toimeksiannosta ohjelman, jolla koordinaattien muunto järjestelmästä toiseen on sujuvaa ja nopeaa. Lisätietoja koordinaattimuuntimesta löydät sen sivuilta.

Kiinnostuitko? Ota yhteyttä, niin suunnittellaan yhdessä sopiva ratkaisu.


text:
require 'spec_helper'
require 'rack/test'
require 'bosh/director/api/controllers/configs_controller'

module Bosh::Director
  describe Api::Controllers::ConfigsController do
    include Rack::Test::Methods

    subject(:app) { Api::Controllers::ConfigsController.new(config) }
    let(:config) do
      config = Config.load_hash(SpecHelper.spec_get_director_config)
      identity_provider = Support::TestIdentityProvider.new(config.get_uuid_provider)
      allow(config).to receive(:identity_provider).and_return(identity_provider)
      config
    end

    describe 'GET', '/' do
      context 'with authenticated admin user' do
        before(:each) do
          authorize('admin', 'admin')
        end

        it 'returns all matching' do
          newest_config = 'new_config'

          Models::Config.make(
            content: 'some-yaml',
            created_at: Time.now - 3.days,
          )

          Models::Config.make(
            content: 'some-other-yaml',
            created_at: Time.now - 2.days,
          )

          Models::Config.make(
            name: 'my-config',
            content: newest_config,
            created_at: Time.now - 1.days,
          )

          get '/?&limit=1'
          expect(last_response.status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(2)
          expect(JSON.parse(last_response.body)).to include(include('content' => 'some-other-yaml'))
          expect(JSON.parse(last_response.body)).to include(include('content' => newest_config))
        end

        context 'when name is given' do
          it 'returns the latest config with that name' do
            Models::Config.make(
              content: 'some-yaml',
              created_at: Time.now - 3.days,
            )

            Models::Config.make(
              content: 'some-other-yaml',
              created_at: Time.now - 2.days,
            )

            newest_config = 'new_config'
            Models::Config.make(
              name: 'my-config',
              content: newest_config,
              created_at: Time.now - 1.days,
            )

            get '/?type=my-type&name=my-config&limit=1'
            expect(last_response.status).to eq(200)
            expect(JSON.parse(last_response.body).count).to eq(1)
            expect(JSON.parse(last_response.body).first['content']).to eq(newest_config)
          end
        end

        it 'returns the latest config' do
          Models::Config.make(
            content: 'some-yaml',
            created_at: Time.now - 3.days,
          )

          Models::Config.make(
            content: 'some-other-yaml',
            created_at: Time.now - 2.days,
          )

          newest_config = 'new_config'
          Models::Config.make(
            content: newest_config,
            created_at: Time.now - 1.days,
          )

          get '/?type=my-type&limit=1'
          expect(last_response.status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(1)
          expect(JSON.parse(last_response.body).first['content']).to eq(newest_config)
        end

        context 'when no records match the filters' do
          it 'returns empty' do
            get '/?type=my-type&name=notExisting&limit=1'

            expect(last_response.status).to eq(200)

            result = JSON.parse(last_response.body)
            expect(result.class).to be(Array)
            expect(result).to eq([])
          end
        end

        context 'when no type is given' do
          it 'does not filter by type' do
            Models::Config.make(content: 'some-other-yaml')

            newest_config = 'new_config'
            Models::Config.make(content: newest_config)

            get '/?limit=1'

            expect(JSON.parse(last_response.body).count).to eq(1)
            expect(JSON.parse(last_response.body).first['content']).to eq(newest_config)
          end
        end

        context 'when no limit param is given' do
          it 'defaults to 1' do
            Models::Config.make
            Models::Config.make(content: 'newest_config')
            get '/?type=my-type&name=some-name'

            expect(last_response.status).to eq(200)
            expect(JSON.parse(last_response.body).count).to eq(1)
            expect(JSON.parse(last_response.body).first['content']).to eq('newest_config')
          end

          context 'when latest is set to true' do
            it 'defaults to 1' do
              Models::Config.make
              Models::Config.make(content: 'newest_config')
              get '/?type=my-type&name=some-name&latest=true'

              expect(last_response.status).to eq(200)
              expect(JSON.parse(last_response.body).count).to eq(1)
              expect(JSON.parse(last_response.body).first['content']).to eq('newest_config')
            end
          end

          context 'when latest is set to false' do
            it 'returns the history of all matching configs' do
              config1 = Models::Config.make
              Models::Config.make

              get '/?type=my-type&latest=false'

              expect(last_response.status).to eq(200)

              result = JSON.parse(last_response.body)
              expect(result.class).to be(Array)
              expect(result.size).to eq(2)
              expect(result).to include(
                'content' => config1.content,
                'id' => config1.id.to_s,
                'type' => config1.type,
                'name' => config1.name,
                'created_at' => config1.created_at.to_s,
                'team' => nil,
              )
            end
          end

          context 'when latest is not set' do
            it 'defaults to 1' do
              Models::Config.make
              Models::Config.make(content: 'newest_config')
              get '/?type=my-type&name=some-name'

              expect(last_response.status).to eq(200)
              expect(JSON.parse(last_response.body).count).to eq(1)
              expect(JSON.parse(last_response.body).first['content']).to eq('newest_config')
            end
          end

          context 'when latest param is given and has wrong value' do
            it 'return 400' do
              get '/?type=my-type&name=some-name&latest=foo'

              expect(last_response.status).to eq(400)
              expect(JSON.parse(last_response.body)['code']).to eq(440_010)
              expect(JSON.parse(last_response.body)['description']).to eq("'latest' must be 'true' or 'false'")
            end
          end
        end

        context 'when latest and limit are given' do
          it 'takes value of limit' do
            Models::Config.make
            Models::Config.make(content: 'newest_config')
            get '/?type=my-type&name=some-name&latest=false&limit=1'

            expect(last_response.status).to eq(200)
            expect(JSON.parse(last_response.body).count).to eq(1)
            expect(JSON.parse(last_response.body).first['content']).to eq('newest_config')
          end
        end

        context 'when limit param is given and has wrong value' do
          it 'return 400' do
            get '/?type=my-type&name=some-name&limit=foo'

            expect(last_response.status).to eq(400)
            expect(JSON.parse(last_response.body)['code']).to eq(440_010)
            expect(JSON.parse(last_response.body)['description']).to eq("'limit' must be a number")
          end

          it 'return 400 for zero' do
            get '/?limit=0'

            expect(last_response.status).to eq(400)
            expect(JSON.parse(last_response.body)['code']).to eq(440_010)
            expect(JSON.parse(last_response.body)['description']).to eq("'limit' must be larger than zero")
          end
        end

        context 'when limit is greater one' do
          it 'returns the history of all matching configs' do
            config1 = Models::Config.make
            Models::Config.make

            get '/?type=my-type&limit=2'

            expect(last_response.status).to eq(200)

            result = JSON.parse(last_response.body)
            expect(result.class).to be(Array)
            expect(result.size).to eq(2)
            expect(result).to include(
              'content' => config1.content,
              'id' => config1.id.to_s,
              'type' => config1.type,
              'name' => config1.name,
              'created_at' => config1.created_at.to_s,
              'team' => nil,
            )
          end
        end
      end
    end

    describe 'POST', '/' do
      let(:config_data) { 'a: 1' }
      let(:request_body) do
        JSON.generate('name' => 'my-name', 'type' => 'my-type', 'content' => config_data, 'expected_latest_id' => '0')
      end

      describe 'when user has admin access' do
        before { authorize('admin', 'admin') }

        it 'creates a new config and returns new config as JSON' do
          expect do
            post '/', request_body, 'CONTENT_TYPE' => 'application/json'
          end.to change(Bosh::Director::Models::Config, :count).from(0).to(1)

          expect(last_response.status).to eq(201)

          config = Bosh::Director::Models::Config.first
          expect(JSON.parse(last_response.body)).to eq(
            'id' => config.id.to_s,
            'type' => 'my-type',
            'name' => 'my-name',
            'content' => 'a: 1',
            'created_at' => config.created_at.to_s,
            'team' => nil,
          )
        end

        context 'when config exists with different content' do
          it 'creates a new config if expected latest id is not specified' do
            Models::Config.make(
              name: 'my-name',
              type: 'my-type',
              content: 'a: 123',
            )
            expect do
              post(
                '/',
                JSON.generate(
                  'name' => 'my-name',
                  'type' => 'my-type',
                  'content' => 'b: 12345',
                ),
                'CONTENT_TYPE' => 'application/json',
              )
            end.to change(Models::Config, :count)
            expect(last_response.status).to eq(201)
          end

          it 'does not create a new config if expected latest id is not latest id' do
            config1 = Models::Config.make(
              name: 'my-name',
              type: 'my-type',
              content: 'a: 123',
            )
            config2 = Models::Config.make(
              name: 'my-name',
              type: 'my-type',
              content: 'a: 456',
            )
            expect do
              post(
                '/',
                JSON.generate(
                  'name' => 'my-name',
                  'type' => 'my-type',
                  'content' => 'b: 789',
                  'expected_latest_id' => config1.id,
                ),
                'CONTENT_TYPE' => 'application/json',
              )
            end.to_not change(Models::Config, :count)
            expect(last_response.status).to eq(412)
            expect(JSON.parse(last_response.body)['latest_id']).to eq(config2.id.to_s)
            expect(JSON.parse(last_response.body)['description']).to include(
              "Latest Id: '#{config2.id}' does not match expected latest id",
            )
          end

          it 'does not create a new config if using expected latest id with empty configs' do
            expect do
              post(
                '/',
                JSON.generate(
                  'name' => 'my-name',
                  'type' => 'my-type',
                  'content' => 'b: 789',
                  'expected_latest_id' => '123',
                ),
                'CONTENT_TYPE' => 'application/json',
              )
            end.to_not change(Models::Config, :count)
            expect(last_response.status).to eq(412)
            expect(JSON.parse(last_response.body)['latest_id']).to eq('0')
            expect(JSON.parse(last_response.body)['description']).to include(
              "Latest Id: '0' does not match expected latest id",
            )
          end

          it 'creates a new config if expected latest id matches latest id' do
            Models::Config.make(
              name: 'my-name',
              type: 'my-type',
              content: 'a: 123',
            )
            config2 = Models::Config.make(
              name: 'my-name',
              type: 'my-type',
              content: 'a: 456',
            )
            expect do
              post(
                '/',
                JSON.generate(
                  'name' => 'my-name',
                  'type' => 'my-type',
                  'content' => 'b: 12345',
                  'expected_latest_id' => config2.id,
                ),
                'CONTENT_TYPE' => 'application/json',
              )
            end.to change(Models::Config, :count)
            expect(last_response.status).to eq(201)
          end
        end

        it 'ignores config when config already exists' do
          Models::Config.make(
            name: 'my-name',
            type: 'my-type',
            content: 'a: 123',
          )

          expect do
            post '/', JSON.generate(
              'name' => 'my-name',
              'type' => 'my-type',
              'content' => 'a: 123',
            ), 'CONTENT_TYPE' => 'application/json'
          end.to_not change(Models::Config, :count)

          expect(last_response.status).to eq(201)
        end

        it 'gives a nice error when request body is invalid json' do
          post '/', "}}}i'm not really encoded, hah!", 'CONTENT_TYPE' => 'application/json'

          expect(last_response.status).to eq(400)
          expect(JSON.parse(last_response.body)['code']).to eq(710_001)
          expect(JSON.parse(last_response.body)['description']).to include('Invalid JSON request body: ')
        end

        context 'when content is not valid json' do
          it 'creates a new event and gives a nice error' do
            new_config = JSON.generate(
              'type' => 'myType',
              'name' => 'myName',
              'content' => "}}}i'm not really json, hah!",
            )

            post '/', new_config, 'CONTENT_TYPE' => 'application/json'

            event = Bosh::Director::Models::Event.first
            expect(event.object_type).to eq('config/myType')
            expect(event.object_name).to eq('myName')
            expect(event.action).to eq('create')
            expect(event.user).to eq('admin')

            expect(last_response.status).to eq(400)
            expect(JSON.parse(last_response.body)['code']).to eq(440_011)
            expect(JSON.parse(last_response.body)['description']).to include('Config must be valid YAML: ')
          end
        end

        it 'creates a new event' do
          expect do
            post '/', request_body, 'CONTENT_TYPE' => 'application/json'
          end.to change(Bosh::Director::Models::Event, :count).from(0).to(1)
          event = Bosh::Director::Models::Event.first
          expect(event.object_type).to eq('config/my-type')
          expect(event.object_name).to eq('my-name')
          expect(event.action).to eq('create')
          expect(event.user).to eq('admin')
        end

        context 'when the content is no YAML hash' do
          let(:request_body) { '{"name":"n","type":"t","content":"I am a string","expected_latest_id":"0"}' }

          it 'return 400' do
            post '/', request_body, 'CONTENT_TYPE' => 'application/json'

            expect(last_response.status).to eq(400)
            expect(JSON.parse(last_response.body)['code']).to eq(440_011)
            expect(JSON.parse(last_response.body)['description']).to eq('YAML hash expected')
          end
        end

        context 'when `type` argument is missing' do
          let(:request_body) do
            JSON.generate('name' => 'my-name', 'content' => '{}', 'expected_latest_id' => '0')
          end

          it 'creates a new event and return 400' do
            post '/', request_body, 'CONTENT_TYPE' => 'application/json'

            event = Bosh::Director::Models::Event.first
            expect(event.object_type).to eq('config/')
            expect(event.object_name).to eq('my-name')
            expect(event.action).to eq('create')
            expect(event.user).to eq('admin')
            expect(event.error).to eq("'type' is required")

            expect(last_response.status).to eq(400)
            expect(JSON.parse(last_response.body)['code']).to eq(440_010)
            expect(JSON.parse(last_response.body)['description']).to eq("'type' is required")
          end
        end

        context 'when `name` argument is missing' do
          let(:request_body) do
            JSON.generate('type' => 'my-type', 'content' => '{}', 'expected_latest_id' => '0')
          end

          it 'creates a new event and return 400' do
            post '/', request_body, 'CONTENT_TYPE' => 'application/json'

            event = Bosh::Director::Models::Event.first
            expect(event.object_type).to eq('config/my-type')
            expect(event.object_name).to eq(nil)
            expect(event.action).to eq('create')
            expect(event.user).to eq('admin')

            expect(last_response.status).to eq(400)
            expect(JSON.parse(last_response.body)['code']).to eq(440_010)
            expect(JSON.parse(last_response.body)['description']).to eq("'name' is required")
          end
        end
      end
    end

    describe 'DELETE', '/' do
      describe 'when user has admin access' do
        before { authorize('admin', 'admin') }

        context 'when type and name are given' do
          context 'when config exists' do
            before do
              Models::Config.make(
                type: 'my-type',
                name: 'my-name',
              )
            end

            it 'deletes the config' do
              expect(delete('/?type=my-type&name=my-name').status).to eq(204)

              configs = JSON.parse(get('/?type=my-type&name=my-name&limit=10').body)

              expect(configs.count).to eq(0)
            end
          end

          context "when there is no config matching given 'type' and 'name'" do
            it 'responds with 404' do
              expect(delete('/?type=my-type&name=my-name').status).to eq(404)
            end
          end
        end

        context "when 'type' parameter is missing" do
          it 'responds with 400' do
            response = delete('/?name=my-name')

            expect(response.status).to eq(400)
            expect(JSON.parse(response.body)['description']).to eq("'type' is required")
          end
        end

        context "when 'name' parameter is missing" do
          it 'responds with 400' do
            response = delete('/?type=my-type')

            expect(response.status).to eq(400)
            expect(JSON.parse(response.body)['description']).to eq("'name' is required")
          end
        end
      end
    end

    describe 'DELETE', '/:id' do
      describe 'when user has admin access' do
        before { authorize('admin', 'admin') }

        context 'when config exists' do
          let(:config_id) { Models::Config.make.id }

          it 'deletes the config specified by id' do
            expect(delete("/#{config_id}").status).to eq(204)
            expect(Models::Config[config_id].deleted).to eq(true)
          end
        end

        context 'when config does not exists' do
          it 'deletes the config specified by id' do
            expect(delete('/5').status).to eq(404)
          end
        end

        context 'when "id" parameter is not an integer' do
          it 'responds with 400' do
            expect(delete('/bla').status).to eq(404)
          end
        end
      end
    end

    describe 'diff' do
      let(:config_hash_with_one_az) do
        {
          'azs' => [
            {
              'name' => 'az1',
              'properties' => {},
            },
          ],
        }
      end

      let(:config_hash_with_two_azs) do
        {
          'azs' => [
            {
              'name' => 'az1',
              'properties' => {},
            },
            {
              'name' => 'az2',
              'properties' => {
                'some-key' => 'some-value',
              },
            },
          ],
        }
      end

      let(:new_config) do
        JSON.generate(
          'type' => 'myType',
          'name' => 'myName',
          'content' => new_content,
        )
      end

      let(:new_content) { "---\n" }

      context 'authenticated access' do
        before { authorize 'admin', 'admin' }

        context 'when none of the accepted request body formats is used' do
          let(:body) do
            JSON.dump('I am not a valid' => 'request')
          end

          let(:id_format) { JSON.dump('id' => '<id>') }
          let(:content_format) { JSON.dump('content' => '<content>') }
          let(:config_format) { JSON.dump('type' => '<type>', 'name' => '<name>', 'content' => '<content>') }

          let(:diff_err_msg) do
            %(The following request formats are allowed:\n) +
              %(1. {"from":<config>,"to":<config>} where <config> is either #{id_format} or #{content_format}\n) +
              %(2. #{config_format})
          end

          it 'returns 400 with error details' do
            post '/diff', body, 'CONTENT_TYPE' => 'application/json'

            expect(last_response.status).to eq(400)
            expect(JSON.parse(last_response.body)['code']).to eq(440_010)
            expect(JSON.parse(last_response.body)['description']).to eq(diff_err_msg)
          end

          context 'when any of the given `id` values is not a string containing an integer' do
            it 'returns 400 with error details' do
              post(
                '/diff',
                JSON.generate('from' => { 'id' => 'foo' }, 'to' => { 'id' => '1' }),
                'CONTENT_TYPE' => 'application/json',
              )

              expect(last_response.status).to eq(400)
              expect(JSON.parse(last_response.body)['code']).to eq(440_010)
              expect(JSON.parse(last_response.body)['description']).to eq(diff_err_msg)

              post(
                '/diff',
                JSON.generate('from' => { 'id' => '1' }, 'to' => { 'id' => 'foo' }),
                'CONTENT_TYPE' => 'application/json',
              )

              expect(last_response.status).to eq(400)
              expect(JSON.parse(last_response.body)['code']).to eq(440_010)
              expect(JSON.parse(last_response.body)['description']).to eq(diff_err_msg)
            end
          end

          context 'when any of the given `id` values is from type integer' do
            it 'returns 400 with error details' do
              post '/diff', JSON.generate('from' => { 'id' => 1 }, 'to' => { 'id' => '1' }), 'CONTENT_TYPE' => 'application/json'

              expect(last_response.status).to eq(400)
              expect(JSON.parse(last_response.body)['code']).to eq(440_010)
              expect(JSON.parse(last_response.body)['description']).to eq(diff_err_msg)
            end
          end

          context 'when the `content` value is not a string' do
            it' returns 400 with error details' do
              post '/diff', JSON.generate('from' => { 'content' => -1 }, 'to' => { 'id' => '1' }), 'CONTENT_TYPE' => 'application/json'

              expect(last_response.status).to eq(400)
              expect(JSON.parse(last_response.body)['code']).to eq(440_010)
              expect(JSON.parse(last_response.body)['description']).to eq(diff_err_msg)
            end
          end
        end

        context 'when diffing yields an error' do
          let(:new_content) { 'a: 1' }
          it 'returns 400 with an empty diff and an error message' do
            allow_any_instance_of(Bosh::Director::Changeset).to receive(:diff).and_raise('Oooooh crap')

            post '/diff', new_config, 'CONTENT_TYPE' => 'application/json'

            expect(last_response.status).to eq(400)
            expect(JSON.parse(last_response.body)['diff']).to eq([])
            expect(JSON.parse(last_response.body)['error']).to include('Unable to diff config content')
          end
        end

        context 'when one concrete config is given' do
          context 'when there is a previous config with given name and type' do
            before do
              Models::Config.create(
                type: 'myType',
                name: 'myName',
                raw_manifest: config_hash_with_two_azs,
              )
            end

            context 'when uploading an empty config' do
              let(:new_content) { "---\n" }

              it 'returns the diff' do
                post(
                  '/diff',
                  new_config,
                  'CONTENT_TYPE' => 'application/json',
                )

                expect(JSON.parse(last_response.body)['diff']).to eq([])
                expect(JSON.parse(last_response.body)['error']).to include('YAML hash expected')
              end
            end

            context 'when there is no diff' do
              let(:new_content) { YAML.dump(config_hash_with_two_azs) }

              it 'returns empty diff' do
                post(
                  '/diff',
                  new_config,
                  'CONTENT_TYPE' => 'application/json',
                )
                expect(last_response.body).to match('\{"from":\{"id":"\d+"\}\,"diff":\[\]}')
              end
            end

            context 'when there is a diff' do
              let(:new_content) { YAML.dump(config_hash_with_one_az) }

              it 'returns the diff' do
                post(
                  '/diff',
                  new_config,
                  'CONTENT_TYPE' => 'application/json',
                )
                expect(last_response.status).to eq(200)
                json_response = JSON.parse(last_response.body)
                expect(json_response).to match(
                  'diff' => [
                    ['azs:', nil],
                    ['- name: az2', 'removed'],
                    ['  properties:', 'removed'],
                    ['    some-key: "<redacted>"', 'removed'],
                  ],
                  'from' => { 'id' => anything }
                )
              end
            end

            context 'when invalid content YAML is given' do
              let(:new_content) { "}}}i'm not really encoded, hah!" }
              it 'gives a nice error when request body is not a valid yml' do
                post('/diff', new_config, 'CONTENT_TYPE' => 'application/json')

                expect(last_response.status).to eq(400)
                expect(JSON.parse(last_response.body)['diff']).to eq([])
                expect(JSON.parse(last_response.body)['error']).to include('Config must be valid YAML')
              end
            end

            context 'when the body is not valid YAML' do
              it 'gives a nice error when request body is invalid json' do
                post('/diff', "}}}i'm not really encoded, hah!", 'CONTENT_TYPE' => 'application/json')

                expect(last_response.status).to eq(400)
                expect(JSON.parse(last_response.body)['code']).to eq(710_001)
                expect(JSON.parse(last_response.body)['description']).to include('Invalid JSON request body: ')
              end
            end

            context 'when config content is empty' do
              let(:new_content) { '' }
              it 'gives a nice error ' do
                post '/diff', new_config, 'CONTENT_TYPE' => 'application/json'

                expect(last_response.status).to eq(400)
                expect(JSON.parse(last_response.body)['diff']).to eq([])
                expect(JSON.parse(last_response.body)['error']).to include('YAML hash expected')
              end
            end

            context 'when config content is not a hash' do
              let(:new_content) { 'I am not a hash' }
              it 'errors' do
                post '/diff', new_config, 'CONTENT_TYPE' => 'application/json'

                expect(last_response.status).to eq(400)
                expect(JSON.parse(last_response.body)['error']).to include('YAML hash expected')
              end
            end
          end

          context 'when there is no previous cloud config' do
            let(:new_content) { YAML.dump(config_hash_with_one_az) }
            it 'returns the diff' do
              post(
                '/diff',
                new_config,
                'CONTENT_TYPE' => 'application/json',
              )
              expect(last_response.status).to eq(200)
              expect(last_response.body).to eq('{"from":{"id":"0"},"diff":[["azs:","added"],["- name: az1","added"],["  properties: {}","added"]]}')
            end
          end

          context 'when previous config is nil' do
            before do
              @config_id = Models::Config.create(
                type: 'myType',
                name: 'myName',
                raw_manifest: nil,
              ).id
            end
            let(:new_content) { YAML.dump(config_hash_with_one_az) }

            it 'returns the diff' do
              post(
                '/diff',
                new_config,
                'CONTENT_TYPE' => 'application/json',
              )
              expect(last_response.status).to eq(200)
              expect(last_response.body).to eq(%({"from":{"id":"#{@config_id}"},"diff":[["azs:","added"],["- name: az1","added"],["  properties: {}","added"]]}))
            end
          end
        end

        context 'when diffing two configs' do
          let(:dev_team) { Models::Team.create(name: 'dev') }
          let(:dev_team_config_manifest) do
            { 'a' => 5 }
          end
          let(:dev_team_config) do
            Models::Config.create(
              type: 'custom',
              name: 'dev-team',
              raw_manifest: dev_team_config_manifest,
              team_id: dev_team.id,
            )
          end

          let(:other_team) { Models::Team.create(name: 'other') }
          let(:other_team_config_manifest) do
            { 'b' => 5 }
          end
          let(:other_team_config) do
            Models::Config.create(
              type: 'custom',
              name: 'other-team',
              raw_manifest: other_team_config_manifest,
              team_id: other_team.id,
            )
          end

          context 'from a given `id` to a given `id`' do
            it 'returns the diff' do
              post(
                '/diff',
                JSON.dump(from: { id: dev_team_config.id.to_s }, to: { id: other_team_config.id.to_s }),
                'CONTENT_TYPE' => 'application/json',
              )
              expect(last_response.status).to eq(200)
              expect(last_response.body).to eq(%'{"diff":[["a: 5","removed"],["",null],["b: 5","added"]]}')
            end
          end

          context 'from a given `content` to a given `content`' do
            it 'returns the diff' do
              post(
                '/diff',
                JSON.dump(from: { content: YAML.dump(dev_team_config_manifest) }, to: { content: YAML.dump(other_team_config_manifest) }),
                'CONTENT_TYPE' => 'application/json',
              )
              expect(last_response.status).to eq(200)
              expect(last_response.body).to eq('{"diff":[["a: 5","removed"],["",null],["b: 5","added"]]}')
            end
          end

          context 'from a given `content` to a given `id`' do
            it 'returns the diff' do
              post(
                '/diff',
                JSON.dump(from: { content: YAML.dump(dev_team_config_manifest) }, to: { id: other_team_config.id.to_s }),
                'CONTENT_TYPE' => 'application/json',
              )
              expect(last_response.status).to eq(200)
              expect(last_response.body).to eq('{"diff":[["a: 5","removed"],["",null],["b: 5","added"]]}')
            end
          end

          context 'from a given `id` to a given `content`' do
            it 'returns the diff' do
              post(
                '/diff',
                JSON.dump(from: { id: dev_team_config.id.to_s }, to: { content: YAML.dump(other_team_config_manifest) }),
                'CONTENT_TYPE' => 'application/json',
              )
              expect(last_response.status).to eq(200)
              expect(last_response.body).to eq(%'{"diff":[["a: 5","removed"],["",null],["b: 5","added"]]}')
            end

            context 'where the `content` is an empty config' do
              it 'gives a nice error' do
                post(
                  '/diff',
                  JSON.dump(from: { id: dev_team_config.id.to_s }, to: { content: "---\n" }),
                  'CONTENT_TYPE' => 'application/json',
                )

                expect(JSON.parse(last_response.body)['diff']).to eq([])
                expect(JSON.parse(last_response.body)['error']).to include('YAML hash expected')
              end
            end

            context 'where the `content` is invalid YAML' do
              it 'gives a nice error' do
                post(
                  '/diff',
                  JSON.dump(from: { id: dev_team_config.id.to_s }, to: { content: "}I'm not valid yaml" }),
                  'CONTENT_TYPE' => 'application/json',
                )

                expect(last_response.status).to eq(400)
                expect(JSON.parse(last_response.body)['diff']).to eq([])
                expect(JSON.parse(last_response.body)['error']).to include('Config must be valid YAML')
              end
            end
          end

          context "when referencing another team's config" do
            context 'without a team-specific user' do
              before { basic_authorize 'dev-team-member', 'dev-team-member' }

              it 'should return an error when the old config is unauthorized' do
                post(
                  '/diff',
                  JSON.dump(from: { id: other_team_config.id.to_s }, to: { id: dev_team_config.id.to_s }),
                  'CONTENT_TYPE' => 'application/json',
                )
                expect(last_response.status).to eq(401)
                json_response = JSON.parse(last_response.body)
                expect(json_response['code']).to eq(600_000)
                expect(json_response['description'])
                  .to eq('Require one of the scopes: bosh.admin, bosh..admin, bosh.teams.other.admin')
              end

              it 'should return an error when the new config is unauthorized' do
                post(
                  '/diff',
                  JSON.dump(from: { id: dev_team_config.id.to_s }, to: { id: other_team_config.id.to_s }),
                  'CONTENT_TYPE' => 'application/json',
                )
                expect(last_response.status).to eq(401)
                json_response = JSON.parse(last_response.body)
                expect(json_response['code']).to eq(600_000)
                expect(json_response['description'])
                  .to eq('Require one of the scopes: bosh.admin, bosh..admin, bosh.teams.other.admin')
              end

              let(:new_config) do
                JSON.generate(
                  'type' => other_team_config.type,
                  'name' => other_team_config.name,
                  'content' => YAML.dump(other_team_config.raw_manifest),
                )
              end

              it 'should return an error when the config is unauthorized and we post data to diff' do
                post(
                  '/diff',
                  new_config,
                  'CONTENT_TYPE' => 'application/json',
                )

                expect(last_response.status).to eq(401)

                json_response = JSON.parse(last_response.body)
                expect(json_response['code']).to eq(600_000)
                expect(json_response['description'])
                  .to eq('Require one of the scopes: bosh.admin, bosh..admin, bosh.teams.other.admin')
              end
            end
          end

          context 'when config with given "id" does not exist' do
            it 'returns 404 with error details' do
              post(
                '/diff',
                JSON.dump(from: { id: '5' }, to: { id: other_team.id.to_s }),
                'CONTENT_TYPE' => 'application/json',
              )

              expect(last_response.status).to eq(404)
              expect(JSON.parse(last_response.body)['code']).to eq(440_012)
              expect(JSON.parse(last_response.body)['description']).to eq('Config 5 not found')
            end
          end
        end
      end

      context 'accessing with invalid credentials' do
        before { authorize 'invalid-user', 'invalid-password' }

        it 'returns 401' do
          post '/diff', {}.to_json, 'CONTENT_TYPE' => 'application/json'
          expect(last_response.status).to eq(401)
        end
      end
    end

    describe 'authorization' do
      let(:request_body) do
        JSON.generate('type' => 'my-type', 'content' => '{}')
      end

      let(:dev_team) { Models::Team.create(name: 'dev') }
      let(:other_team) { Models::Team.create(name: 'other') }
      let!(:dev_config) do
        Models::Config.make(
          content: 'some-yaml',
          name: 'dev_config',
          created_at: Time.now - 3.days,
          team_id: dev_team.id,
        )
      end

      let!(:other_config) do
        Models::Config.make(
          content: 'some-other-yaml',
          name: 'other_config',
          created_at: Time.now - 2.days,
          team_id: other_team.id,
        )
      end

      context 'without an authenticated user' do
        it 'denies read access' do
          expect(get('/').status).to eq(401)
        end

        it 'denies write access' do
          expect(post('/', request_body, 'CONTENT_TYPE' => 'application/json').status).to eq(401)
        end

        it 'does not permit delete the config' do
          expect(delete('/?type=my-type&name=dev_config').status).to eq(401)
        end
      end

      context 'when user has a team admin membership' do
        before { basic_authorize 'dev-team-member', 'dev-team-member' }

        it 'returns team configs' do
          get '/?type=my-type&latest=false'
          expect(get('/?type=my-type&latest=false').status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(1)
          expect(JSON.parse(last_response.body)).to include(include('content' => 'some-yaml'))
          expect(JSON.parse(last_response.body).first['team']).to eq('dev')
        end

        it 'stores team-specific configs' do
          expect do
            post(
              '/',
              JSON.generate('name' => 'my-name', 'type' => 'my-type', 'content' => 'a: 123'),
              'CONTENT_TYPE' => 'application/json',
            )
          end.to change(Bosh::Director::Models::Config, :count).from(2).to(3)
          expect(Bosh::Director::Models::Config.all[2][:team_id]).to eq(dev_team.id)
        end

        it 'deletes the config' do
          expect(delete('/?type=my-type&name=dev_config').status).to eq(204)
          configs = JSON.parse(get('/?type=my-type&name=dev_config&latest=false').body)
          expect(configs.count).to eq(0)
        end

        it "cannot overwrite another team's config" do
          expect(
            post(
              '/',
              JSON.generate('name' => 'other_config', 'type' => 'my-type', 'content' => 'a: 123'),
              'CONTENT_TYPE' => 'application/json',
            ).status,
          ).to eq(401)
        end

        it "cannot delete another team's config" do
          expect(delete('/?type=my-type&name=other_config').status).to eq(401)
        end

        it "cannot delete another team's config by id" do
          expect(delete("/#{other_config.id}").status).to eq(401)
        end
      end

      context 'when user has a team read membership' do
        before { basic_authorize 'dev-team-read-member', 'dev-team-read-member' }

        it 'permits read access to the teams config' do
          get '/?type=my-type&latest=false'
          expect(get('/?type=my-type&latest=false').status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(1)
          expect(JSON.parse(last_response.body)).to include(include('content' => 'some-yaml'))
        end

        it 'denies write access' do
          expect(post('/', request_body, 'CONTENT_TYPE' => 'application/json').status).to eq(401)
        end

        it 'does not permit delete the config' do
          expect(delete('/?type=my-type&name=dev_config').status).to eq(401)
        end

        it 'returns team configs' do
          get '/?type=my-type&latest=false'
          expect(get('/?type=my-type&latest=false').status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(1)
          expect(JSON.parse(last_response.body).first['team']).to eq('dev')
        end
      end

      context 'when user is an admin' do
        before { basic_authorize('admin', 'admin') }

        it 'permits read access to all configs' do
          expect(get('/?type=my-type&latest=false').status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(2)
        end

        it 'permits write access' do
          expect do
            post(
              '/',
              JSON.generate('name' => 'my-name', 'type' => 'my-type', 'content' => 'a: 123'),
              'CONTENT_TYPE' => 'application/json',
            )
          end.to change(Bosh::Director::Models::Config, :count).from(2).to(3)
        end

        it 'deletes the config' do
          expect(delete('/?type=my-type&name=dev_config').status).to eq(204)
          configs = JSON.parse(get('/?type=my-type&name=dev_config&latest=false').body)
          expect(configs.count).to eq(0)
        end

        it 'returns teams value' do
          get '/?type=my-type&latest=false'
          expect(get('/?type=my-type&latest=false').status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(2)
          expect(JSON.parse(last_response.body).map { |x| x['team'] }).to contain_exactly('dev', 'other')
        end
      end

      context 'when user has read-only access to director' do
        before { basic_authorize('reader', 'reader') }

        it 'permits read access to all configs' do
          expect(get('/?type=my-type&latest=false').status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(2)
        end

        it 'denies write access' do
          expect(post('/', request_body, 'CONTENT_TYPE' => 'application/json').status).to eq(401)
        end

        it 'does not permit delete the config' do
          expect(delete('/?type=my-type&name=dev_config').status).to eq(401)
        end

        it 'returns all configs' do
          get '/?type=my-type&latest=false'
          expect(get('/?type=my-type&latest=false').status).to eq(200)
          expect(JSON.parse(last_response.body).count).to eq(2)
          expect(JSON.parse(last_response.body).first['team']).to eq('dev')
          expect(JSON.parse(last_response.body)[1]['team']).to eq('other')
        end
      end
    end

    describe 'id' do
      let!(:config_example) { Bosh::Director::Models::Config.make(id: 123, type: 'my-type', name: 'default', content: '1') }

      context 'with authenticated admin user' do
        before(:each) do
          authorize('admin', 'admin')
        end

        it 'it returns the specified config' do
          get('/123')

          expect(last_response.status).to eq(200)
          expect(JSON.parse(last_response.body)).to eq('id' => '123', 'type' => 'my-type', 'name' => 'default', 'content' => '1', 'created_at' => config_example.created_at.to_s, 'team' => nil)
        end

        context 'when no config is found' do
          it 'returns a 404' do
            get('/999')

            expect(last_response.status).to eq(404)
          end
        end

        context 'when `id` is not a valid database primary key type' do
          it 'returns a 404' do
            get('/invalidType!$_0')

            expect(last_response.status).to eq(404)
          end
        end
      end

      context 'without an authenticated user' do
        it 'denies access' do
          response = get('/my-fake-id')
          expect(response.status).to eq(401)
        end
      end

      context 'when user is reader' do
        before { basic_authorize('reader', 'reader') }

        it 'permits access' do
          expect(get('/123').status).to eq(200)
        end
      end
    end
  end
end


text:
'use strict';

const Handlebars = require('handlebars/dist/handlebars.runtime');
const PubSub = require('../utility/pubsub');

class View {
  constructor(container) {
    this._container = container;

    this._subscriptions = [];
    this._documentListeners = {};
    this._widgets = [];

    this._lastParams = null;
  }

  // tidy this up?
  get _el() {
    return this._container._el;
  }

  get lastParams() {
    return this._lastParams;
  }

  render(preRendered, params) {
    this.cleanup();

    if (!preRendered) {
      const template = Handlebars.template(this._container._templates[this._getTemplate()]);
      this._container.update(this, template(params));
    }

    this.initEvents(params);

    this._lastParams = params;
  }

  renderPartial(name, params) {
    console.log('render partial', name);

    const template = Handlebars.template(this._container._partials[name]);
    const view = this._el.querySelector('.partial-' + name);
    view.outerHTML = template(params);

    this._lastParams = params;

    return this._el.querySelector('.partial-' + name);
  }

  _getTemplate() {
    return this.constructor.name.toLowerCase().substring(4);
  }

  _addDocumentListener(name, type, fn) {
    if (!this._documentListeners[name]) {
      this._documentListeners[name] = {
        type,
        fn: fn.bind(this),
      };
    }

    document.addEventListener(type, this._documentListeners[name].fn);
  }

  cleanup() {
    // console.log('view cleaup', this);

    for (const sub of this._subscriptions) {
      PubSub.unsubscribe(sub);
    }

    for (const lname in this._documentListeners) {
      const listener = this._documentListeners[lname];
      document.removeEventListener(listener.type, listener.fn);
    }

    this.cleanupWidgets();
  }

  initEvents() {
    this.initWidgets(this._el);
  }

  registerWidget(Widget) {
    this._widgets.push(new Widget());
  }

  initWidgets(el) {
    this._widgets.forEach(widget => {
      widget.initEvents(el);
    });
  }

  cleanupWidgets() {
    this._widgets.forEach(widget => {
      widget.cleanup();
    });
  }

}

module.exports = View;


text:
import cloneDeep from 'lodash/cloneDeep'
import animateScrollTo from '../packages/animated-scroll-to'

export default {
    methods: {
        scrollOnLoad() {
            // scroll & click on prev selected item
            if (!this.no_files && this.currentFileIndex) {
                this.scrollToFile(this.getElementByIndex(this.currentFileIndex))
            }

            // scroll to breadcrumb item
            if (this.$refs.bc) {
                let folders = cloneDeep(this.folders).pop()
                this.scrollMobileBc(folders, this.$refs.bc)
            }
        },
        scrollToFile(file) {
            if (file) {
                file.click()

                // make sure scrolling fires
                setTimeout(this.scrollToSelected(file), 500)
            }
        },
        scrollToSelected(file) {
            return animateScrollTo(file, {
                speed: 150,
                maxDuration: 2000,
                offset: -20,
                element: this.$refs['__stack-files'].$el,
                useKeys: true
            })
        },
        scrollMobileBc(name, bc) {
            animateScrollTo(document.getElementById(`${name ? name : 'library'}-bc`), {
                speed: 150,
                maxDuration: 500,
                horizontal: true,
                element: bc.$el
            })
        },
        updateScrollByRow() {
            const fileslist = this.$refs.filesList
            const cont = fileslist || null

            if (cont) {
                let width = cont.clientWidth
                let pad = parseInt(window.getComputedStyle(cont).paddingLeft) + parseInt(window.getComputedStyle(cont).paddingRight)
                let contWidth = width - pad
                let itemWidth = fileslist.firstChild ? fileslist.firstChild.clientWidth : 0

                this.scrollByRowItemsCount = Math.floor(contWidth / itemWidth)
            }
        }
    }
}


text:
(function (bingo) {
    //version 1.0.1
    "use strict";
    var undefined;

    var _loadedJS = [], //已经加载的js
        _loadingJS = [], //加载中的js
        _squareJS = [], //预备的js
        _loadingCallback = [[],[]]; //加载中的callback

    var _inArray = function (element, list) {
        return bingo.inArray(function (item) { return bingo.isStringEquals(item, element); }, list);
    };

    var _hasJS = function (js) {
        return (_inArray(js, _loadedJS) >= 0
            || _inArray(js, _loadingJS) >= 0
            || _inArray(js, _squareJS) >= 0);
    };

    var _loadFun = function (jsList, callback, pos) {
        !bingo.isNumeric(pos) && (pos = bingo.usingPriority.Normal);

        _makeNeedList(jsList);

        _loadingCallback[pos] || (_loadingCallback[pos] = []);

        _loadingCallback[pos].push(callback);
        if (_squareJS.length > 0) {
            _loadJS();
        } else {
            //如果没有js, 或js已经加载
            setTimeout(function () {
                if (_isLoadEnd())
                    _endDone();
            }, 1);
        }
        //callback = jsList = null;
    },
    _makeNeedList = function (jsList) {
        var pathTemp = bingo.stringEmpty;
        bingo.each(jsList, function (pathItem) {
            if (bingo.isNull(pathItem)) return;
            pathTemp = bingo.route(pathItem);

            //路由
            pathTemp = _getMapPath(pathTemp);
            //如里有prdtVersion, 添加prdtVersion, query
            if (!bingo.supportWorkspace && !bingo.isNullEmpty(bingo.prdtVersion))
                pathTemp = [pathTemp, pathTemp.indexOf('?') >= 0 ? '&' : '?', '_version_=', bingo.prdtVersion].join('');

            //js文件是否已经存在
            if (!_hasJS(pathTemp)) {
                _squareJS.push(pathTemp); //加入预备
            }

        });
    };
    //var _isloading = false;
    var _loadJS = function () {
        //console.log("_loadJS", _squareJS, _loadingJS, _loadedJS);
        if (_squareJS.length > 0) {
            var squareJSTemp = _squareJS;
            _squareJS = [];//清空_squareJS
            bingo.each(squareJSTemp, function (path) {
                _loadingJS.push(path);//放入_loadingJS
                bingo.fetch(path, _fetchCallback);
            });
        }
    };
    var _isLoadEnd = function () {
        return (_squareJS.length <= 0 && _loadingJS.length <= 0);
    };
    var _fetchTimeId = undefined;
    var _fetchCallback = function (url, id) {
        _loadedJS.push(url);//放入_loadedJS
        _loadingJS = bingo.removeArrayItem(url, _loadingJS);//从_loadingJS删除

        if (_fetchTimeId != undefined)
            clearTimeout(_fetchTimeId);
        _fetchTimeId = setTimeout(function () {
            _fetchTimeId = undefined;
            if (_isLoadEnd()) {
                _endDone();
            }
        }, 5);

    };
    var _endDone = function () {
        var isAllDone = true;
        bingo.each(_loadingCallback, function (item , pos) {
            var loadingCallbackTemp = _loadingCallback[pos];//.reverse();
            _loadingCallback[pos] = [];
            bingo.each(loadingCallbackTemp, function (callback) {
                if (bingo.isFunction(callback))
                    callback();
            });
            if (_loadingCallback[pos].length > 0) {
                isAllDone = false;
                return false;
            }
        });

        //如果没有全部运行
        if (!isAllDone) {
            //如果加载完成, 没有新的js加载
            if (_isLoadEnd()) {
                _endDone();
            }
        }
    };

    //map========================================
    var _mapList = [],    //{path:"", mapPath:""}
        _createMapItem = function (mapPath, path) {
            return { path: path, mapPath: mapPath, pathReg: _makeRegexMapPath(path) };
        },
        _addMap = function (mapPath, path) {

            mapPath = bingo.route(mapPath);
            path = bingo.route(path);

            var oldmap = _getMap(path);
            if (bingo.isNull(oldmap)) {
                _mapList.push(_createMapItem(mapPath, path));
            } else {
                oldmap.mapPath = mapPath;
            }
        },
        _getMap = function (path, checkReg) {
            var index = bingo.inArray(function (item) {
                if (checkReg === true && item.pathReg) {
                    item.pathReg.lastIndex = 0;
                    return item.pathReg.test(path);
                }
                else
                    return bingo.isStringEquals(item.path, path);
            }, _mapList);
            return index >= 0 ? _mapList[index] : null;
        },
        _getMapPath = function (path) {
            var mapItem = _getMap(path, true);
            return (mapItem && mapItem.mapPath) || path;
        };

    //makeRegexMapPath
    var _makeRegexPath = /(\W)/g,
        _makeRegexPathSS = /(\\([?*]))/g,//查找 ?和*符号
        _makeRegexPathAll = /\\\*\\\*/g,//查找 ?和*符号
        _urlQueryPart = /\?[^?=]+\=.*$/,//查找query部分, ?aaa=111&b=222
        _hasRegPath = /[?*]+/,
        _isRegexMapPath = function (path) {
            return (!bingo.isNullEmpty(path)
                    && _hasRegPath.test(path.replace(_urlQueryPart, '')));
        }, _makeRegexMapPath = function (path) {
            if (!_isRegexMapPath(path)) return null;

            //去除query部分/aaa/ssss.?js?aaa=dfsdf  ==结果==> /aa?a/ssss.?js
            var query = path.match(_urlQueryPart);
            if (query) {
                //如果查找到返回数组:[''], 如果没有返回null
                query = query[0];
                path = path.replace(query, '');
                query = query.replace(_makeRegexPath, "\\$1");
            } else
                query = '';

            _makeRegexPath.lastIndex = 0;
            _makeRegexPathSS.lastIndex = 0;
            _makeRegexPathAll.lastIndex = 0;
            var regS = path.replace(_makeRegexPath, "\\$1").replace(_makeRegexPathAll, '.*').replace(_makeRegexPathSS, '[^./\]$2');
            regS = ['^', regS, query, '$'].join('');
            return new RegExp(regS);
        };

    bingo.extend({
        using: function () {
            if (arguments.length <= 0) return;
            var jsList = [];
            var callback = null;
            var pos = 0;

            var item = null;
            for (var i = 0, len = arguments.length; i < len; i++) {
                item = arguments[i];
                if (item) {
                    if (bingo.isFunction(item))
                        callback = item;
                    else if (bingo.isNumeric(item))
                        pos = item;
                    else
                        jsList = jsList.concat(item);
                }
            }
            _loadFun(jsList, function () {
                callback && callback();
            }, pos);
        },
        makeRegexMapPath: _makeRegexMapPath,
        isRegexMapPath: _isRegexMapPath,
        usingMap: function (mapPath, paths) {
            if (bingo.isNullEmpty(mapPath) || !paths || paths.length <= 0) return;

            bingo.each(paths, function (item, index) {
                if (bingo.isNullEmpty(item)) return;
                _addMap(mapPath, item);
            });
        },
        usingPriority: {
            First: 0,
            NormalBefore: 45,
            Normal: 50,
            NormalAfter: 55,
            Last: 100
        },
        path: function (a) {
            if (this.isObject(a)) {
                this.extend(_paths, a);
            } else {
                if (arguments.length > 1) {
                    _paths[arguments[0]] = arguments[1];
                } else {
                    var urls = a.split('?');
                    a = urls[0];
                    a = _makePath(a);
                    if (urls.length > 1)
                        a += ('?' + bingo.sliceArray(urls, 1).join('?'));
                    return a;
                }
            }
        }
    });

    var _paths = {}, _makePathMatch = /%([^%]*)%/i,
    _makePath = function (path) {
        if (bingo.isNullEmpty(path) || path.indexOf("%") < 0) return path;
        var query = '';
        if (path.indexOf('?')) {
            var pList = path.split('?');
            path = pList[0];
            query = pList[1];
        }

        _makePathMatch.lastIndex = 0;
        var pathRegx = path.match(_makePathMatch);
        var pathReturn = bingo.stringEmpty;
        var pathConfig = _paths;
        if (pathRegx) {
            if (pathConfig[pathRegx[1]])
                pathReturn = _makePath(path.replace(pathRegx[0], pathConfig[pathRegx[1]]));
            else
                pathReturn = _makePath(path.replace(pathRegx[0], bingo.stringEmpty));
        }
        pathRegx = null;
        pathConfig = null;
        return !query ? pathReturn : [pathReturn, query].join('?');
    };

})(bingo);


text:
/*
 * American Data Fest 2013
 * ITESM Chihuahua
 * Chihuahua, Chihuahua Mexico
 * November 2013
 * SOS Latino California Edition
 * Team: Urban Jungle
 *
 * Designer:
 *  Fernanda Gonzalez Jaquez (s.fernandagonzalez@gmail.com)
 *
 *Developers:
 *
 * Luis Fernando Mata Lic—n (wisimata@gmail.com)
 *
 * Jorge Arturo Alejos Loya (A00758689@itesm.mx)
 *
 * Gerardo Anselmo Torres PŽrez (chemoatp@gmail.com)
 *
 * David Alejandro JimŽnez Jaramillo (himie.las@gmail.com)
 *
 */

package com.urbanjungle.survivalguide101;

import com.urbanjungle.survivalguide101.R;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

/*
 * This class implements the City Home, that works as the main view of the app.
 * Here the user can choose between, any of the principal items of the app or to see
 * their bookmarks.
 */
public class Home extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_home);
		// Here we get the city we're right know
		final String ciudad = getIntent().getStringExtra("Ciudad");
		LinearLayout linearLayout = (LinearLayout) findViewById(R.id.LinearLayout2);
		linearLayout.setBackgroundResource(R.drawable.fondociudades);

		int city = Integer.parseInt(ciudad);

		//Here we select the banner for each city
		ImageView banner = (ImageView) findViewById(R.id.imgBanner);
		switch (city) {
		case 1:
			banner.setImageResource(R.drawable.headerla);
			break;
		case 2:
			banner.setImageResource(R.drawable.headersf);
			break;
		default:
			break;
		}

		/*
		 * Here we populate the array of elements for the ListView
		 * For the rows of the ListView we use the item RenglonImagen
		 * that is a row that uses a Image as element.
		 */
		RenglonImagen[] arrayOfElementos = new RenglonImagen[5];

		RenglonImagen transp = new RenglonImagen("btnmapa");
		arrayOfElementos[0] = transp;
		RenglonImagen ong = new RenglonImagen("btnasistencia");
		arrayOfElementos[1] = ong;
		RenglonImagen salud = new RenglonImagen("btnsalud");
		arrayOfElementos[2] = salud;
		RenglonImagen traducc = new RenglonImagen("btntraduccion");
		arrayOfElementos[3] = traducc;
		RenglonImagen bookmarks = new RenglonImagen("btnbookmarks");
		arrayOfElementos[4] = bookmarks;

		//Here we populate the custom adapter in order to populate the ListView
		RenglonImagenAdapter adaptador = new RenglonImagenAdapter(this);
		for (int i = 0; i < arrayOfElementos.length; i++) {
			adaptador.add(arrayOfElementos[i]);
		}

		ListView listView = (ListView) findViewById(R.id.lstHome);
		listView.setAdapter(adaptador);

		listView.setDivider(null);
		listView.setDividerHeight(0);

		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> a, View v, int position,
					long id) {

				String datosEnviar = "" + id;

				/*
				 * Here we send basic information to the views of the different data
				 * "Ciudad" .- Sends informationa about the city we are at the moment (1.- LA, 2.- SF)
				 * "Type".- Type of data that was requested
				 * "Nombre".- Sends information to setting Titles and searching on databases
				 */

				switch (position) {
				case 0:
					Intent Int0 = new Intent(Home.this, Mapas.class);
					Int0.putExtra("Ciudad", ciudad);
					startActivity(Int0);
					break;
				case 1:
					Intent Int1 = new Intent(Home.this, Asistencia.class);
					Int1.putExtra("Nombre", "Asistencia");
					Int1.putExtra("Ciudad", ciudad);
					startActivity(Int1);
					break;
				case 2:
					Intent Int2 = new Intent(Home.this, Salud.class);
					datosEnviar = "" + 0;
					Int2.putExtra("Type", datosEnviar);
					Int2.putExtra("Ciudad", ciudad);
					startActivity(Int2);
					break;
				case 3:
					Intent Int3 = new Intent(Home.this,
							ListarTraducciones.class);
					startActivity(Int3);
					break;
				case 4:
					Intent Int4 = new Intent(Home.this, ListarBookmarks.class);
					Int4.putExtra("Ciudad", ciudad);
					startActivity(Int4);
					break;
				default:
					break;
				}

			}
		});

		//Return button to the cities activity
		ImageView regresar = (ImageView) findViewById(R.id.imgReturn);
		regresar.setClickable(true);
		regresar.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {

				finish();
			}
		});

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.home, menu);
		return true;
	}

}


text:
namespace {

class NetworkProfileBubbleView : public views::BubbleDialogDelegateView {
 public:
  METADATA_HEADER(NetworkProfileBubbleView);
  NetworkProfileBubbleView(views::View* anchor,
                           content::PageNavigator* navigator,
                           Profile* profile);
  NetworkProfileBubbleView(const NetworkProfileBubbleView&) = delete;
  NetworkProfileBubbleView& operator=(const NetworkProfileBubbleView&) = delete;

 private:
  ~NetworkProfileBubbleView() override;

  // views::BubbleDialogDelegateView:
  void Init() override;
  bool Accept() override;

  void LinkClicked(const ui::Event&);

  // Used for loading pages.
  raw_ptr<content::PageNavigator> navigator_;
  raw_ptr<Profile> profile_;
};

////////////////////////////////////////////////////////////////////////////////
// NetworkProfileBubbleView, public:

NetworkProfileBubbleView::NetworkProfileBubbleView(
    views::View* anchor,
    content::PageNavigator* navigator,
    Profile* profile)
    : BubbleDialogDelegateView(anchor, views::BubbleBorder::TOP_RIGHT),
      navigator_(navigator),
      profile_(profile) {
  SetButtons(ui::DIALOG_BUTTON_OK);
  auto* learn_more = SetExtraView(
      std::make_unique<views::Link>(l10n_util::GetStringUTF16(IDS_LEARN_MORE)));
  learn_more->SetCallback(base::BindRepeating(
      &NetworkProfileBubbleView::LinkClicked, base::Unretained(this)));
  chrome::RecordDialogCreation(
      chrome::DialogIdentifier::NETWORK_SHARE_PROFILE_WARNING);
}

////////////////////////////////////////////////////////////////////////////////
// NetworkProfileBubbleView, private:

NetworkProfileBubbleView::~NetworkProfileBubbleView() {
}

void NetworkProfileBubbleView::Init() {
  SetLayoutManager(std::make_unique<views::FillLayout>());
  views::Label* label = new views::Label(
      l10n_util::GetStringFUTF16(IDS_PROFILE_ON_NETWORK_WARNING,
          l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
  label->SetMultiLine(true);
  constexpr int kNotificationBubbleWidth = 250;
  label->SizeToFit(kNotificationBubbleWidth);
  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  AddChildView(label);
}

bool NetworkProfileBubbleView::Accept() {
  NetworkProfileBubble::RecordUmaEvent(
      NetworkProfileBubble::METRIC_ACKNOWLEDGED);
  return true;
}

void NetworkProfileBubbleView::LinkClicked(const ui::Event& event) {
  NetworkProfileBubble::RecordUmaEvent(
      NetworkProfileBubble::METRIC_LEARN_MORE_CLICKED);
  WindowOpenDisposition disposition = ui::DispositionFromEventFlags(
      event.flags(), WindowOpenDisposition::NEW_FOREGROUND_TAB);
  content::OpenURLParams params(
      GURL("https://sites.google.com/a/chromium.org/dev/administrators/"
           "common-problems-and-solutions#network_profile"),
      content::Referrer(), disposition, ui::PAGE_TRANSITION_LINK, false);
  navigator_->OpenURL(params);

  // If the user interacted with the bubble we don't reduce the number of
  // warnings left.
  PrefService* prefs = profile_->GetPrefs();
  int left_warnings = prefs->GetInteger(prefs::kNetworkProfileWarningsLeft);
  prefs->SetInteger(prefs::kNetworkProfileWarningsLeft, ++left_warnings);
  GetWidget()->Close();
}

BEGIN_METADATA(NetworkProfileBubbleView, views::BubbleDialogDelegateView)
END_METADATA

}  // namespace

// static
void NetworkProfileBubble::ShowNotification(Browser* browser) {
  views::View* anchor = NULL;
  BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
  if (browser_view && browser_view->toolbar())
    anchor = browser_view->toolbar_button_provider()->GetAppMenuButton();
  NetworkProfileBubbleView* bubble =
      new NetworkProfileBubbleView(anchor, browser, browser->profile());
  views::BubbleDialogDelegateView::CreateBubble(bubble)->Show();

  NetworkProfileBubble::SetNotificationShown(true);

  // Mark the time of the last bubble and reduce the number of warnings left
  // before the next silence period starts.
  PrefService* prefs = browser->profile()->GetPrefs();
  prefs->SetInt64(prefs::kNetworkProfileLastWarningTime,
                  base::Time::Now().ToTimeT());
  int left_warnings = prefs->GetInteger(prefs::kNetworkProfileWarningsLeft);
  if (left_warnings > 0)
    prefs->SetInteger(prefs::kNetworkProfileWarningsLeft, --left_warnings);
}


text:
layout: text/textblock
---

The service design and delivery process is an agile approach with 4 stages:
- [Discovery stage](../discovery-stage/) — the team gets a deep understanding of the users and their needs, and developing hypotheses to solve the problems
- [Alpha stage](../alpha-stage) — the team builds prototypes to test the hypotheses
- [Beta stage](../beta-stage) — the team builds and tests a solution based on the hypotheses validated in Alpha
- [Live stage](../live-stage) — the team is changed to maintain and improve the service

The stages build on each other but they don't always go in order. Sometimes a service might go back to an earlier stage (for example, if a service in Beta needs to go back to Discovery to work on a different problem).


text:
#!/bin/sh -e

#  FLAC - Free Lossless Audio Codec
#  Copyright (C) 2002-2009  Josh Coalson
#  Copyright (C) 2011-2014  Xiph.Org Foundation
#
#  This file is part the FLAC project.  FLAC is comprised of several
#  components distributed under different licenses.  The codec libraries
#  are distributed under Xiph.Org's BSD-like license (see the file
#  COPYING.Xiph in this distribution).  All other programs, libraries, and
#  plugins are distributed under the GPL (see COPYING.GPL).  The documentation
#  is distributed under the Gnu FDL (see COPYING.FDL).  Each file in the
#  FLAC distribution contains at the top the terms under which it may be
#  distributed.
#
#  Since this particular file is relevant to all components of FLAC,
#  it may be distributed under the Xiph.Org license, which is the least
#  restrictive of those mentioned above.  See the file COPYING.Xiph in this
#  distribution.

. ./common.sh

PATH=`pwd`/../src/flac:$PATH
PATH=`pwd`/../src/metaflac:$PATH
PATH=`pwd`/../objs/$BUILD/bin:$PATH

if echo a | (grep -E '(a|b)') >/dev/null 2>&1
	then EGREP='grep -E'
	else EGREP='egrep'
fi

testdir="metaflac-test-files"
flacfile="replaygain.flac"

run_flac ()
{
	if [ x"$FLAC__TEST_WITH_VALGRIND" = xyes ] ; then
		echo "valgrind --leak-check=yes --show-reachable=yes --num-callers=50 flac $*" >>test_replaygain.valgrind.log
		valgrind --leak-check=yes --show-reachable=yes --num-callers=50 --log-fd=4 flac --no-error-on-compression-fail $* 4>>test_replaygain.valgrind.log
	else
		flac${EXE} --no-error-on-compression-fail $*
	fi
}

run_metaflac ()
{
	if [ x"$FLAC__TEST_WITH_VALGRIND" = xyes ] ; then
		echo "valgrind --leak-check=yes --show-reachable=yes --num-callers=50 metaflac $*" >>test_replaygain.valgrind.log
		valgrind --leak-check=yes --show-reachable=yes --num-callers=50 --log-fd=4 metaflac $* 4>>test_replaygain.valgrind.log
	else
		metaflac${EXE} $*
	fi
}

run_metaflac_silent ()
{
	if [ -z "$SILENT" ] ; then
		run_metaflac $*
	else
		if [ x"$FLAC__TEST_WITH_VALGRIND" = xyes ] ; then
			echo "valgrind --leak-check=yes --show-reachable=yes --num-callers=50 metaflac $*" >>test_replaygain.valgrind.log
			valgrind --leak-check=yes --show-reachable=yes --num-callers=50 --log-fd=4 metaflac $* 2>/dev/null 4>>test_replaygain.valgrind.log
		else
			metaflac${EXE} $* 2>/dev/null
		fi
	fi
}

check_flac ()
{
	run_flac --silent --test $flacfile || die "ERROR in $flacfile" 1>&2
}

echo "Generating stream..."
bytes=80000
if dd if=/dev/zero ibs=1 count=$bytes | flac${EXE} --force --verify -0 --input-size=$bytes --output-name=$flacfile --force-raw-format --endian=big --sign=signed --channels=1 --bps=8 --sample-rate=8000 - ; then
	chmod +w $flacfile
else
	die "ERROR during generation"
fi

check_flac

if mawk ; then
	AWK=mawk
else
	# Really hope awk is not gawk, because the following AWK script doesn't
	# work correctly with gawk 4.0.1 but did with earlier versions.
	AWK=awk
	fi

# Replay gain tests - Test the rates which have specific filter table entries
# and verify that harmonics can be processed correctly.

tonegenerator ()
{
	# When using GAWK, use --lint=posix to identify non-POSIX awk usages.
    $AWK -- '
    BEGIN {
            samplerate = '$1';

            tone = 1000;
            duration = 1;
            bitspersample = 24;

            samplemidpoint = 1;
			for (sps = 0 ; sps < bitspersample - 1 ; sps++) {
				samplemidpoint *= 2;
			}

            samplerange = samplemidpoint - 1;

            pi = 4 * atan2(1,1);

            for (ix = 0; ix < duration * samplerate; ++ix) {
                    sample = sin(2 * pi * tone * ix / samplerate);
                    sample *= samplerange;
                    sample += samplemidpoint;
                    sample = int(sample);
                    for (bx = 0; bx < bitspersample/8; ++bx) {
                            byte[bx] = sample % 256;
                            sample /= 256;
                    }
                    while (bx--) {
                            printf("%c", byte[bx]);
                    }
            }

    }' /dev/null |
    flac${EXE} --silent --no-error-on-compression-fail --force-raw-format \
        --endian=big --channels=1 --bps=24 --sample-rate=$1 --sign=unsigned -
}

REPLAYGAIN_FREQ=
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ  8000/-12.76"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 11025/-12.93"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 12000/-13.00"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 16000/-13.29"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 18900/-13.43"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 22050/-13.77"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 24000/-13.83"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 28000/-14.06"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 32000/-14.08"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 36000/-14.12"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 37800/-14.18"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 44100/-14.17"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 48000/-14.16:1:2:4"

set -e

for ACTION in $REPLAYGAIN_FREQ ; do
  if [ -n "${ACTION##*:*}" ] ; then
    HARMONICS=1
  else
    HARMONICS="${ACTION#*:}"
  fi
  FREQ="${ACTION%%/*}"
  GAIN="${ACTION#*/}"
  GAIN="${GAIN%%:*}"
  while [ -n "$HARMONICS" ] ; do
    MULTIPLE="${HARMONICS%%:*}"
    if [ x"$MULTIPLE" = x"$HARMONICS" ] ; then
      HARMONICS=
    else
      HARMONICS="${HARMONICS#*:}"
    fi
    RATE=$(($MULTIPLE * FREQ))
    [ $MULTIPLE -eq 1 -o -n "${REPLAYGAIN_FREQ##* $RATE/*}" ] || break
    echo -n "Testing FLAC replaygain $RATE ($FREQ x $MULTIPLE) ... "
    tonegenerator $RATE > $flacfile
    run_metaflac --add-replay-gain $flacfile
    run_metaflac --list $flacfile | grep REPLAYGAIN.*GAIN= |
    while read -r REPLAYGAIN ; do
      MEASUREDGAIN="${REPLAYGAIN##*=}"
      MEASUREDGAIN="${MEASUREDGAIN%% *}"
      if [ x"$MEASUREDGAIN" != x"$GAIN" ] ; then
        die "ERROR, Expected $GAIN db instead of $REPLAYGAIN"
      fi
    done
    echo OK
  done
done

rm -f $testdir/out.flac $testdir/out.meta

exit 0