text:
package typescriptify

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"reflect"
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

type Address struct {
	// Used in html
	Duration float64 `json:"duration"`
	Text1    string  `json:"text,omitempty"`
	// Ignored:
	Text2 string `json:",omitempty"`
	Text3 string `json:"-"`
}

type Dummy struct {
	Something string `json:"something"`
}

type HasName struct {
	Name string `json:"name"`
}

type Person struct {
	HasName
	Nicknames []string  `json:"nicknames"`
	Addresses []Address `json:"addresses"`
	Address   *Address  `json:"address"`
	Metadata  string    `json:"metadata" ts_type:"{[key:string]:string}" ts_transform:"JSON.parse(__VALUE__ || \"{}\")"`
	Friends   []*Person `json:"friends"`
	Dummy     Dummy     `json:"a"`
}

func TestTypescriptifyWithTypes(t *testing.T) {
	t.Parallel()
	converter := New()

	converter.AddType(reflect.TypeOf(Person{}))
	converter.CreateConstructor = false
	converter.BackupDir = ""

	desiredResult := `export class Dummy {
        something: string;
}
export class Address {
        duration: number;
        text?: string;
}
export class Person {
        name: string;
        nicknames: string[];
		addresses: Address[];
		address?: Address;
		metadata: {[key:string]:string};
		friends: Person[];
        a: Dummy;
}`
	testConverter(t, converter, false, desiredResult, nil)
}

func TestTypescriptifyWithCustomImports(t *testing.T) {
	t.Parallel()
	converter := New()

	converter.AddType(reflect.TypeOf(Person{}))
	converter.BackupDir = ""
	converter.AddImport("//import { Decimal } from 'decimal.js'")
	converter.CreateConstructor = false

	desiredResult := `
//import { Decimal } from 'decimal.js'

export class Dummy {
        something: string;
}
export class Address {
        duration: number;
        text?: string;
}
export class Person {
        name: string;
        nicknames: string[];
		addresses: Address[];
		address?: Address;
		metadata: {[key:string]:string};
		friends: Person[];
        a: Dummy;
}`
	testConverter(t, converter, false, desiredResult, nil)
}

func TestTypescriptifyWithInstances(t *testing.T) {
	t.Parallel()
	converter := New()

	converter.Add(Person{})
	converter.Add(Dummy{})
	converter.DontExport = true
	converter.BackupDir = ""
	converter.CreateConstructor = false

	desiredResult := `class Dummy {
        something: string;
}
class Address {
        duration: number;
        text?: string;
}
class Person {
        name: string;
        nicknames: string[];
		addresses: Address[];
		address?: Address;
		metadata: {[key:string]:string};
		friends: Person[];
        a: Dummy;
}`
	testConverter(t, converter, false, desiredResult, nil)
}

func TestTypescriptifyWithInterfaces(t *testing.T) {
	t.Parallel()
	converter := New()

	converter.Add(Person{})
	converter.Add(Dummy{})
	converter.DontExport = true
	converter.BackupDir = ""
	converter.CreateInterface = true

	desiredResult := `interface Dummy {
        something: string;
}
interface Address {
        duration: number;
        text?: string;
}
interface Person {
        name: string;
        nicknames: string[];
		addresses: Address[];
		address?: Address;
		metadata: {[key:string]:string};
		friends: Person[];
        a: Dummy;
}`
	testConverter(t, converter, true, desiredResult, nil)
}

func TestTypescriptifyWithDoubleClasses(t *testing.T) {
	t.Parallel()
	converter := New()

	converter.AddType(reflect.TypeOf(Person{}))
	converter.AddType(reflect.TypeOf(Person{}))
	converter.CreateConstructor = false
	converter.BackupDir = ""

	desiredResult := `export class Dummy {
        something: string;
}
export class Address {
        duration: number;
        text?: string;
}
export class Person {
        name: string;
		nicknames: string[];
		addresses: Address[];
		address?: Address;
		metadata: {[key:string]:string};
		friends: Person[];
        a: Dummy;
}`
	testConverter(t, converter, false, desiredResult, nil)
}

func TestWithPrefixes(t *testing.T) {
	t.Parallel()
	converter := New()

	converter.Prefix = "test_"
	converter.Suffix = "_test"

	converter.Add(Person{})
	converter.DontExport = true
	converter.BackupDir = ""

	desiredResult := `class test_Dummy_test {
	something: string;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.something = source["something"];
    }
}
class test_Address_test {
    duration: number;
	text?: string;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.duration = source["duration"];
        this.text = source["text"];
    }
}
class test_Person_test {
    name: string;
    nicknames: string[];
    addresses: test_Address_test[];
    address?: test_Address_test;
    metadata: {[key:string]:string};
    friends: test_Person_test[];
	a: test_Dummy_test;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.name = source["name"];
        this.nicknames = source["nicknames"];
        this.addresses = this.convertValues(source["addresses"], test_Address_test);
        this.address = this.convertValues(source["address"], test_Address_test);
		this.metadata = JSON.parse(source["metadata"] || "{}");
		this.friends = this.convertValues(source["friends"], test_Person_test);
		this.a = this.convertValues(source["a"], test_Dummy_test);
    }

	` + tsConvertValuesFunc + `
}`
	jsn := jsonizeOrPanic(Person{
		Address:   &Address{Text1: "txt1"},
		Addresses: []Address{{Text1: "111"}},
		Metadata:  `{"something": "aaa"}`,
	})
	testConverter(t, converter, true, desiredResult, []string{
		`new test_Person_test()`,
		`JSON.stringify(new test_Person_test()?.metadata) === "{}"`,
		`!(new test_Person_test()?.address)`,
		`!(new test_Person_test()?.addresses)`,
		`!(new test_Person_test()?.addresses)`,

		`new test_Person_test(` + jsn + ` as any)`,
		`new test_Person_test(` + jsn + ` as any)?.metadata?.something === "aaa"`,
		`(new test_Person_test(` + jsn + ` as any)?.address as test_Address_test).text === "txt1"`,
		`new test_Person_test(` + jsn + ` as any)?.addresses?.length === 1`,
		`(new test_Person_test(` + jsn + ` as any)?.addresses[0] as test_Address_test)?.text === "111"`,
	})
}

func testConverter(t *testing.T, converter *TypeScriptify, strictMode bool, desiredResult string, tsExpressionAndDesiredResults []string) {
	typeScriptCode, err := converter.Convert(nil)
	if err != nil {
		panic(err.Error())
	}

	fmt.Println("----------------------------------------------------------------------------------------------------")
	fmt.Println(desiredResult)
	fmt.Println("----------------------------------------------------------------------------------------------------")
	fmt.Println(typeScriptCode)
	fmt.Println("----------------------------------------------------------------------------------------------------")

	desiredResult = strings.TrimSpace(desiredResult)
	typeScriptCode = strings.Trim(typeScriptCode, " \t\n\r")
	if typeScriptCode != desiredResult {
		gotLines1 := strings.Split(typeScriptCode, "\n")
		expectedLines2 := strings.Split(desiredResult, "\n")

		max := len(gotLines1)
		if len(expectedLines2) > max {
			max = len(expectedLines2)
		}

		for i := 0; i < max; i++ {
			var gotLine, expectedLine string
			if i < len(gotLines1) {
				gotLine = gotLines1[i]
			}
			if i < len(expectedLines2) {
				expectedLine = expectedLines2[i]
			}
			if assert.Equal(t, strings.TrimSpace(expectedLine), strings.TrimSpace(gotLine), "line #%d", 1+i) {
				fmt.Printf("OK:       %s\n", gotLine)
			} else {
				t.FailNow()
			}
		}
	}

	if t.Failed() {
		t.FailNow()
	}

	testTypescriptExpression(t, strictMode, typeScriptCode, tsExpressionAndDesiredResults)
}

func testTypescriptExpression(t *testing.T, strictMode bool, baseScript string, tsExpressionAndDesiredResults []string) {
	f, err := ioutil.TempFile(os.TempDir(), "*.ts")
	assert.Nil(t, err)
	assert.NotNil(t, f)

	_, _ = f.WriteString(baseScript)
	_, _ = f.WriteString("\n")
	for n, expr := range tsExpressionAndDesiredResults {
		_, _ = f.WriteString("// " + expr + "\n")
		_, _ = f.WriteString(`if (` + expr + `) { console.log("#` + fmt.Sprint(1+n) + ` OK") } else { throw new Error() }`)
		_, _ = f.WriteString("\n\n")
	}

	fmt.Println("tmp ts: ", f.Name())
	var byts []byte
	if strictMode {
		byts, err = exec.Command("tsc", "--strict", f.Name()).CombinedOutput()
	} else {
		byts, err = exec.Command("tsc", f.Name()).CombinedOutput()
	}
	assert.Nil(t, err, string(byts))

	jsFile := strings.Replace(f.Name(), ".ts", ".js", 1)
	fmt.Println("executing:", jsFile)
	byts, err = exec.Command("node", jsFile).CombinedOutput()
	assert.Nil(t, err, string(byts))
}

func TestTypescriptifyCustomType(t *testing.T) {
	t.Parallel()
	type TestCustomType struct {
		Map map[string]int `json:"map" ts_type:"{[key: string]: number}"`
	}

	converter := New()

	converter.AddType(reflect.TypeOf(TestCustomType{}))
	converter.BackupDir = ""
	converter.CreateConstructor = false

	desiredResult := `export class TestCustomType {
        map: {[key: string]: number};
}`
	testConverter(t, converter, false, desiredResult, nil)
}

func TestDate(t *testing.T) {
	t.Parallel()
	type TestCustomType struct {
		Time time.Time `json:"time" ts_type:"Date" ts_transform:"new Date(__VALUE__)"`
	}

	converter := New()
	converter.AddType(reflect.TypeOf(TestCustomType{}))
	converter.BackupDir = ""

	desiredResult := `export class TestCustomType {
	time: Date;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.time = new Date(source["time"]);
    }
}`

	jsn := jsonizeOrPanic(TestCustomType{Time: time.Date(2020, 10, 9, 8, 9, 0, 0, time.UTC)})
	testConverter(t, converter, true, desiredResult, []string{
		`new TestCustomType(` + jsonizeOrPanic(jsn) + `).time instanceof Date`,
		//`console.log(new TestCustomType(` + jsonizeOrPanic(jsn) + `).time.toJSON())`,
		`new TestCustomType(` + jsonizeOrPanic(jsn) + `).time.toJSON() === "2020-10-09T08:09:00.000Z"`,
	})
}

func TestDateWithoutTags(t *testing.T) {
	t.Parallel()
	type TestCustomType struct {
		Time time.Time `json:"time"`
	}

	// Test with custom field options defined per-one-struct:
	converter1 := New()
	converter1.Add(NewStruct(TestCustomType{}).WithFieldOpts(time.Time{}, TypeOptions{TSType: "Date", TSTransform: "new Date(__VALUE__)"}))
	converter1.BackupDir = ""

	// Test with custom field options defined globally:
	converter2 := New()
	converter2.Add(reflect.TypeOf(TestCustomType{}))
	converter2.ManageType(time.Time{}, TypeOptions{TSType: "Date", TSTransform: "new Date(__VALUE__)"})
	converter2.BackupDir = ""

	for _, converter := range []*TypeScriptify{converter1, converter2} {
		desiredResult := `export class TestCustomType {
	time: Date;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.time = new Date(source["time"]);
    }
}`

		jsn := jsonizeOrPanic(TestCustomType{Time: time.Date(2020, 10, 9, 8, 9, 0, 0, time.UTC)})
		testConverter(t, converter, true, desiredResult, []string{
			`new TestCustomType(` + jsonizeOrPanic(jsn) + `).time instanceof Date`,
			//`console.log(new TestCustomType(` + jsonizeOrPanic(jsn) + `).time.toJSON())`,
			`new TestCustomType(` + jsonizeOrPanic(jsn) + `).time.toJSON() === "2020-10-09T08:09:00.000Z"`,
		})
	}
}

func TestRecursive(t *testing.T) {
	t.Parallel()
	type Test struct {
		Children []Test `json:"children"`
	}

	converter := New()

	converter.AddType(reflect.TypeOf(Test{}))
	converter.BackupDir = ""

	desiredResult := `export class Test {
	children: Test[];

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.children = this.convertValues(source["children"], Test);
    }

	` + tsConvertValuesFunc + `
}`
	testConverter(t, converter, true, desiredResult, nil)
}

func TestArrayOfArrays(t *testing.T) {
	t.Parallel()
	type Key struct {
		Key string `json:"key"`
	}
	type Keyboard struct {
		Keys [][]Key `json:"keys"`
	}

	converter := New()

	converter.AddType(reflect.TypeOf(Keyboard{}))
	converter.BackupDir = ""

	desiredResult := `export class Key {
	key: string;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.key = source["key"];
    }
}
export class Keyboard {
    keys: Key[][];

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.keys = this.convertValues(source["keys"], Key);
    }

	` + tsConvertValuesFunc + `
}`
	testConverter(t, converter, true, desiredResult, nil)
}

func TestFixedArray(t *testing.T) {
	t.Parallel()
	type Sub struct{}
	type Tmp struct {
		Arr  [3]string `json:"arr"`
		Arr2 [3]Sub    `json:"arr2"`
	}

	converter := New()

	converter.AddType(reflect.TypeOf(Tmp{}))
	converter.BackupDir = ""

	desiredResult := `export class Sub {

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);

    }
}
export class Tmp {
    arr: string[];
    arr2: Sub[];

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.arr = source["arr"];
        this.arr2 = this.convertValues(source["arr2"], Sub);
    }

	` + tsConvertValuesFunc + `
}
`
	testConverter(t, converter, true, desiredResult, nil)
}

func TestAny(t *testing.T) {
	t.Parallel()
	type Test struct {
		Any interface{} `json:"field"`
	}

	converter := New()

	converter.AddType(reflect.TypeOf(Test{}))
	converter.BackupDir = ""

	desiredResult := `export class Test {
	field: any;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.field = source["field"];
	}
}`
	testConverter(t, converter, true, desiredResult, nil)
}

type NumberTime time.Time

func (t NumberTime) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf("%d", time.Time(t).Unix())), nil
}

func TestTypeAlias(t *testing.T) {
	t.Parallel()
	type Person struct {
		Birth NumberTime `json:"birth" ts_type:"number"`
	}

	converter := New()

	converter.AddType(reflect.TypeOf(Person{}))
	converter.BackupDir = ""
	converter.CreateConstructor = false

	desiredResult := `export class Person {
    birth: number;
}`
	testConverter(t, converter, false, desiredResult, nil)
}

type MSTime struct {
	time.Time
}

func (MSTime) UnmarshalJSON([]byte) error   { return nil }
func (MSTime) MarshalJSON() ([]byte, error) { return []byte("1111"), nil }

func TestOverrideCustomType(t *testing.T) {
	t.Parallel()

	type SomeStruct struct {
		Time MSTime `json:"time" ts_type:"number"`
	}
	var _ json.Marshaler = new(MSTime)
	var _ json.Unmarshaler = new(MSTime)

	converter := New()

	converter.AddType(reflect.TypeOf(SomeStruct{}))
	converter.BackupDir = ""
	converter.CreateConstructor = false

	desiredResult := `export class SomeStruct {
    time: number;
}`
	testConverter(t, converter, false, desiredResult, nil)

	byts, _ := json.Marshal(SomeStruct{Time: MSTime{Time: time.Now()}})
	assert.Equal(t, `{"time":1111}`, string(byts))
}

type Weekday int

const (
	Sunday Weekday = iota
	Monday
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
)

func (w Weekday) TSName() string {
	switch w {
	case Sunday:
		return "SUNDAY"
	case Monday:
		return "MONDAY"
	case Tuesday:
		return "TUESDAY"
	case Wednesday:
		return "WEDNESDAY"
	case Thursday:
		return "THURSDAY"
	case Friday:
		return "FRIDAY"
	case Saturday:
		return "SATURDAY"
	default:
		return "???"
	}
}

// One way to specify enums is to list all values and then every one must have a TSName() method
var allWeekdaysV1 = []Weekday{
	Sunday,
	Monday,
	Tuesday,
	Wednesday,
	Thursday,
	Friday,
	Saturday,
}

// Another way to specify enums:
var allWeekdaysV2 = []struct {
	Value  Weekday
	TSName string
}{
	{Sunday, "SUNDAY"},
	{Monday, "MONDAY"},
	{Tuesday, "TUESDAY"},
	{Wednesday, "WEDNESDAY"},
	{Thursday, "THURSDAY"},
	{Friday, "FRIDAY"},
	{Saturday, "SATURDAY"},
}

type Holliday struct {
	Name    string  `json:"name"`
	Weekday Weekday `json:"weekday"`
}

func TestEnum(t *testing.T) {
	t.Parallel()
	for _, allWeekdays := range []interface{}{allWeekdaysV1, allWeekdaysV2} {
		converter := New().
			AddType(reflect.TypeOf(Holliday{})).
			AddEnum(allWeekdays).
			WithConstructor(true).
			WithBackupDir("")

		desiredResult := `export enum Weekday {
	SUNDAY = 0,
	MONDAY = 1,
	TUESDAY = 2,
	WEDNESDAY = 3,
	THURSDAY = 4,
	FRIDAY = 5,
	SATURDAY = 6,
}
export class Holliday {
	name: string;
	weekday: Weekday;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.name = source["name"];
        this.weekday = source["weekday"];
    }
}`
		testConverter(t, converter, true, desiredResult, nil)
	}
}

type Gender string

const (
	MaleStr   Gender = "m"
	FemaleStr Gender = "f"
)

var allGenders = []struct {
	Value  Gender
	TSName string
}{
	{MaleStr, "MALE"},
	{FemaleStr, "FEMALE"},
}

func TestEnumWithStringValues(t *testing.T) {
	t.Parallel()
	converter := New().
		AddEnum(allGenders).
		WithConstructor(false).
		WithBackupDir("")

	desiredResult := `
export enum Gender {
	MALE = "m",
	FEMALE = "f",
}
`
	testConverter(t, converter, true, desiredResult, nil)
}

func TestConstructorWithReferences(t *testing.T) {
	t.Parallel()
	converter := New().
		AddType(reflect.TypeOf(Person{})).
		AddEnum(allWeekdaysV2).
		WithConstructor(true).
		WithBackupDir("")

	desiredResult := `export enum Weekday {
    SUNDAY = 0,
    MONDAY = 1,
    TUESDAY = 2,
    WEDNESDAY = 3,
    THURSDAY = 4,
    FRIDAY = 5,
    SATURDAY = 6,
}
export class Dummy {
    something: string;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.something = source["something"];
    }
}
export class Address {
    duration: number;
    text?: string;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.duration = source["duration"];
        this.text = source["text"];
    }
}
export class Person {
    name: string;
    nicknames: string[];
    addresses: Address[];
    address?: Address;
    metadata: {[key:string]:string};
    friends: Person[];
    a: Dummy;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.name = source["name"];
        this.nicknames = source["nicknames"];
        this.addresses = this.convertValues(source["addresses"], Address);
        this.address = this.convertValues(source["address"], Address);
		this.metadata = JSON.parse(source["metadata"] || "{}");
        this.friends = this.convertValues(source["friends"], Person);
        this.a = this.convertValues(source["a"], Dummy);
    }

	` + tsConvertValuesFunc + `
}`
	testConverter(t, converter, true, desiredResult, nil)
}

type WithMap struct {
	Map        map[string]int      `json:"simpleMap"`
	MapObjects map[string]Address  `json:"mapObjects"`
	PtrMap     *map[string]Address `json:"ptrMapObjects"`
}

func TestMaps(t *testing.T) {
	t.Parallel()
	converter := New().
		AddType(reflect.TypeOf(WithMap{})).
		WithConstructor(true).
		WithBackupDir("")

	desiredResult := `
      export class Address {
          duration: number;
          text?: string;

          constructor(source: any = {}) {
              if ('string' === typeof source) source = JSON.parse(source);
              this.duration = source["duration"];
              this.text = source["text"];
		  }
      }
      export class WithMap {
          simpleMap: {[key: string]: number};
          mapObjects: {[key: string]: Address};
          ptrMapObjects?: {[key: string]: Address};

          constructor(source: any = {}) {
              if ('string' === typeof source) source = JSON.parse(source);
              this.simpleMap = source["simpleMap"];
			  this.mapObjects = this.convertValues(source["mapObjects"], Address, true);
			  this.ptrMapObjects = this.convertValues(source["ptrMapObjects"], Address, true);
		  }

		  ` + tsConvertValuesFunc + `
      }
`

	json := WithMap{
		Map:        map[string]int{"aaa": 1},
		MapObjects: map[string]Address{"bbb": {Duration: 1.0, Text1: "txt1"}},
		PtrMap:     &map[string]Address{"ccc": {Duration: 2.0, Text1: "txt2"}},
	}

	testConverter(t, converter, true, desiredResult, []string{
		`new WithMap(` + jsonizeOrPanic(json) + `).simpleMap.aaa == 1`,
		`(new WithMap(` + jsonizeOrPanic(json) + `).mapObjects.bbb) instanceof Address`,
		`!((new WithMap(` + jsonizeOrPanic(json) + `).mapObjects.bbb) instanceof WithMap)`,
		`new WithMap(` + jsonizeOrPanic(json) + `).mapObjects.bbb.duration == 1`,
		`new WithMap(` + jsonizeOrPanic(json) + `).mapObjects.bbb.text === "txt1"`,
		`(new WithMap(` + jsonizeOrPanic(json) + `)?.ptrMapObjects?.ccc) instanceof Address`,
		`!((new WithMap(` + jsonizeOrPanic(json) + `)?.ptrMapObjects?.ccc) instanceof WithMap)`,
		`new WithMap(` + jsonizeOrPanic(json) + `)?.ptrMapObjects?.ccc?.duration === 2`,
		`new WithMap(` + jsonizeOrPanic(json) + `)?.ptrMapObjects?.ccc?.text === "txt2"`,
	})
}

func TestPTR(t *testing.T) {
	t.Parallel()
	type Person struct {
		Name *string `json:"name"`
	}

	converter := New()
	converter.BackupDir = ""
	converter.CreateConstructor = false
	converter.Add(Person{})

	desiredResult := `export class Person {
    name?: string;
}`
	testConverter(t, converter, true, desiredResult, nil)
}

type PersonWithPtrName struct {
	*HasName
}

func TestAnonymousPtr(t *testing.T) {
	t.Parallel()
	var p PersonWithPtrName
	p.HasName = &HasName{}
	p.Name = "JKLJKL"
	converter := New().
		AddType(reflect.TypeOf(PersonWithPtrName{})).
		WithConstructor(true).
		WithBackupDir("")

	desiredResult := `
      export class PersonWithPtrName {
          name: string;

          constructor(source: any = {}) {
              if ('string' === typeof source) source = JSON.parse(source);
              this.name = source["name"];
          }
      }
`
	testConverter(t, converter, true, desiredResult, nil)
}

func jsonizeOrPanic(i interface{}) string {
	byts, err := json.Marshal(i)
	if err != nil {
		panic(err)
	}
	return string(byts)
}

func TestTestConverter(t *testing.T) {
	t.Parallel()

	ts := `class Converter {
		` + tsConvertValuesFunc + `
}
const converter = new Converter();

class Address {
    street: string;
    number: number;

    constructor(a: any) {
        this.street = a["street"];
        this.number = a["number"];
    }
}
`

	testTypescriptExpression(t, true, ts, []string{
		`(converter.convertValues(null, Address)) === null`,
		`(converter.convertValues([], Address)).length === 0`,
		`(converter.convertValues({}, Address)) instanceof Address`,
		`!(converter.convertValues({}, Address, true) instanceof Address)`,

		`(converter.convertValues([{street: "aaa", number: 19}] as any, Address) as Address[]).length == 1`,
		`(converter.convertValues([{street: "aaa", number: 19}] as any, Address) as Address[])[0] instanceof Address`,
		`(converter.convertValues([{street: "aaa", number: 19}] as any, Address) as Address[])[0].number === 19`,
		`(converter.convertValues([{street: "aaa", number: 19}] as any, Address) as Address[])[0].street === "aaa"`,

		`(converter.convertValues([[{street: "aaa", number: 19}]] as any, Address) as Address[]).length == 1`,
		`(converter.convertValues([[{street: "aaa", number: 19}]] as any, Address) as Address[][])[0][0] instanceof Address`,
		`(converter.convertValues([[{street: "aaa", number: 19}]] as any, Address) as Address[][])[0][0].number === 19`,
		`(converter.convertValues([[{street: "aaa", number: 19}]] as any, Address) as Address[][])[0][0].street === "aaa"`,

		`Object.keys((converter.convertValues({"first": {street: "aaa", number: 19}}, Address, true) as {[_: string]: Address})).length == 1`,
		`(converter.convertValues({"first": {street: "aaa", number: 19}} as any, Address, true) as {[_: string]: Address})["first"] instanceof Address`,
		`(converter.convertValues({"first": {street: "aaa", number: 19}} as any, Address, true) as {[_: string]: Address})["first"].number === 19`,
		`(converter.convertValues({"first": {street: "aaa", number: 19}} as any, Address, true) as {[_: string]: Address})["first"].street === "aaa"`,
	})
}

func TestIgnoredPTR(t *testing.T) {
	t.Parallel()
	type PersonWithIgnoredPtr struct {
		Name     string  `json:"name"`
		Nickname *string `json:"-"`
	}

	converter := New()
	converter.BackupDir = ""
	converter.Add(PersonWithIgnoredPtr{})

	desiredResult := `
      export class PersonWithIgnoredPtr {
          name: string;

          constructor(source: any = {}) {
              if ('string' === typeof source) source = JSON.parse(source);
              this.name = source["name"];
          }
      }
`
	testConverter(t, converter, true, desiredResult, nil)
}

func TestMapWithPrefix(t *testing.T) {
	t.Parallel()

	type Example struct {
		Variable map[string]string `json:"variable"`
	}

	converter := New().WithPrefix("prefix_").Add(Example{})

	desiredResult := `
export class prefix_Example {
    variable: {[key: string]: string};

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.variable = source["variable"];
    }
}
`
	testConverter(t, converter, true, desiredResult, nil)
}

func TestFieldNamesWithoutJSONAnnotation(t *testing.T) {
	t.Parallel()

	type WithoutAnnotation struct {
		PublicField  string
		privateField string
	}

	converter := New().Add(WithoutAnnotation{})
	desiredResult := `
export class WithoutAnnotation {
    PublicField: string;

    constructor(source: any = {}) {
        if ('string' === typeof source) source = JSON.parse(source);
        this.PublicField = source["PublicField"];
    }
}
`
	testConverter(t, converter, true, desiredResult, nil)
}

func TestTypescriptifyComment(t *testing.T) {
	t.Parallel()
	type Person struct {
		Name string `json:"name" ts_doc:"This is a comment"`
	}

	converter := New()

	converter.AddType(reflect.TypeOf(Person{}))
	converter.BackupDir = ""
	converter.CreateConstructor = false

	desiredResult := `export class Person {
	/** This is a comment */
	name: string;
}`
	testConverter(t, converter, false, desiredResult, nil)
}


text:
/**
 * Created by sebadmin on 2015-07-29.
 */
///<reference path='../../../typingsCustom/myInterfaces.d.ts' />

namespace stackClone{
	/**
	 * Main
	 */
// class Main extends TestTimer{
	class Main{

		componentName:string;

		static $inject = ['$log','QuestionService','SharedService'];

		constructor(private $log:ng.ILogService, private questionService:stackClone.QuestionService,private shared:stackClone.SharedService) {

			this.componentName = 'Questions as';
			$log.info("Main LOADED");

		}

	}

	function sebMain() {
		return {
			//templateUrl: '/components/main/main.ng.html',
			templateUrl: 'components/main/main.ng.html',
			controllerAs: 'main',
			controller: Main
		};
	}

	angular.module('stackClone')
		.directive('sebMain', sebMain);
}

redpajama_set_name: RedPajamaGithub


text:
class RenameSubjectsToLocations < ActiveRecord::Migration
  def change
    rename_table :subjects, :locations
    rename_column :feedback_inputs, :subject_id, :location_id
    rename_column :notification_subscriptions, :subject_id, :location_id
  end
end


text:
function out = km_swkrls(vars,pars,x,y)
% KM_SWKRLS implements the basic iteration of the sliding-window kernel
% recursive least-squares (SW-KRLS) algorithm.
% Input:	- vars: structure containing the used variables
%			- pars: structure containing kernel and algorithm parameters
%			- x: matrix containing input vectors as rows
%			- y: vector containing output values
% Output:	- out: contains the new vars if the algorithm is in learning
%			mode (when x and y are provided) and the estimated output when
%			the algorithm is being evaluated (when only x is given).
% Dependencies: km_kernel.
% USAGE: out = km_swkrls(vars,pars,x,y)
%
% Author: Steven Van Vaerenbergh (steven.vanvaerenbergh at unican.es) 2011.
%
% This file is part of the Kernel Methods Toolbox for MATLAB.
% https://github.com/steven2358/kmbox
%
% The algorithm in this file is based on the following publication:
% S. Van Vaerenbergh, J. Via, and I. Santamaria. "A sliding-window kernel
% RLS algorithm and its application to nonlinear channel identification",
% 2006 IEEE International Conference on Acoustics, Speech, and Signal
% Processing (ICASSP), Toulouse, France, 2006.

ktype = pars.kernel.type;
kpar = pars.kernel.par;
len = pars.M;
reg = pars.c;	% regularization constant

if nargin<4,
	mode = 'eval';
else
	if ~isfield(vars,'basis')
		mode = 'init';
	else
		mode = 'train';
	end
end

switch mode
	case 'init'		% initialize
		mem = x;
		basis = 1;
		ymem = y;
		knn = km_kernel(mem,x,ktype,kpar) + reg;
		K_inv = 1/knn;
		alpha = K_inv*ymem;

		vars.mem = mem;
		vars.basis = basis;
		vars.ymem = y;
		vars.K_inv = K_inv;
		vars.alpha = alpha;

		out = vars;
	case 'eval'		% evaluate
		mem = vars.mem;
		alpha = vars.alpha;

		K = km_kernel(x,mem,ktype,kpar);	% could be sped up
		y = K*alpha;

		out = y;
	case 'train'		% train
		mem = vars.mem;
		ymem = vars.ymem;
		K_inv = vars.K_inv;
		basis = vars.basis;
		t = vars.t;

		% expand dictionary
		mem = [mem; x];	% x should contain only one sample (column)
		ymem = [ymem; y];	% store subset labels
		basis = [basis t];

		k = km_kernel(mem,x,ktype,kpar);
		kn = k(1:size(mem,1)-1);
		knn = k(end) + reg;
		K_inv = inverse_addrowcol(kn,knn,K_inv);	% extend kernel matrix

		if (size(mem,1)>len)
			% prune dictionary
			mem(1,:) = [];
			ymem(1) = [];
			K_inv = inverse_removerowcol(K_inv);
			basis(1) = [];
		end
		alpha = K_inv*ymem;

		vars.K_inv = K_inv;
		vars.alpha = alpha;
		vars.mem = mem;
		vars.ymem = ymem;
		vars.basis = basis;

		out = vars;
end

function K_inv = inverse_addrowcol(b,d,A_inv)
% returns the inverse matrix of K = [A b;b' d]
% http://www.squobble.com/academic/swkrls/node15.html

g_inv = d - b'*A_inv*b;
g = 1/g_inv;
f = -A_inv*b*g;
% I = eye(size(A,1));
% E = A_inv*(I-b*f');
E = A_inv - A_inv*b*f';

K_inv = [E f;f' g];

function D_inv = inverse_removerowcol(K_inv)
% calculates the inverse of D with K = [a b';b D]
% http://www.squobble.com/academic/swkrls/node16.html

N = size(K_inv,1);

G = K_inv(2:N,2:N);
f = K_inv(2:N,1);
e = K_inv(1,1);

D_inv = G - f*f'/e;


text:
{{mySectionName}}

    <select style="width:120px;" ng-model="SelectingExp">
      <option ng-repeat="typeExp in selectExp" value="{{typeExp.name}}">{{typeExp.name}}</option>
    </select>

    <timeline ng-cloak>
      <timeline-event ng-repeat="exp in mesExperiences | selecttype : SelectingExp">
        <timeline-badge class="{{exp.badgeClass}} timeline-hidden" when-visible="animateElementIn" when-not-visible="animateElementOut">

        </timeline-badge>
        <timeline-panel class="{{exp.badgeClass}} timeline-hidden" when-visible="animateElementIn" when-not-visible="animateElementOut">
          <timeline-heading>

{{exp.title_type}}, {{exp.title_name}}

 {{exp.when_started | date:'yyyy'}}/{{exp.when_finished | date:'yyyy'}}

                  {{exp.location}}

          </timeline-heading>

{{exp.content | limitTo: contentlimit}} contentlimit" ng-click="contentlimit=exp.content.length">...En savoir plusReduire

          {{exp.trytry}}
        </timeline-panel>
      </timeline-event>
    </timeline>


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
    <TextView
            android:id="@+id/word"
            style="@android:style/TextAppearance.Large"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    <TextView
            android:id="@+id/definition"
            style="@android:style/TextAppearance.Small"
            android:singleLine="true"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
</LinearLayout>


text:
import sys
from nose import SkipTest
try:
    from IPython.parallel import Client
except ImportError:
    print >> sys.stderr, "Skipping IPython Tests (IPython not found)"
    raise SkipTest('IPython not present')

from hyperopt.ipy import IPythonTrials
import hyperopt.hp
import hyperopt.tpe
import hyperopt

def simple_objective(args):
    import time
    import random
    return args ** 2

space = hyperopt.hp.uniform('x', 0, 1)

def test0():
    client = Client()
    trials = IPythonTrials(client)

    minval = trials.fmin(simple_objective, space, hyperopt.tpe.suggest, 25)
    print minval
    assert minval['x'] < .2

def test_fmin_fn():
    client = Client()
    trials = IPythonTrials(client)
    assert not trials._testing_fmin_was_called
    minval = hyperopt.fmin(simple_objective, space,
            algo=hyperopt.tpe.suggest,
            max_evals=25,
            trials=trials)

    assert minval['x'] < .2
    assert trials._testing_fmin_was_called


text:
/**
 * Add the correct system-ui font-family in Firefox.
 */

@font-face {
  font-family: system-ui;
  src: local(".AppleSystemUIFont"), local("Segoe UI"), local("Ubuntu"), local("Roboto-Regular"), local("HelveticaNeue");
}

@font-face {
  font-family: system-ui;
  font-style: italic;
  src: local(".AppleSystemUIFont"), local("Segoe UI Italic"), local("Ubuntu-Italic"), local("Roboto-Italic"), local("HelveticaNeue-Italic");
}

@font-face {
  font-family: system-ui;
  font-weight: bold;
  src: local(".AppleSystemUIFont"), local("Segoe UI Bold"), local("Ubuntu-Bold"), local("Roboto-Bold"), local("HelveticaNeue-Bold");
}

@font-face {
  font-family: system-ui;
  font-style: italic;
  font-weight: bold;
  src: local(".AppleSystemUIFont"), local("Segoe UI Bold Italic"), local("Ubuntu-BoldItalic"), local("Roboto-BoldItalic"), local("HelveticaNeue-BoldItalic");
}


text:
/**
 * Adds the state transitions noted by clusters to the state transitions object.
 * @param StateTransitions
 * @param clusters
 */
function addClusterStateTransitions(StateTransitions, clusters) {
  for (let key in StateTransitions) {
    //console.log(key);
    // if it is a cluster
    if (clusters[key])
      resolveCluster(key, StateTransitions[key], StateTransitions, clusters);
  }
}

function resolveCluster(clusterName, followUpStates, StateTransitions, clusters) {
  clusters[clusterName].forEach(function (item) {
    // recursive if the item itself is a clusters
    if (clusters[item])
      return resolveCluster(item, followUpStates, StateTransitions, clusters);
    // if it is a single state
    addFollowUpStatesToSingleState(item, followUpStates, StateTransitions);
  });
}

function addFollowUpStatesToSingleState(state, followUpStates, StateTransitions) {
  // add multiple followUpStates to state
  for (let key in followUpStates) {
    if (followUpStates.hasOwnProperty(key))
      if (!StateTransitions[state])
        return new Error("Probable typo: " + state + " is not defined in StateTransitions.");
    StateTransitions[state][key] = followUpStates[key];
  }
}

module.exports = addClusterStateTransitions;


text:
import React from 'react'
import PropTypes from 'prop-types'

import generateUrl from 'utils/urlGenerator'

const DownloadLinks = (props) => {
  const links = props.links.map((link, index) => {
    let name
    switch (link.get('type')) {
      case 'story':
        name = 'Le récit'
        break
      case 'video':
        name = 'Vidéo'
        break
      case 'focus':
        name = 'Le focus'
        break
      default:
        name = link.get('type')
    }
    return
{name}

  })
  return (

{props.links.size === 0 ? 'Lien' : 'Liens'} de téléchargement :

Emission complète

        {links}

  )
}

DownloadLinks.propTypes = {
  main: PropTypes.string.isRequired,
  links: PropTypes.object
}

export default DownloadLinks


text:
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (c) 2016. Microlands Systems
  ~
  ~ 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.
  ~
  -->

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/question_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:padding="24dp"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|center_horizontal"
        android:orientation="horizontal">

        <Button
            android:id="@+id/true_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="?android:buttonBarStyle"
            android:text="@string/true_button"/>

        <Button
            android:id="@+id/false_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="?android:buttonBarStyle"
            android:text="@string/false_button"/>

    </LinearLayout>

    <Button
        android:id="@+id/cheat_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/cheat_button"
        android:layout_gravity="bottom|center"/>

    <ImageButton
        android:id="@+id/prev_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|left"
        android:contentDescription="@string/prev_button"
        android:src="@drawable/arrow_left"/>

    <ImageButton
        android:id="@+id/next_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:contentDescription="@string/next_button"
        android:src="@drawable/arrow_right"/>

</FrameLayout>


text:
Sesión educativa para explicar Spark Streaming con PySpark y realizar un pequeño ejercicio con la API de Twitter

## Preparativos para el 1er notebook/ejercicio: Spark_Streaming.ipynb
### Repaso de Arquitectura Lambda

![LA Overview](http://lambda-architecture.net/img/la-overview_small.png)

####  Contenedor
1. Iniciar Docker
2. En la terminal de comandos de su computadora:

```bash
$ docker run -e GRANT_SUDO=yes --user root -d -p 8888:8888 jupyter/pyspark-notebook start-notebook.sh
```
Problemas en Windows: https://medium.com/@neil.avery_68603/running-docker-from-windows-cmd-prompt-6540daebedad#.lae8p2oiz

#### Dentro del contenedor

```bash
# apt-get update
# apt-get install netcat
# su jovyan
$ git clone https://github.com/israelzuniga/spark_streaming_class.git
$ cd spark_streaming_class
$ nc -lkv 127.0.0.1 -p 9999
```

## Preparativos para el 2do notebook/ejercicio: TwitterTrends

#### Instalar Tweepy

```bash
$ /opt/conda/bin/pip install tweepy
```

#### Cuando sea requerido, ejecutar *read.py*

Desde el folder TwitterTrends/
```bash
$ cd TwitterTrends
$ /opt/conda/bin/python read.py
```

#### Abrir el notebook de Jupyter: TwitterTrends/Twitter stream.ipynb


text:
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.sync.notifier;

import android.accounts.Account;
import android.content.Intent;

import com.google.ipc.invalidation.external.client.types.ObjectId;
import com.google.protos.ipc.invalidation.Types;

import org.chromium.base.CollectionUtil;
import org.chromium.sync.internal_api.pub.base.ModelType;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

/**
 * Constants and utility methods to create the intents used to communicate between the
 * controller and the invalidation client library.
 */
public class InvalidationIntentProtocol {
    /**
     * Action set on register intents.
     */
    public static final String ACTION_REGISTER =
            "org.chromium.sync.notifier.ACTION_REGISTER_TYPES";

    /**
     * Parcelable-valued intent extra containing the account of the user.
     */
    public static final String EXTRA_ACCOUNT = "account";

    /**
     * String-list-valued intent extra of the syncable types to sync.
     */
    public static final String EXTRA_REGISTERED_TYPES = "registered_types";

    /**
     * Int-array-valued intent extra containing sources of objects to register for.
     * The array is parallel to EXTRA_REGISTERED_OBJECT_NAMES.
     */
    public static final String EXTRA_REGISTERED_OBJECT_SOURCES = "registered_object_sources";

    /**
     * String-array-valued intent extra containing names of objects to register for.
     * The array is parallel to EXTRA_REGISTERED_OBJECT_SOURCES.
     */
    public static final String EXTRA_REGISTERED_OBJECT_NAMES = "registered_object_names";

    /**
     * Boolean-valued intent extra indicating that the service should be stopped.
     */
    public static final String EXTRA_STOP = "stop";

    /**
     * Create an Intent that will start the invalidation listener service and
     * register for the specified types.
     */
    public static Intent createRegisterIntent(Account account,
                                              boolean allTypes, Set<ModelType> types) {
        Intent registerIntent = new Intent(ACTION_REGISTER);
        String[] selectedTypesArray;
        if (allTypes) {
            selectedTypesArray = new String[]{ModelType.ALL_TYPES_TYPE};
        } else {
            selectedTypesArray = new String[types.size()];
            int pos = 0;
            for (ModelType type : types) {
                selectedTypesArray[pos++] = type.name();
            }
        }
        registerIntent.putStringArrayListExtra(EXTRA_REGISTERED_TYPES,
                CollectionUtil.newArrayList(selectedTypesArray));
        registerIntent.putExtra(EXTRA_ACCOUNT, account);
        return registerIntent;
    }

    /**
     * Create an Intent that will start the invalidation listener service and
     * register for the object ids with the specified sources and names.
     * Sync-specific objects are filtered out of the request since Sync types
     * are registered using the other version of createRegisterIntent.
     */
    public static Intent createRegisterIntent(Account account, int[] objectSources,
            String[] objectNames) {
        if (objectSources.length != objectNames.length) {
            throw new IllegalArgumentException(
                    "objectSources and objectNames must have the same length");
        }

        // Add all non-Sync objects to new lists.
        ArrayList<Integer> sources = new ArrayList<Integer>();
        ArrayList<String> names = new ArrayList<String>();
        for (int i = 0; i < objectSources.length; i++) {
            if (objectSources[i] != Types.ObjectSource.CHROME_SYNC) {
                sources.add(objectSources[i]);
                names.add(objectNames[i]);
            }
        }

        Intent registerIntent = new Intent(ACTION_REGISTER);
        registerIntent.putIntegerArrayListExtra(EXTRA_REGISTERED_OBJECT_SOURCES, sources);
        registerIntent.putStringArrayListExtra(EXTRA_REGISTERED_OBJECT_NAMES, names);
        registerIntent.putExtra(EXTRA_ACCOUNT, account);
        return registerIntent;
    }

    /** Returns whether {@code intent} is a stop intent. */
    public static boolean isStop(Intent intent) {
        return intent.getBooleanExtra(EXTRA_STOP, false);
    }

    /** Returns whether {@code intent} is a registered types change intent. */
    public static boolean isRegisteredTypesChange(Intent intent) {
        return intent.hasExtra(EXTRA_REGISTERED_TYPES)
                || intent.hasExtra(EXTRA_REGISTERED_OBJECT_SOURCES);
    }

    /** Returns the object ids for which to register contained in the intent. */
    public static Set<ObjectId> getRegisteredObjectIds(Intent intent) {
        ArrayList<Integer> objectSources =
                intent.getIntegerArrayListExtra(EXTRA_REGISTERED_OBJECT_SOURCES);
        ArrayList<String> objectNames =
                intent.getStringArrayListExtra(EXTRA_REGISTERED_OBJECT_NAMES);
        if (objectSources == null || objectNames == null
                || objectSources.size() != objectNames.size()) {
            return null;
        }
        Set<ObjectId> objectIds = new HashSet<ObjectId>(objectSources.size());
        for (int i = 0; i < objectSources.size(); i++) {
            objectIds.add(ObjectId.newInstance(
                    objectSources.get(i), objectNames.get(i).getBytes()));
        }
        return objectIds;
    }

    private InvalidationIntentProtocol() {
        // Disallow instantiation.
    }
}


text:
/*
 *  Document   : hashtegny.css
 *  Author     : Omar El Gabry <omar.elgabry.93@gmail.com>
 *  Description: Main CSS File
 *
 */

html, body {
    margin: 0;
    height: 100%;
}
body {
    background: #5f2c82; /* fallback for old browsers */
    background: -webkit-linear-gradient(to left, #5f2c82 , #49a09d); /* Chrome 10-25, Safari 5.1-6 */
    background: linear-gradient(to left, #5f2c82 , #49a09d); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
    font-family: "Avant Garde",Avantgarde,"Century Gothic",CenturyGothic,AppleGothic,sans-serif;
}

/* ==== Social Networks === */
.instagram .user-image,.instagram .user-name,.instagram .post-text,.instagram .post-time{
    background-color: #306088;
    border-color: #306088;
    color: white;
}
.twitter .user-image,.twitter .user-name,.twitter .post-text,.twitter .post-time{
    background-color: #0084B4;
    border-color: #0084B4;
    color: white;
}
.google .user-image,.google .user-name,.google .post-text,.google .post-time{
    background-color: #DD4B39;
    border-color: #DD4B39;
    color: white;
}
.vk .user-image,.vk .user-name,.vk .post-text,.vk .post-time{
    background-color: #45668e;
    border-color: #45668e;
    color: white;
}

/* ==== Search Container === */
.intro-container{
    background-color: white;
    text-align: center;
}
.intro-container .toggle-header{
    color: #3498db;
}
.intro-container .toggle-header:hover{
    cursor: pointer;
    color: #3cb0fd;
}

/* ==== Header === */
.header{
    font-size: 0.9em;
    padding: 0.5%;
    font-family: "Avant Garde",Avantgarde,"Century Gothic",CenturyGothic,AppleGothic,sans-serif;
}
.header h3{
    font-size: 70px;
    font-weight: bold;
    margin: 2% auto;
}
.header hr{
    opacity: 0.2;
    background-color: #fff;
    border-color: #fff;
    border-bottom: none;
    width: 50%;
}
.header p{
    font-size: 1.5em;
    padding: 10px;
    margin: 0;
}
.header button{
    border: none;
    font-family: "Avant Garde",Avantgarde,"Century Gothic",CenturyGothic,AppleGothic,sans-serif;
    background-color: #3498db;
    color: #ffffff;
    padding: 10px;
}
.header button:hover{
    cursor: pointer;
    -webkit-transform: scale(1.1);
    transform: scale(1.1);
}
.header button.animation-button, .header button.grid-button{
    padding-left: 15px;
    padding-right: 15px;
}
.header button.animation-button{
    background-color: #49a09d;
}
.header button.grid-button{
    background-color: #5f2c82;
}
.header input{
    padding: 10px;
    border: solid 1px #3498db;
    font-family: "Avant Garde",Avantgarde,"Century Gothic",CenturyGothic,AppleGothic,sans-serif;
}
.header .network-icons{
    padding: 1%;
}
.network-icons, .network-icons div{
    display: inline-block;
    vertical-align: middle;
}

/* ==== Spinner === */
.spinner{
    color: #3498db;
    text-align: center;
    display: inline-block;
    vertical-align: middle;
    margin-top: -1px;
    margin-left: 9px;
}

/* ==== Error === */
.error strong {
    line-height:30px;
}
.error span {
    position: fixed;
    right: 0;
    bottom: 0;
    z-index:999;
    display:inline;
    font-size: 1em;
    color: #a94442;
    padding: 1%;
    margin: 0.5%;
    width: 20%;
    border:1px solid transparent;
    background:#f2dede;
    border-radius:4px;
    box-shadow: 5px 5px 8px #CCC;
}

/* ==== @media Query === */
@media screen and (max-width: 1024px) {
    .error{
        font-size: 0.9em;
    }
}
@media screen and (max-width: 480px) {
    .header{
        font-size: 0.8em;
    }
    .header h3{
        font-size: 30px;
    }
    .error{
        display: none;
    }
}
@-ms-viewport{
  width: device-width;
  height: device-height;
  initial-scale: 1.0;
}


text:
package org.apache.catalina.mapper;

import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Test;

import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.Wrapper;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.core.StandardWrapper;
import org.apache.catalina.startup.LoggingBaseTest;
import org.apache.tomcat.util.buf.MessageBytes;

public class TestMapper extends LoggingBaseTest {

    protected Mapper mapper;

    private HashMap<String, Host> hostMap = new HashMap<>();

    private synchronized Host createHost(String name) {
        Host host = hostMap.get(name);
        if (host == null) {
            host = new StandardHost();
            host.setName(name);
            hostMap.put(name, host);
        }
        return host;
    }

    private Context createContext(String name) {
        Context context = new StandardContext();
        context.setName(name);
        return context;
    }

    private Wrapper createWrapper(String name) {
        Wrapper wrapper = new StandardWrapper();
        wrapper.setName(name);
        return wrapper;
    }

    @Before
    @Override
    public void setUp() throws Exception {
        super.setUp();
        mapper = new Mapper();

        mapper.addHost("sjbjdvwsbvhrb", new String[0], createHost("blah1"));
        mapper.addHost("sjbjdvwsbvhr/", new String[0], createHost("blah1"));
        mapper.addHost("wekhfewuifweuibf", new String[0], createHost("blah2"));
        mapper.addHost("ylwrehirkuewh", new String[0], createHost("blah3"));
        mapper.addHost("iohgeoihro", new String[0], createHost("blah4"));
        mapper.addHost("fwehoihoihwfeo", new String[0], createHost("blah5"));
        mapper.addHost("owefojiwefoi", new String[0], createHost("blah6"));
        mapper.addHost("iowejoiejfoiew", new String[0], createHost("blah7"));
        mapper.addHost("ohewoihfewoih", new String[0], createHost("blah8"));
        mapper.addHost("fewohfoweoih", new String[0], createHost("blah9"));
        mapper.addHost("ttthtiuhwoih", new String[0], createHost("blah10"));
        mapper.addHost("lkwefjwojweffewoih", new String[0], createHost("blah11"));
        mapper.addHost("zzzuyopjvewpovewjhfewoih", new String[0], createHost("blah12"));
        mapper.addHost("xxxxgqwiwoih", new String[0], createHost("blah13"));
        mapper.addHost("qwigqwiwoih", new String[0], createHost("blah14"));
        mapper.addHost("qwerty.net", new String[0], createHost("blah15"));
        mapper.addHost("*.net", new String[0], createHost("blah16"));
        mapper.addHost("zzz.com", new String[0], createHost("blah17"));
        mapper.addHostAlias("iowejoiejfoiew", "iowejoiejfoiew_alias");

        mapper.setDefaultHostName("ylwrehirkuewh");

        String[] welcomes = new String[2];
        welcomes[0] = "boo/baba";
        welcomes[1] = "bobou";

        Host host = createHost("blah7");
        mapper.addContextVersion("iowejoiejfoiew", host, "",
                "0", createContext("context0"), new String[0], null, null);
        mapper.addContextVersion("iowejoiejfoiew", host, "/foo",
                "0", createContext("context1"), new String[0], null, null);
        mapper.addContextVersion("iowejoiejfoiew", host, "/foo/bar",
                "0", createContext("context2"), welcomes, null, null);

        mapper.addWrappers("iowejoiejfoiew", "/foo", "0", Arrays
                .asList(new WrapperMappingInfo[] {
                        new WrapperMappingInfo("/",
                                createWrapper("context1-defaultWrapper"), false, false) }));
        mapper.addWrappers("iowejoiejfoiew", "/foo/bar", "0", Arrays
                .asList(new WrapperMappingInfo[] {
                        new WrapperMappingInfo("/fo/*",
                                createWrapper("wrapper0"), false, false),
                        new WrapperMappingInfo("/", createWrapper("wrapper1"),
                                false, false),
                        new WrapperMappingInfo("/blh",
                                createWrapper("wrapper2"), false, false),
                        new WrapperMappingInfo("*.jsp",
                                createWrapper("wrapper3"), false, false),
                        new WrapperMappingInfo("/blah/bou/*",
                                createWrapper("wrapper4"), false, false),
                        new WrapperMappingInfo("/blah/bobou/*",
                                createWrapper("wrapper5"), false, false),
                        new WrapperMappingInfo("*.htm",
                                createWrapper("wrapper6"), false, false) }));

        mapper.addContextVersion(
                "iowejoiejfoiew",
                host,
                "/foo/bar/bla",
                "0",
                createContext("context3"),
                new String[0],
                null,
                Arrays.asList(new WrapperMappingInfo[] { new WrapperMappingInfo(
                        "/bobou/*", createWrapper("wrapper7"), false, false) }));

        host = createHost("blah16");
        mapper.addContextVersion("*.net", host, "", "0", createContext("context4"),
                new String[0], null, null);
        mapper.addWrappers("*.net", "", "0", Arrays
                .asList(new WrapperMappingInfo[] {
                        new WrapperMappingInfo("/",
                                createWrapper("context4-defaultWrapper"), false, false) }));
    }

    @Test
    public void testAddHost() throws Exception {
        // Try to add duplicates
        // Duplicate Host name
        mapper.addHost("iowejoiejfoiew", new String[0], createHost("blah17"));
        // Alias conflicting with existing Host
        mapper.addHostAlias("iowejoiejfoiew", "qwigqwiwoih");
        // Alias conflicting with existing Alias
        mapper.addHostAlias("sjbjdvwsbvhrb", "iowejoiejfoiew_alias");
        // Redundancy. Alias name = Host name. No error here.
        mapper.addHostAlias("qwigqwiwoih", "qwigqwiwoih");
        // Redundancy. Duplicate Alias for the same Host name. No error here.
        mapper.addHostAlias("iowejoiejfoiew", "iowejoiejfoiew_alias");
        mapper.addHostAlias("iowejoiejfoiew", "iowejoiejfoiew_alias");

        // Check we have the right number
        // (added 17 including one host alias. Three duplicates do not increase the count.)
        assertEquals(19, mapper.hosts.length);

        // Make sure adding a duplicate *does not* overwrite
        final int iowPos = 4;
        assertEquals("blah7", mapper.hosts[iowPos].object.getName());

        final int qwigPos = 10;
        assertEquals("blah14", mapper.hosts[qwigPos].object.getName());

        // Check for alphabetical order of host names
        String previous;
        String current = mapper.hosts[0].name;
        for (int i = 1; i < mapper.hosts.length; i++) {
            previous = current;
            current = mapper.hosts[i].name;
            assertTrue(previous.compareTo(current) < 0);
        }

        // Check that host alias has the same data
        Mapper.MappedHost host = mapper.hosts[iowPos];
        Mapper.MappedHost alias = mapper.hosts[iowPos + 1];
        assertEquals("iowejoiejfoiew", host.name);
        assertEquals("iowejoiejfoiew_alias", alias.name);
        assertFalse(host.isAlias());
        assertTrue(alias.isAlias());
        assertEquals(host.object, alias.object);

        // Test addContextVersion() followed by addHost()
        Host hostZ = createHost("zzzz");
        Context contextZ = createContext("contextZ");

        assertEquals(19, mapper.hosts.length);
        mapper.addContextVersion("zzzz", hostZ, "/", "", contextZ, null, null,
                null);
        assertEquals(20, mapper.hosts.length);

        mapper.addHost("zzzz", new String[] { "zzzz_alias1", "zzzz_alias2" },
                hostZ);
        assertEquals(22, mapper.hosts.length);

        assertEquals("zzzz", mapper.hosts[19].name);
        assertEquals("zzzz_alias1", mapper.hosts[20].name);
        assertEquals("zzzz_alias2", mapper.hosts[21].name);
        assertEquals(2, mapper.hosts[19].getAliases().size());
        assertSame(contextZ,
                mapper.hosts[19].contextList.contexts[0].versions[0].object);
        assertSame(contextZ,
                mapper.hosts[21].contextList.contexts[0].versions[0].object);
    }

    @Test
    public void testRemoveHost() {
        assertEquals(19, mapper.hosts.length);
        mapper.removeHostAlias("iowejoiejfoiew");
        mapper.removeHost("iowejoiejfoiew_alias");
        assertEquals(19, mapper.hosts.length); // No change
        mapper.removeHostAlias("iowejoiejfoiew_alias");
        assertEquals(18, mapper.hosts.length); // Removed

        mapper.addHostAlias("iowejoiejfoiew", "iowejoiejfoiew_alias");
        assertEquals(19, mapper.hosts.length);

        final int iowPos = 4;
        Mapper.MappedHost hostMapping = mapper.hosts[iowPos];
        Mapper.MappedHost aliasMapping = mapper.hosts[iowPos + 1];
        assertEquals("iowejoiejfoiew_alias", aliasMapping.name);
        assertTrue(aliasMapping.isAlias());
        assertSame(hostMapping.object, aliasMapping.object);

        assertEquals("iowejoiejfoiew", hostMapping.getRealHostName());
        assertEquals("iowejoiejfoiew", aliasMapping.getRealHostName());
        assertSame(hostMapping, hostMapping.getRealHost());
        assertSame(hostMapping, aliasMapping.getRealHost());

        mapper.removeHost("iowejoiejfoiew");
        assertEquals(17, mapper.hosts.length); // Both host and alias removed
        for (Mapper.MappedHost host : mapper.hosts) {
            assertTrue(host.name, !host.name.startsWith("iowejoiejfoiew"));
        }
    }

    @Test
    public void testMap() throws Exception {
        MappingData mappingData = new MappingData();
        MessageBytes host = MessageBytes.newInstance();
        host.setString("iowejoiejfoiew");
        MessageBytes wildcard = MessageBytes.newInstance();
        wildcard.setString("foo.net");
        MessageBytes alias = MessageBytes.newInstance();
        alias.setString("iowejoiejfoiew_alias");
        MessageBytes uri = MessageBytes.newInstance();
        uri.setString("/foo/bar/blah/bobou/foo");
        uri.toChars();
        uri.getCharChunk().setLimit(-1);

        mapper.map(host, uri, null, mappingData);
        assertEquals("blah7", mappingData.host.getName());
        assertEquals("context2", mappingData.context.getName());
        assertEquals("wrapper5", mappingData.wrapper.getName());
        assertEquals("/foo/bar", mappingData.contextPath.toString());
        assertEquals("/blah/bobou", mappingData.wrapperPath.toString());
        assertEquals("/foo", mappingData.pathInfo.toString());
        assertTrue(mappingData.redirectPath.isNull());

        mappingData.recycle();
        uri.recycle();
        uri.setString("/foo/bar/bla/bobou/foo");
        uri.toChars();
        uri.getCharChunk().setLimit(-1);
        mapper.map(host, uri, null, mappingData);
        assertEquals("blah7", mappingData.host.getName());
        assertEquals("context3", mappingData.context.getName());
        assertEquals("wrapper7", mappingData.wrapper.getName());
        assertEquals("/foo/bar/bla", mappingData.contextPath.toString());
        assertEquals("/bobou", mappingData.wrapperPath.toString());
        assertEquals("/foo", mappingData.pathInfo.toString());
        assertTrue(mappingData.redirectPath.isNull());

        mappingData.recycle();
        uri.recycle();
        uri.setString("/foo/bar/bla/bobou/foo");
        uri.toChars();
        uri.getCharChunk().setLimit(-1);
        mapper.map(wildcard, uri, null, mappingData);
        assertEquals("blah16", mappingData.host.getName());
        assertEquals("context4", mappingData.context.getName());
        assertEquals("context4-defaultWrapper", mappingData.wrapper.getName());
        assertEquals("", mappingData.contextPath.toString());
        assertEquals("/foo/bar/bla/bobou/foo", mappingData.wrapperPath.toString());
        assertTrue(mappingData.pathInfo.isNull());
        assertTrue(mappingData.redirectPath.isNull());

        mappingData.recycle();
        uri.setString("/foo/bar/bla/bobou/foo");
        uri.toChars();
        uri.getCharChunk().setLimit(-1);
        mapper.map(alias, uri, null, mappingData);
        assertEquals("blah7", mappingData.host.getName());
        assertEquals("context3", mappingData.context.getName());
        assertEquals("wrapper7", mappingData.wrapper.getName());
        assertEquals("/foo/bar/bla", mappingData.contextPath.toString());
        assertEquals("/bobou", mappingData.wrapperPath.toString());
        assertEquals("/foo", mappingData.pathInfo.toString());
        assertTrue(mappingData.redirectPath.isNull());
    }

    @Test
    public void testAddRemoveContextVersion() throws Exception {
        final String hostName = "iowejoiejfoiew";
        final int iowPos = 4;
        final String contextPath = "/foo/bar";
        final int contextPos = 2;

        MappingData mappingData = new MappingData();
        MessageBytes hostMB = MessageBytes.newInstance();
        MessageBytes uriMB = MessageBytes.newInstance();
        hostMB.setString(hostName);
        uriMB.setString("/foo/bar/blah/bobou/foo");

        // Verifying configuration created by setUp()
        Mapper.MappedHost mappedHost = mapper.hosts[iowPos];
        assertEquals(hostName, mappedHost.name);
        Mapper.MappedContext mappedContext = mappedHost.contextList.contexts[contextPos];
        assertEquals(contextPath, mappedContext.name);
        assertEquals(1, mappedContext.versions.length);
        assertEquals("0", mappedContext.versions[0].name);
        Host oldHost = mappedHost.object;
        Context oldContext = mappedContext.versions[0].object;
        assertEquals("context2", oldContext.getName());

        Context oldContext1 = mappedHost.contextList.contexts[contextPos - 1].versions[0].object;
        assertEquals("context1", oldContext1.getName());

        mappingData.recycle();
        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("blah7", mappingData.host.getName());
        assertEquals("context2", mappingData.context.getName());
        assertEquals("wrapper5", mappingData.wrapper.getName());
        mappingData.recycle();
        mapper.map(oldContext, uriMB, mappingData);
        assertEquals("wrapper5", mappingData.wrapper.getName());

        Context newContext = createContext("newContext");
        mapper.addContextVersion(
                hostName,
                oldHost,
                contextPath,
                "1",
                newContext,
                null,
                null,
                Arrays.asList(new WrapperMappingInfo[] { new WrapperMappingInfo(
                        "/", createWrapper("newContext-default"), false, false) }));

        assertEquals(2, mappedContext.versions.length);
        assertEquals("0", mappedContext.versions[0].name);
        assertEquals("1", mappedContext.versions[1].name);
        mappingData.recycle();
        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("newContext", mappingData.context.getName());
        assertEquals("newContext-default", mappingData.wrapper.getName());
        mappingData.recycle();
        mapper.map(newContext, uriMB, mappingData);
        assertEquals("newContext-default", mappingData.wrapper.getName());

        mapper.removeContextVersion(oldContext, hostName, contextPath, "0");

        assertEquals(1, mappedContext.versions.length);
        assertEquals("1", mappedContext.versions[0].name);
        mappingData.recycle();
        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("newContext", mappingData.context.getName());
        assertEquals("newContext-default", mappingData.wrapper.getName());
        mappingData.recycle();
        mapper.map(newContext, uriMB, mappingData);
        assertEquals("newContext-default", mappingData.wrapper.getName());

        mapper.removeContextVersion(oldContext, hostName, contextPath, "1");

        assertNotSame(mappedContext, mappedHost.contextList.contexts[contextPos]);
        assertEquals("/foo/bar/bla", mappedHost.contextList.contexts[contextPos].name);
        mappingData.recycle();
        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("context1", mappingData.context.getName());
        assertEquals("context1-defaultWrapper", mappingData.wrapper.getName());
        mappingData.recycle();
        mapper.map(oldContext1, uriMB, mappingData);
        assertEquals("context1-defaultWrapper", mappingData.wrapper.getName());

        mapper.addContextVersion(
                hostName,
                oldHost,
                contextPath,
                "0",
                newContext,
                null,
                null,
                Arrays.asList(new WrapperMappingInfo[] { new WrapperMappingInfo(
                        "/", createWrapper("newContext-defaultWrapper2"), false, false) }));
        mappedContext = mappedHost.contextList.contexts[contextPos];

        assertEquals(contextPath, mappedContext.name);
        assertEquals(1, mappedContext.versions.length);
        assertEquals("0", mappedContext.versions[0].name);
        mappingData.recycle();
        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("newContext", mappingData.context.getName());
        assertEquals("newContext-defaultWrapper2", mappingData.wrapper.getName());
        mappingData.recycle();
        mapper.map(newContext, uriMB, mappingData);
        assertEquals("newContext-defaultWrapper2", mappingData.wrapper.getName());
    }

    @Test
    public void testReloadContextVersion() throws Exception {
        final String hostName = "iowejoiejfoiew";
        final int iowPos = 4;
        final String contextPath = "/foo/bar";
        final int contextPos = 2;

        MappingData mappingData = new MappingData();
        MessageBytes hostMB = MessageBytes.newInstance();
        MessageBytes uriMB = MessageBytes.newInstance();
        hostMB.setString(hostName);
        uriMB.setString("/foo/bar/blah/bobou/foo");

        // Verifying configuration created by setUp()
        Mapper.MappedHost mappedHost = mapper.hosts[iowPos];
        assertEquals(hostName, mappedHost.name);
        Mapper.MappedContext mappedContext = mappedHost.contextList.contexts[contextPos];
        assertEquals(contextPath, mappedContext.name);
        assertEquals(1, mappedContext.versions.length);
        assertEquals("0", mappedContext.versions[0].name);
        Host oldHost = mappedHost.object;
        Context oldContext = mappedContext.versions[0].object;
        assertEquals("context2", oldContext.getName());

        Context oldContext1 = mappedHost.contextList.contexts[contextPos - 1].versions[0].object;
        assertEquals("context1", oldContext1.getName());

        mappingData.recycle();
        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("blah7", mappingData.host.getName());
        assertEquals("context2", mappingData.context.getName());
        assertEquals("wrapper5", mappingData.wrapper.getName());
        mappingData.recycle();
        mapper.map(oldContext, uriMB, mappingData);
        assertEquals("wrapper5", mappingData.wrapper.getName());

        // Mark context as paused
        // This is what happens when context reload starts
        mapper.pauseContextVersion(oldContext, hostName, contextPath, "0");

        mappingData.recycle();
        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("blah7", mappingData.host.getName());
        assertEquals("context2", mappingData.context.getName());
        // Wrapper is not mapped for incoming requests if context is paused
        assertNull(mappingData.wrapper);
        mappingData.recycle();
        mapper.map(oldContext, uriMB, mappingData);
        // Wrapper is mapped for mapping method used by forward or include dispatch
        assertEquals("wrapper5", mappingData.wrapper.getName());

        // Re-add the same context, but different list of wrappers
        // This is what happens when context reload completes
        mapper.addContextVersion(
                hostName,
                oldHost,
                contextPath,
                "0",
                oldContext,
                null,
                null,
                Arrays.asList(new WrapperMappingInfo[] { new WrapperMappingInfo(
                        "/", createWrapper("newDefaultWrapper"), false, false) }));

        mappedContext = mappedHost.contextList.contexts[contextPos];
        assertEquals(contextPath, mappedContext.name);
        assertEquals(1, mappedContext.versions.length);
        assertEquals("0", mappedContext.versions[0].name);

        mappingData.recycle();
        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("blah7", mappingData.host.getName());
        assertEquals("context2", mappingData.context.getName());
        assertEquals("newDefaultWrapper", mappingData.wrapper.getName());
        mappingData.recycle();
        mapper.map(oldContext, uriMB, mappingData);
        assertEquals("newDefaultWrapper", mappingData.wrapper.getName());
    }

    @Test
    public void testContextListConcurrencyBug56653() throws Exception {
        final Host host = createHost("localhost");
        final Context contextRoot = createContext("ROOT");
        final Context context1 = createContext("foo");
        final Context context2 = createContext("foo#bar");
        final Context context3 = createContext("foo#bar#bla");
        final Context context4 = createContext("foo#bar#bla#baz");

        mapper.addHost("localhost", new String[] { "alias" }, host);
        mapper.setDefaultHostName("localhost");

        mapper.addContextVersion("localhost", host, "", "0", contextRoot,
                new String[0], null, null);
        mapper.addContextVersion("localhost", host, "/foo", "0", context1,
                new String[0], null, null);
        mapper.addContextVersion("localhost", host, "/foo/bar", "0", context2,
                new String[0], null, null);
        mapper.addContextVersion("localhost", host, "/foo/bar/bla", "0",
                context3, new String[0], null, null);
        mapper.addContextVersion("localhost", host, "/foo/bar/bla/baz", "0",
                context4, new String[0], null, null);

        final AtomicBoolean running = new AtomicBoolean(true);
        Thread t = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 100000; i++) {
                    mapper.removeContextVersion(context4, "localhost",
                            "/foo/bar/bla/baz", "0");
                    mapper.addContextVersion("localhost", host,
                            "/foo/bar/bla/baz", "0", context4, new String[0],
                            null, null);
                }
                running.set(false);
            }
        };

        MappingData mappingData = new MappingData();
        MessageBytes hostMB = MessageBytes.newInstance();
        hostMB.setString("localhost");
        MessageBytes aliasMB = MessageBytes.newInstance();
        aliasMB.setString("alias");
        MessageBytes uriMB = MessageBytes.newInstance();
        char[] uri = "/foo/bar/bla/bobou/foo".toCharArray();
        uriMB.setChars(uri, 0, uri.length);

        mapper.map(hostMB, uriMB, null, mappingData);
        assertEquals("/foo/bar/bla", mappingData.contextPath.toString());

        mappingData.recycle();
        uriMB.setChars(uri, 0, uri.length);
        mapper.map(aliasMB, uriMB, null, mappingData);
        assertEquals("/foo/bar/bla", mappingData.contextPath.toString());

        t.start();
        while (running.get()) {
            mappingData.recycle();
            uriMB.setChars(uri, 0, uri.length);
            mapper.map(hostMB, uriMB, null, mappingData);
            assertEquals("/foo/bar/bla", mappingData.contextPath.toString());

            mappingData.recycle();
            uriMB.setChars(uri, 0, uri.length);
            mapper.map(aliasMB, uriMB, null, mappingData);
            assertEquals("/foo/bar/bla", mappingData.contextPath.toString());
        }
    }
}


text:
import asyncio

import irc.parser
import pyparsing

def unescape(value):
    return value.replace("\\:", ";") \
                .replace("\\s", " ") \
                .replace("\\\\", "\\") \
                .replace("\\r", "\r") \
                .replace("\\n", "\n")

class Connection:
    def __init__(self, host, port, handler, loop=None):
        self.host = host
        self.port = port

        self.handler = handler

        self.loop = loop or asyncio.get_event_loop()
        self.writer = None

    @asyncio.coroutine
    def run(self):
        wait_time = 1
        while True:
            try:
                reader, self.writer = yield from asyncio.open_connection(self.host, self.port, loop=self.loop)
                yield from self.signal("connect", self)
                while not reader.at_eof():
                    line = yield from reader.readline()
                    if not line.endswith(b"\r\n"):
                        continue
                    wait_time = 1
                    try:
                        tags, source, command, params = irc.parser.message.parseString(line.decode("utf-8", "replace"))
                    except pyparsing.ParseException as e:
                        print("Parse error while parsing %r: %s" % (line, e))
                        continue
                    tags = {tag: unescape(value) for tag, value in tags}
                    params = list(params)
                    if "server" in source:
                        source = source["server"]
                    elif "nick" in source:
                        source = source["nick"]
                        if len(source) == 1:
                            source = (source[0], None, None)
                        elif len(source) == 2:
                            source = (source[0], None, source[1])
                        else:
                            source = (source[0], source[1], source[2])
                    else:
                        source = self.host
                    command = command.lower()
                    if command == "privmsg" and params[1][0] == "\x01" and params[1][-1] == "\x01": # CTCP message
                        tag, param = params[1][1:-1].split(" ", 1)
                        yield from self.signal("ctcp_" + tag.lower(), self, tags, source, [params[0], param])
                    else:
                        yield from self.signal(command, self, tags, source, params)
            except IOError as e:
                pass
            yield from asyncio.sleep(wait_time)
            wait_time *= 2

    def disconnect(self):
        self.writer.close()

    @asyncio.coroutine
    def signal(self, name, *args, **kwargs):
        callback = getattr(self.handler, "on_" + name, None)
        if callback is not None:
            yield from callback(*args, **kwargs)

    #
    # IRC commands
    #
    @asyncio.coroutine
    def command_raw(self, command):
        self.writer.write((command+"\r\n").encode("utf-8"))
        yield from self.writer.drain()

    @asyncio.coroutine
    def password(self, password):
        yield from self.command_raw("PASS " + password)

    @asyncio.coroutine
    def nick(self, nick):
        yield from self.command_raw("NICK " + nick)

    @asyncio.coroutine
    def join(self, target):
        yield from self.command_raw("JOIN " + target)

    @asyncio.coroutine
    def cap_req(self, cap):
        yield from self.command_raw("CAP REQ :" + cap)

    @asyncio.coroutine
    def ping(self, server1, server2=None):
        yield from self.command_raw("PING " + server1 + (" " + server2 if server2 is not None else ""))

    @asyncio.coroutine
    def pong(self, server1, server2=None):
        yield from self.command_raw("PONG " + server1 + (" " + server2 if server2 is not None else ""))

    @asyncio.coroutine
    def privmsg(self, target, message):
        yield from self.command_raw("PRIVMSG " + target + " :" + message)


text:
package net.coding.program.project.detail.file;

import android.content.Intent;
import android.support.v7.widget.SwitchCompat;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.TextView;

import net.coding.program.R;
import net.coding.program.common.Global;
import net.coding.program.common.model.ProjectObject;
import net.coding.program.common.model.RequestData;
import net.coding.program.common.model.Share;
import net.coding.program.common.model.ShareParam;
import net.coding.program.common.ui.BackActivity;
import net.coding.program.common.umeng.UmengEvent;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.androidannotations.annotations.ViewById;
import org.json.JSONException;
import org.json.JSONObject;

@EActivity(R.layout.activity_share_file_link)
public class ShareFileLinkActivity extends BackActivity {

    private static final String TAG_SHARE_LINK_ON = "TAG_SHARE_LINK_ON";
    private static final String TAG_SHARE_LINK_OFF = "TAG_SHARE_LINK_OFF";

    @Extra
    ProjectObject mProject;

    @Extra
    ShareParam mAttachmentFileObject;

    @ViewById
    View layoutShareLink;

    @ViewById
    SwitchCompat clickSettingShare;

    @ViewById
    TextView linkContent;
    private CompoundButton.OnCheckedChangeListener settingShareLister = new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (clickSettingShare.isChecked()) {
                RequestData request = mAttachmentFileObject.getHttpShareLinkOn(mProject);
                postNetwork(request, TAG_SHARE_LINK_ON);
            } else {
                String url = mAttachmentFileObject.getHttpShareLinkOff();
                deleteNetwork(url, TAG_SHARE_LINK_OFF);
            }

            showProgressBar(true, "");
        }

    };

    @AfterViews
    protected final void initShareFileLinkActivity() {
        clickSettingShare.setOnCheckedChangeListener(null);
        if (mAttachmentFileObject.isShared()) {
            clickSettingShare.setChecked(true);
        } else {
            clickSettingShare.setChecked(false);
        }
        clickSettingShare.setOnCheckedChangeListener(settingShareLister);

        bindData();
    }

    @Click
    void clickShareLink() {
        String shareLink = mAttachmentFileObject.getShareLink();
        Global.copy(this, shareLink);
        showButtomToast("共享链接已复制");
        finish();
    }

    @Override
    public void parseJson(int code, JSONObject respanse, String tag, int pos, Object data) throws JSONException {
        if (tag.equals(TAG_SHARE_LINK_ON)) {
            showProgressBar(false);
            if (code == 0) {
                umengEvent(UmengEvent.FILE, "开启共享");
                Share mShare = new Share(respanse.optJSONObject("data"));
                mAttachmentFileObject.setShereLink(mShare.getUrl());
                bindData();
            } else {
                showErrorMsg(code, respanse);
            }
        } else if (tag.equals(TAG_SHARE_LINK_OFF)) {
            showProgressBar(false);
            if (code == 0) {
                umengEvent(UmengEvent.FILE, "关闭共享");
                mAttachmentFileObject.setShereLink("");
                bindData();
            } else {
                showErrorMsg(code, respanse);
            }
        }
    }

    private void bindData() {
        if (mAttachmentFileObject.isShared()) {
            layoutShareLink.setVisibility(View.VISIBLE);
            linkContent.setText(mAttachmentFileObject.getShareLink());
        } else {
            layoutShareLink.setVisibility(View.GONE);
        }
    }

    @Override
    public void finish() {
        Intent intent = new Intent();
        intent.putExtra("intentData", mAttachmentFileObject);
        setResult(RESULT_OK, intent);
        super.finish();
    }
}


text:
// Copyright (C) 2011  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.

#include "tester.h"
#include <dlib/svm_threaded.h>
#include <dlib/data_io.h>
#include "create_iris_datafile.h"
#include <vector>
#include <sstream>

namespace
{
    using namespace test;
    using namespace dlib;
    using namespace std;
    dlib::logger dlog("test.svm_multiclass_trainer");

    class test_svm_multiclass_trainer : public tester
    {
        /*!
            WHAT THIS OBJECT REPRESENTS
                This object represents a unit test.  When it is constructed
                it adds itself into the testing framework.
        !*/
    public:
        test_svm_multiclass_trainer (
        ) :
            tester (
                "test_svm_multiclass_trainer",       // the command line argument name for this test
                "Run tests on the svm_multiclass_linear_trainer stuff.", // the command line argument description
                0                     // the number of command line arguments for this test
            )
        {
        }

        template <typename sample_type>
        void run_test()
        {
            print_spinner();

            typedef typename sample_type::value_type::second_type scalar_type;

            std::vector<sample_type> samples;
            std::vector<scalar_type> labels;

            load_libsvm_formatted_data("iris.scale",samples, labels);

            DLIB_TEST(samples.size() == 150);
            DLIB_TEST(labels.size() == 150);

            typedef sparse_linear_kernel<sample_type> kernel_type;
            svm_multiclass_linear_trainer<kernel_type> trainer;
            trainer.set_c(100);
            trainer.set_epsilon(0.000001);

            randomize_samples(samples, labels);
            matrix<double> cv = cross_validate_multiclass_trainer(trainer, samples, labels, 4);

            dlog << LINFO << "confusion matrix: \n" << cv;
            const scalar_type cv_accuracy = sum(diag(cv))/sum(cv);
            dlog << LINFO << "cv accuracy: " << cv_accuracy;
            DLIB_TEST(cv_accuracy > 0.97);

            {
                print_spinner();
                typedef matrix<scalar_type,0,1> dsample_type;
                std::vector<dsample_type> dsamples = sparse_to_dense(samples);
                DLIB_TEST(dsamples.size() == 150);

                typedef linear_kernel<dsample_type> kernel_type;
                svm_multiclass_linear_trainer<kernel_type> trainer;
                trainer.set_c(100);

                cv = cross_validate_multiclass_trainer(trainer, dsamples, labels, 4);

                dlog << LINFO << "dense confusion matrix: \n" << cv;
                const scalar_type cv_accuracy = sum(diag(cv))/sum(cv);
                dlog << LINFO << "dense cv accuracy: " << cv_accuracy;
                DLIB_TEST(cv_accuracy > 0.97);
            }

        }

        void perform_test (
        )
        {
            print_spinner();
            create_iris_datafile();

            run_test<std::map<unsigned int, double> >();
            run_test<std::map<unsigned int, float> >();
            run_test<std::vector<std::pair<unsigned int, float> > >();
            run_test<std::vector<std::pair<unsigned long, double> > >();
        }
    };

    test_svm_multiclass_trainer a;

}


text:
namespace nValid.Validators
{
    public class NegatedValidator<TInstance, TValue> : IValidator<TInstance, TValue>
    {
        private readonly IValidator<TInstance, TValue> inner;

        public NegatedValidator(IValidator<TInstance, TValue> inner)
        {
            this.inner = inner;
        }

        public bool Validate(TInstance instance, TValue value)
        {
            return !inner.Validate(instance, value);
        }

        public string DefaultErrorMessage
        {
            get { return inner.DefaultNegatedErrorMessage; }
        }

        public string DefaultNegatedErrorMessage
        {
            get { return inner.DefaultErrorMessage; }
        }
    }
}


text:
#include <limits.h>
#include <string.h>

#include "ogldev_math_3d.h"
#include "ogldev_util.h"
#include "lighting_technique.h"

LightingTechnique::LightingTechnique()
{
}

bool LightingTechnique::Init()
{
    if (!Technique::Init()) {
        return false;
    }

    if (!AddShader(GL_VERTEX_SHADER, "lighting.vs")) {
        return false;
    }

    if (!AddShader(GL_TESS_CONTROL_SHADER, "lighting.cs")) {
        return false;
    }

    if (!AddShader(GL_TESS_EVALUATION_SHADER, "lighting.es")) {
        return false;
    }

    if (!AddShader(GL_FRAGMENT_SHADER, "lighting.fs")) {
        return false;
    }

    if (!Finalize()) {
        return false;
    }

    m_VPLocation = GetUniformLocation("gVP");
    m_WorldMatrixLocation = GetUniformLocation("gWorld");
    m_colorTextureLocation = GetUniformLocation("gColorMap");
    m_eyeWorldPosLocation = GetUniformLocation("gEyeWorldPos");
    m_dirLightLocation.Color = GetUniformLocation("gDirectionalLight.Base.Color");
    m_dirLightLocation.AmbientIntensity = GetUniformLocation("gDirectionalLight.Base.AmbientIntensity");
    m_dirLightLocation.Direction = GetUniformLocation("gDirectionalLight.Direction");
    m_dirLightLocation.DiffuseIntensity = GetUniformLocation("gDirectionalLight.Base.DiffuseIntensity");
    m_matSpecularIntensityLocation = GetUniformLocation("gMatSpecularIntensity");
    m_matSpecularPowerLocation = GetUniformLocation("gSpecularPower");
    m_numPointLightsLocation = GetUniformLocation("gNumPointLights");
    m_numSpotLightsLocation = GetUniformLocation("gNumSpotLights");
    m_TLLocation = GetUniformLocation("gTessellationLevel");

    if (m_dirLightLocation.AmbientIntensity == INVALID_UNIFORM_LOCATION ||
        m_VPLocation == INVALID_UNIFORM_LOCATION ||
        m_WorldMatrixLocation == INVALID_UNIFORM_LOCATION ||
        m_colorTextureLocation == INVALID_UNIFORM_LOCATION ||
        m_eyeWorldPosLocation == INVALID_UNIFORM_LOCATION ||
        m_dirLightLocation.Color == INVALID_UNIFORM_LOCATION ||
        m_dirLightLocation.DiffuseIntensity == INVALID_UNIFORM_LOCATION ||
        m_dirLightLocation.Direction == INVALID_UNIFORM_LOCATION ||
        m_matSpecularIntensityLocation == INVALID_UNIFORM_LOCATION ||
        m_matSpecularPowerLocation == INVALID_UNIFORM_LOCATION ||
        m_numPointLightsLocation == INVALID_UNIFORM_LOCATION ||
        m_numSpotLightsLocation == INVALID_UNIFORM_LOCATION ||
        m_TLLocation == INVALID_UNIFORM_LOCATION) {
        return false;
    }

    for (unsigned int i = 0 ; i < ARRAY_SIZE_IN_ELEMENTS(m_pointLightsLocation) ; i++) {
        char Name[128];
        memset(Name, 0, sizeof(Name));
        SNPRINTF(Name, sizeof(Name), "gPointLights[%d].Base.Color", i);
        m_pointLightsLocation[i].Color = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gPointLights[%d].Base.AmbientIntensity", i);
        m_pointLightsLocation[i].AmbientIntensity = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gPointLights[%d].Position", i);
        m_pointLightsLocation[i].Position = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gPointLights[%d].Base.DiffuseIntensity", i);
        m_pointLightsLocation[i].DiffuseIntensity = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gPointLights[%d].Atten.Constant", i);
        m_pointLightsLocation[i].Atten.Constant = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gPointLights[%d].Atten.Linear", i);
        m_pointLightsLocation[i].Atten.Linear = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gPointLights[%d].Atten.Exp", i);
        m_pointLightsLocation[i].Atten.Exp = GetUniformLocation(Name);

        if (m_pointLightsLocation[i].Color == INVALID_UNIFORM_LOCATION ||
            m_pointLightsLocation[i].AmbientIntensity == INVALID_UNIFORM_LOCATION ||
            m_pointLightsLocation[i].Position == INVALID_UNIFORM_LOCATION ||
            m_pointLightsLocation[i].DiffuseIntensity == INVALID_UNIFORM_LOCATION ||
            m_pointLightsLocation[i].Atten.Constant == INVALID_UNIFORM_LOCATION ||
            m_pointLightsLocation[i].Atten.Linear == INVALID_UNIFORM_LOCATION ||
            m_pointLightsLocation[i].Atten.Exp == INVALID_UNIFORM_LOCATION) {
            return false;
        }
    }

    for (unsigned int i = 0 ; i < ARRAY_SIZE_IN_ELEMENTS(m_spotLightsLocation) ; i++) {
        char Name[128];
        memset(Name, 0, sizeof(Name));
        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Base.Base.Color", i);
        m_spotLightsLocation[i].Color = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Base.Base.AmbientIntensity", i);
        m_spotLightsLocation[i].AmbientIntensity = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Base.Position", i);
        m_spotLightsLocation[i].Position = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Direction", i);
        m_spotLightsLocation[i].Direction = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Cutoff", i);
        m_spotLightsLocation[i].Cutoff = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Base.Base.DiffuseIntensity", i);
        m_spotLightsLocation[i].DiffuseIntensity = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Base.Atten.Constant", i);
        m_spotLightsLocation[i].Atten.Constant = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Base.Atten.Linear", i);
        m_spotLightsLocation[i].Atten.Linear = GetUniformLocation(Name);

        SNPRINTF(Name, sizeof(Name), "gSpotLights[%d].Base.Atten.Exp", i);
        m_spotLightsLocation[i].Atten.Exp = GetUniformLocation(Name);

        if (m_spotLightsLocation[i].Color == INVALID_UNIFORM_LOCATION ||
            m_spotLightsLocation[i].AmbientIntensity == INVALID_UNIFORM_LOCATION ||
            m_spotLightsLocation[i].Position == INVALID_UNIFORM_LOCATION ||
            m_spotLightsLocation[i].Direction == INVALID_UNIFORM_LOCATION ||
            m_spotLightsLocation[i].Cutoff == INVALID_UNIFORM_LOCATION ||
            m_spotLightsLocation[i].DiffuseIntensity == INVALID_UNIFORM_LOCATION ||
            m_spotLightsLocation[i].Atten.Constant == INVALID_UNIFORM_LOCATION ||
            m_spotLightsLocation[i].Atten.Linear == INVALID_UNIFORM_LOCATION ||
            m_spotLightsLocation[i].Atten.Exp == INVALID_UNIFORM_LOCATION) {
            return false;
        }
    }

    return true;
}

void LightingTechnique::SetVP(const Matrix4f& VP)
{
    glUniformMatrix4fv(m_VPLocation, 1, GL_TRUE, (const GLfloat*)VP.m);
}

void LightingTechnique::SetWorldMatrix(const Matrix4f& WorldInverse)
{
    glUniformMatrix4fv(m_WorldMatrixLocation, 1, GL_TRUE, (const GLfloat*)WorldInverse.m);
}

void LightingTechnique::SetColorTextureUnit(unsigned int TextureUnit)
{
    glUniform1i(m_colorTextureLocation, TextureUnit);
}

void LightingTechnique::SetDirectionalLight(const DirectionalLight& Light)
{
    glUniform3f(m_dirLightLocation.Color, Light.Color.x, Light.Color.y, Light.Color.z);
    glUniform1f(m_dirLightLocation.AmbientIntensity, Light.AmbientIntensity);
    Vector3f Direction = Light.Direction;
    Direction.Normalize();
    glUniform3f(m_dirLightLocation.Direction, Direction.x, Direction.y, Direction.z);
    glUniform1f(m_dirLightLocation.DiffuseIntensity, Light.DiffuseIntensity);
}

void LightingTechnique::SetEyeWorldPos(const Vector3f& EyeWorldPos)
{
    glUniform3f(m_eyeWorldPosLocation, EyeWorldPos.x, EyeWorldPos.y, EyeWorldPos.z);
}

void LightingTechnique::SetMatSpecularIntensity(float Intensity)
{
    glUniform1f(m_matSpecularIntensityLocation, Intensity);
}

void LightingTechnique::SetMatSpecularPower(float Power)
{
    glUniform1f(m_matSpecularPowerLocation, Power);
}

void LightingTechnique::SetPointLights(unsigned int NumLights, const PointLight* pLights)
{
    glUniform1i(m_numPointLightsLocation, NumLights);

    for (unsigned int i = 0 ; i < NumLights ; i++) {
        glUniform3f(m_pointLightsLocation[i].Color, pLights[i].Color.x, pLights[i].Color.y, pLights[i].Color.z);
        glUniform1f(m_pointLightsLocation[i].AmbientIntensity, pLights[i].AmbientIntensity);
        glUniform1f(m_pointLightsLocation[i].DiffuseIntensity, pLights[i].DiffuseIntensity);
        glUniform3f(m_pointLightsLocation[i].Position, pLights[i].Position.x, pLights[i].Position.y, pLights[i].Position.z);
        glUniform1f(m_pointLightsLocation[i].Atten.Constant, pLights[i].Attenuation.Constant);
        glUniform1f(m_pointLightsLocation[i].Atten.Linear, pLights[i].Attenuation.Linear);
        glUniform1f(m_pointLightsLocation[i].Atten.Exp, pLights[i].Attenuation.Exp);
    }
}

void LightingTechnique::SetSpotLights(unsigned int NumLights, const SpotLight* pLights)
{
    glUniform1i(m_numSpotLightsLocation, NumLights);

    for (unsigned int i = 0 ; i < NumLights ; i++) {
        glUniform3f(m_spotLightsLocation[i].Color, pLights[i].Color.x, pLights[i].Color.y, pLights[i].Color.z);
        glUniform1f(m_spotLightsLocation[i].AmbientIntensity, pLights[i].AmbientIntensity);
        glUniform1f(m_spotLightsLocation[i].DiffuseIntensity, pLights[i].DiffuseIntensity);
        glUniform3f(m_spotLightsLocation[i].Position,  pLights[i].Position.x, pLights[i].Position.y, pLights[i].Position.z);
        Vector3f Direction = pLights[i].Direction;
        Direction.Normalize();
        glUniform3f(m_spotLightsLocation[i].Direction, Direction.x, Direction.y, Direction.z);
        glUniform1f(m_spotLightsLocation[i].Cutoff, cosf(ToRadian(pLights[i].Cutoff)));
        glUniform1f(m_spotLightsLocation[i].Atten.Constant, pLights[i].Attenuation.Constant);
        glUniform1f(m_spotLightsLocation[i].Atten.Linear,   pLights[i].Attenuation.Linear);
        glUniform1f(m_spotLightsLocation[i].Atten.Exp,      pLights[i].Attenuation.Exp);
    }
}

void LightingTechnique::SetTessellationLevel(float TL)
{
    glUniform1f(m_TLLocation, TL);
}


text:
Setup based on https://www.digitalocean.com/community/tutorials/how-to-install-tinc-and-set-up-a-basic-vpn-on-ubuntu-14-04

This node is meant to be accessible from a public IP and be the first node that
other nodes on the VPN connects to.

No special capabilties or privileges are needed on the host as no interface is
created by tinc. This is achieved by setting `DeviceType = dummy` in
`tinc.conf`.

## Configuring the gateway

1. Edit tinc/hosts/gateway to add in the public IP/DNS for the gateway

1. Build the Docker image
  ```
  docker build -t tinc-gateway .
  ```

1. Generate 4096 bits RSA public/private key pair for the gateway node. The private key
   will be written as tinc/rsa_key.priv and the public key will be appended to
   tinc/hosts/gateway.

  ```
  docker run -v `pwd`/tinc:/etc/tinc tinc-gateway -K4096
  ```

## Running the gateway

To run the gateway node directly on the host machine, execute
```
docker run -v `pwd`/tinc:/etc/tinc tinc-gateway
```

## Adding a node to the vpn

1. Generate public/private key pair for the node

1. Copy the node's host file to tinc/hosts/

1. Copy tinc/hosts/gateway to the hosts folder on node and start the node


text:
static const char* s_motion_type_name[] = {
    "DEFAULT_MOTION_TYPE",
    "CHARACTERWISE_INCLUSIVE",
    "CHARACTERWISE_EXCLUSIVE",
    "LINEWISE",
    "BLOCKWISE",
};

NSString* XVimMotionTypeName(MOTION_TYPE motion_type)
{
    return [NSString stringWithFormat:@"%s", s_motion_type_name[motion_type]];
}


text:
package com.datastax.spark.connector.rdd.typeTests

import com.datastax.driver.core.Row

class SmallIntTypeTest extends AbstractTypeTest[Short, java.lang.Short]{
  override protected val typeName: String = "smallint"

  override protected val typeData: Seq[Short] = (1 to 10).map(_.toShort)
  override protected val addData: Seq[Short] = (11 to 20).map(_.toShort)

  override def getDriverColumn(row: Row, colName: String): Short = row.getShort(colName)

}


text:
using System;
using NUnit.Framework;
using ccl.Framework.Exceptions;
using ccl.tests.Commands;

namespace ccl.tests
{
    [TestFixture]
    public class CommandTests
    {
        [Test]
        public void Run_registered_command()
        {
            CommandLine.Run("install", "db");
            Assert.That(InstallDatabase.IsExecuted, Is.True);
        }

        [Test]
        public void Handle_commands_that_throw_exceptions()
        {
            Assert.Throws<CommandNotRunException>(() => CommandLine.Run("throw", "exception"));
        }

        [Test]
        public void Handle_unregistered_commands()
        {
            Assert.Throws<CommandNotFoundException>(() => CommandLine.Run("unregistered", "command"));
        }

        [Test]
        public void Handle_commands_that_cannot_be_created()
        {
            Assert.Throws<CommandNotCreatedException>(() => CommandLine.Run("cannot", "create"));
        }

        [Test]
        public void Run_command_and_set_parameters()
        {
            CommandLine.Run("with", "params", "param1=value1", "-param2=33", "/param3");

            Assert.That(CommandWithParameters.Param1Value, Is.EqualTo("value1"));
            Assert.That(CommandWithParameters.Param2Value, Is.EqualTo(33));
            Assert.That(CommandWithParameters.Param3Value, Is.True);
        }

        [Test]
        public void Throw_when_required_parameter_is_not_supplied()
        {
            Assert.Throws<CommandNotCreatedException>(() => CommandLine.Run("command", "required"));
        }

        [Test]
        public void Not_set_hidden_parameter_even_if_it_is_explicitly_supplied()
        {
            CommandLine.Run("run", "hidden", "/param=hello");
            Assert.That(CommandWithHiddenParameter.ParameterValue, Is.Not.EqualTo("hello"));
        }
    }
}