text:
<?php

use Mockery as m;
use SuperClosure\Serializer;

class IronQueueTest extends PHPUnit_Framework_TestCase
{
    public function tearDown()
    {
        m::close();
    }

    public function testPushProperlyPushesJobOntoIron()
    {
        $iron = m::mock('IronMQ\IronMQ');
        $iron->shouldReceive('postMessage')->once()->with('default', 'encrypted', [])->andReturn((object) ['id' => 1]);
        $crypt = m::mock('Illuminate\Contracts\Encryption\Encrypter');
        $crypt->shouldReceive('encrypt')->once()->with(json_encode(['displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'timeout' => null, 'data' => [1, 2, 3], 'queue' => 'default']))->andReturn('encrypted');
        $queue = new Collective\IronQueue\IronQueue($iron, m::mock('Illuminate\Http\Request'), 'default', true);
        $queue->setEncrypter($crypt);
        $queue->push('foo', [1, 2, 3]);
    }

    public function testPushProperlyPushesJobOntoIronWithoutEncryption()
    {
        $iron = $iron = m::mock('IronMQ\IronMQ');
        $iron->shouldReceive('postMessage')->once()->with('default', json_encode(['displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'timeout' => null, 'data' => [1, 2, 3], 'queue' => 'default']), [])->andReturn((object) ['id' => 1]);
        $crypt = m::mock('Illuminate\Contracts\Encryption\Encrypter');
        $crypt->shouldReceive('encrypt')->never();
        $queue = new Collective\IronQueue\IronQueue($iron, m::mock('Illuminate\Http\Request'), 'default');
        $queue->setEncrypter($crypt);
        $queue->push('foo', [1, 2, 3]);
    }

    public function testDelayedPushProperlyPushesJobOntoIron()
    {
        $iron = m::mock('IronMQ\IronMQ');
        $iron->shouldReceive('postMessage')->once()->with('default', 'encrypted', ['delay' => 5])->andReturn((object) ['id' => 1]);
        $crypt = m::mock('Illuminate\Contracts\Encryption\Encrypter');
        $crypt->shouldReceive('encrypt')->once()->with(json_encode(['displayName' => 'foo', 'job' => 'foo', 'maxTries' => null, 'timeout' => null, 'data' => [1, 2, 3], 'queue' => 'default']))->andReturn('encrypted');
        $queue = new Collective\IronQueue\IronQueue($iron, m::mock('Illuminate\Http\Request'), 'default', true);
        $queue->setEncrypter($crypt);
        $queue->later(5, 'foo', [1, 2, 3]);
    }

    public function testPopProperlyPopsJobOffOfIron()
    {
        $queue = new Collective\IronQueue\IronQueue($iron = m::mock('IronMQ\IronMQ'), m::mock('Illuminate\Http\Request'), 'default', true);
        $crypt = m::mock('Illuminate\Contracts\Encryption\Encrypter');
        $queue->setEncrypter($crypt);
        $queue->setContainer(m::mock('Illuminate\Container\Container'));
        $iron->shouldReceive('reserveMessage')->once()->with('default', 60)->andReturn($job = m::mock('IronMQ_Message'));
        $job->body = 'foo';
        $crypt->shouldReceive('decrypt')->once()->with('foo')->andReturn('foo');
        $result = $queue->pop();

        $this->assertInstanceOf('Collective\IronQueue\Jobs\IronJob', $result);
    }

    public function testPopProperlyPopsJobOffOfIronWithCustomTimeout()
    {
        $queue = new Collective\IronQueue\IronQueue($iron = m::mock('IronMQ\IronMQ'), m::mock('Illuminate\Http\Request'), 'default', true, 120);
        $crypt = m::mock('Illuminate\Contracts\Encryption\Encrypter');
        $queue->setEncrypter($crypt);
        $queue->setContainer(m::mock('Illuminate\Container\Container'));
        $iron->shouldReceive('reserveMessage')->once()->with('default', 120)->andReturn($job = m::mock('IronMQ_Message'));
        $job->body = 'foo';
        $crypt->shouldReceive('decrypt')->once()->with('foo')->andReturn('foo');
        $result = $queue->pop();

        $this->assertInstanceOf('Collective\IronQueue\Jobs\IronJob', $result);
    }

    public function testPopProperlyPopsJobOffOfIronWithoutEncryption()
    {
        $queue = new Collective\IronQueue\IronQueue($iron = m::mock('IronMQ\IronMQ'), m::mock('Illuminate\Http\Request'), 'default');
        $crypt = m::mock('Illuminate\Contracts\Encryption\Encrypter');
        $queue->setEncrypter($crypt);
        $queue->setContainer(m::mock('Illuminate\Container\Container'));
        $iron->shouldReceive('reserveMessage')->once()->with('default', 60)->andReturn($job = m::mock('IronMQ_Message'));
        $job->body = 'foo';
        $crypt->shouldReceive('decrypt')->never();
        $result = $queue->pop();

        $this->assertInstanceOf('Collective\IronQueue\Jobs\IronJob', $result);
    }

    /**
     * @expectedException IronCore\HttpException
     */
    public function testDeleteJobWithExpiredReservationIdThrowsAnException()
    {
        $queue = new Collective\IronQueue\IronQueue($iron = m::mock('IronMQ\IronMQ'), m::mock('Illuminate\Http\Request'), 'default', false, 30);
        $iron->shouldReceive('deleteMessage')->with('default', 1, 'def456')->andThrow('IronCore\HttpException', '{"msg":"Reservation has timed out"}');
        // 'def456' refers to a reservation id that expired
        $queue->deleteMessage('default', 1, 'def456');
    }

    public function testPushedJobsCanBeMarshaled()
    {
        $queue = $this->getMockBuilder('Collective\IronQueue\IronQueue')->setMethods(['createPushedIronJob'])->setConstructorArgs([$iron = m::mock('IronMQ\IronMQ'), $request = m::mock('Illuminate\Http\Request'), 'default', true])->getMock();
        $crypt = m::mock('Illuminate\Contracts\Encryption\Encrypter');
        $queue->setEncrypter($crypt);
        $request->shouldReceive('header')->once()->with('iron-message-id')->andReturn('message-id');
        $request->shouldReceive('getContent')->once()->andReturn($content = json_encode(['foo' => 'bar']));
        $crypt->shouldReceive('decrypt')->once()->with($content)->andReturn($content);
        $job = (object) ['id' => 'message-id', 'body' => json_encode(['foo' => 'bar']), 'pushed' => true];
        $queue->expects($this->once())->method('createPushedIronJob')->with($this->equalTo($job))->will($this->returnValue($mockIronJob = m::mock('StdClass')));
        $mockIronJob->shouldReceive('fire')->once();

        $response = $queue->marshal();

        $this->assertInstanceOf('Illuminate\Http\Response', $response);
        $this->assertEquals(200, $response->getStatusCode());
    }
}


text:
{% extends "base.html" %}

{% block title %}Flasky - Page Not Found{% endblock %}

{% block page_content %}

Not Found - 404

{% endblock %}

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

    <meta charset="utf8"/>
    <title>PAT - Process Acceptance Testing</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

Questionnaire 1

Experiment 1 - Mechanical Turk

        <button type="submit" id="nextButton" class="btn btn-primary">Next step</button>


text:
import { AppSettings, AppSettingsTypes, OVERWRITE_SETTINGS, OVERWRITE_COLOR_THEME, SET_HIDE_LEGEND } from './types';

const initialState: AppSettings = {
  webmap: '512eef95997b4e7486cdbdc45078739d',
  title: 'GFW Mapbuilder',
  subtitle: 'Make maps that matter',
  logoUrl: 'https://my.gfw-mapbuilder.org/img/gfw-logo.png',
  logoLinkUrl: 'https://developers.globalforestwatch.org/map-builder/',
  useAlternativeLanguage: false,
  analyticsCode: 'UA-62288390-15',
  alternativeWebmap: '',
  alternativeLanguage: 'fr',
  includeMyGFWLogin: true,
  hideFooter: false,
  hideHeader: false,
  hideLegend: false,
  navLinksInNewTab: true,
  aboutLinkUrl: '',
  downloadLinkUrl: '',
  sharinghost: 'https://www.arcgis.com/',
  printServiceUrl: 'https://gis.forest-atlas.org/server/rest/services/print/ExportWebMap/GPServer/Export%20Web%20Map',
  language: 'en',
  iso: '',
  layerPanel: {
    GROUP_WEBMAP: {},
    GROUP_BASEMAP: {},
    GROUP_LC: {},
    GROUP_LCD: {},
    GROUP_IMAGERY: {},
    extraLayers: {}
  },
  narrative: '',
  alternativeNarrative: '',
  alternativeLanguageTitle: '',
  alternativeLanguageSubtitle: '',
  mapThemeIds: '',
  mapThemes: '',
  alternativeMapThemes: '',
  customColorTheme: '#f0ab00', // #f0ab00 - is the default, it will be overwritten if configed
  footerLinks: [],
  disabledAnalysisModules: []
};

export function appSettingsReducer(state = initialState, action: AppSettingsTypes): AppSettings {
  switch (action.type) {
    case OVERWRITE_SETTINGS:
      return { ...state, ...action.payload };
    case OVERWRITE_COLOR_THEME:
      return { ...state, customColorTheme: action.payload };
    case SET_HIDE_LEGEND:
      return { ...state, hideLegend: action.payload };
    default:
      return state;
  }
}


text:
Localization Utils
==================
Utility set to help on language localisation of Android and iOS apps.

* **localizable-generator:** Will generate strings.xml files for Android and all Localizable.strings for iOS from a Google Drive Spreadsheet data.
* **spreadsheet-generator:** [Only on standalone] Will populate a Google Drive Spreadsheet reading from Android strings.xml or iOS Localizable.strings files.

Fastlane usage
--------------
There's a built in integration to fastlane inside the repo. I assume you're already working with it, otherwise I encourage to to take a look at their [Fastlane Documentation](https://docs.fastlane.tools/)

Once you have fastlane setup, you just need to import our fastlane file (so that the action ek_locales action is imported)

Add the following import just after `fastlane version x.x.x` on your fastfile:

```
fastlane_version "2.32.1"

import_from_git(url: 'git@github.com:elikohen/EKLocalesGenerator.git', path: 'fastlane/Fastfile')
```

So now you're ready to use the ek_locales action. It contains the following parameters:

- *spreadsheet_name*: Name of spreadsheet. I.E. if spreadsheet is '[Localizables] myProject', you must set `myProject`
- *spreadsheet_id*: [Optional*] Id of spreadsheet. I.E. if url is _https://docs.google.com/spreadsheets/d/1G5vMNUlm7HlsO1MMUShlUdsm6DDZI4L4HZmvOaWcqlw/edit?usp=sharing_ you must set `1G5vMNUlm7HlsO1MMUShlUdsm6DDZI4L4HZmvOaWcqlw`. ***Note**: If you are using company **team drive** to place the spreadsheet this becomes **mandatory** as the script cannot search inside team drives.
- *localizables_dir*: Directory of .lproj files on iOS and res directory on android
- *google\_client\_id*: [Optional] If you want to use your own google apps account with google drive this is the Google apps client id
- *google\_client\_secret*: [Optional] If you want to use your own google apps account with google drive this is the Google apps client secret of the oauth key
- *repository_path*: [optional] Path to the repository if it's located on a subfolder. Usefull if you're using c.i. and it checkouts a specific branch to a temporary folder-
- *mark_unused*: [Optional] Mark all the unused strings in spreadsheet
- *ios_extension*: [Optional] When using iOS and swift, create all helpers as an extension of `String` instead of using the `Localizables` class. (default:
- *ios_suffix*: [optional] Suffix to append to all vars and function helpers.

examples:

```
ek_locales(
	spreadsheet_name: 'myProject',
	localizables_dir: 'myProject/i18n/'
)
```
```
ek_locales(
	google_client_id: 'someid-somehash.apps.googleusercontent.com',
	google_client_secret: 'someHexa64Secret'',
	spreadsheet_name: 'myProject',
	spreadsheet_id: '1G5vMNUlm7HlsO1MMUShlUdsm6DDZI4L4HZmvOaWcqlw',
	localizables_dir: 'myProject/i18n/',
	repository_path: 'some/temporal/subdir/',
	ios_extension: true,
	ios_suffix: 'Localized',
	mark_unused: true
)
```

Standalone Installation
-----------------------
Ruby >= 1.9.3 is required. If you require installing it and don't know how to do it, try with [RVM](https://rvm.io/rvm/install/).

In order to use the scripts, all the required gems must be installed, so type this on the root folder:

	bundle install

It will install all dependencies.

If bundle command is not installed please follow this link: http://bundler.io/

localizable-generator Usage
---------------------------

Those are the generator parameters, you can show all them by typing -h

	localizable-generator (c) 2019 EKGDev <elikohen@gmail.com>
		--client-id                  google Client id
	    -l, --client-secret              google Client secret
	    -s example-spreadsheet,          Spreadsheet containing the localization info
		--spreadsheet
		--spreadsheet-id             Spreadsheet id shown in the path of the url (just before /edit)
		--[no-]just-credentials      [Optional] If enabled, script just creates google credentials
	    -i /the_path/Localizables/,      Path to the iOS localization directory
		--output-ios
	    -n LocalizedConstants,           [Optional] Constants localizable name for iOS
		--ios-constants-name
	    -p, --ios-constants-path         [Optional] Constants localizable path for iOS
	    -f NSLocalizedString,            [Optional] Constants localizable function for iOS
		--ios-constants-function
	    -x                               [Optional] Whether to extend String or use LocalizedString struct
		--[no-]ios-constants-extension
	    -o, --ios-constants-sufix        [Optional] sufix to use on elements
	    -u, --[no-]ios-just-swift        [Optional] Whether to build constants just for swift
		--[no-]ios-add-base          [Optional] Whether to add Base.lproj linked with the default language
	    -a /the_path/res/,               Path to the resource directory of an Android project
		--output-android
	    -j /the_path/localizables.json,  Path to the resource file of the output as json
		--output-json
	    -k, --[no-]keep-keys             [Optional] Whether to maintain original keys or not
	    -c, --[no-]check-unused          [Optional] Whether to check unused keys on project
	    -m, --[no-]check-unused-mark     [Optional] When checking keys (--check-unused) -> mark them on spreadsheet prepending [u]
	    -h, --help                       Show this message
	    -v, --version                    Print version

It might sound weird or difficult but I'll explain them

- **Client**, this is created going thru https://console.developers.google.com, follow the instructions to create a Client ID for native application, download the JSON and enter the download path here. After creating a project go to *APIs & auth* then *Credentials*, click on *Create new Client ID*, select *Installed Application* and then you can download the json. There you can find the client_id and secret required by the script
- **Spreadsheet name** is part of the spreadsheet name without the [Localizables] token. For instance if the spreadsheet is called *[Localizables] Ztory* you can type just *Ztory* on this parameter.
- **iOS, Android and JSON paths:** It must be at least one of this parameters. In case of iOS it should point to the folder where are the Localizables.strings, on android it should point to the .../res folder.
- **check-unused** It shows a list of all keys that are not used on the project (it can provide false positives if you concatenate strings to access them).
- **check-unused-mark** when checking unused if this parameter is provided, the script will prepend [u] to each unused key on the google spreadsheet so that in the next generation it won't be generated.
- *trick:* If you want one of the keys (spreadsheet row) just for one of the platforms, just type [i], [a] or [j] as a prefix for the key.

An example will show everything better.

- This will generate just iOS localisables of a "MyApp" ios project located under user/workspace using a spreadsheet called `[Localizables] MyApp`

		localizable-generator --client-id=someid-somehash.apps.googleusercontent.com --client-secret=someHexa64Secret -s MyApp -i ~/workspace/MyApp/res/i18n/

- This will generate just iOS localisables of a "MyApp" ios project located under user/workspace using a spreadsheet whose id is `1G5vMNUlm7HlsO1MMUShlUdsm6DDZI4L4HZmvOaWcqlw`

		localizable-generator --client-id=someid-somehash.apps.googleusercontent.com --client-secret=someHexa64Secret -s MyApp --spreadsheet-id= 1G5vMNUlm7HlsO1MMUShlUdsm6DDZI4L4HZmvOaWcqlw -i ~/workspace/MyApp/res/i18n/

- And this will generate both iOS and Android

		localizable-generator --client-id=someid-somehash.apps.googleusercontent.com --client-secret=someHexa64Secret -s MyApp -i ~/workspace/MyAppIOS/res/i18n/ -a ~/workspace/MyAppAndroid/app/res/

Google Drive spreadseet
----------------------------------

Take this spreadsheet as an example <https://docs.google.com/spreadsheet/ccc?key=0AiB94r-ubs9sdHBQYTBOcEJ2TV9KeG5qT2lWSWhOOXc&usp=sharing>

* A column will **always** contain the locale key *in a readable way* (with spaces, no slashes, underscores, etc). The script will camel case keys on iOS and use underscores on android.

* The **[key]** token on column A indicates start of localizables, so all the next columns to the right will have (in the same row than the [key] token) the language indicator. If you want to set one language as default, just append **\*** to the language.

* The **[COMMENT]** token (always in the A column) indicates a comment, to use as separator in localizable files. It is recommended to translate also the comment for each column so that the generated file will be even more readable.

* By default any translation you write will be generated for all platforms.
	* If you want to restrict one key just for android prepend **[a]** to the key.
	* To restrict just for iOS prepend **[i]** to the key.
* The **[END]** token is required at the end of the column A to indicate that there are no more keys to generate.

It is important to maintain the Spreadsheet file with colors (on important rows, columns, comments) so that it becomes more readable. You can use any style modifier you want as it won't affect the generation.

Common issues
----------------------------------
### Cannot install nokogiri gem
In their [home page](www.nokogiri.org) you can find an excellent [tutorial](http://www.nokogiri.org/tutorials/installing_nokogiri.html#install_with_included_libraries__recommended_). In my case I had a problem with conflicting libxml2 libraries because of homebrew usage. The solution they propose of unlinking `xz` and linking it again worked perfectly:

	brew unlink xz
	sudo gem install nokogiri
	brew link xz

### Open ssl issue
Some of you are having a ssl issue related with OPENSSLv3 and rvm. This is related of ruby using a the wrong system certificates. If you fall into that please reinstall your current ruby version using the following command:

`rvm reinstall [yourversion] --disable-binary`

Helper Script
----------------------------------
This is a helper script to place on your root project folder that downloads localizable script and executes it. Just change the line that starts with *./localizable-generator* with your own values.

    #!/bin/bash
    dir="$HOME/.ekscripts/locales-generator"
    projectDir=`pwd`
    if [ -d "$dir" -a ! -h "$dir" ]
    then
      echo "$dir found, updating script"
      cd "$dir" && git fetch --tags && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))
      echo "Updated. NOTE: if some gems are missing go to $dir and type 'bundle update'"
    else
      echo "Error: $dir not found, creating it and cloning script"
      mkdir -p "$dir"
      git clone "https://github.com/elikohen/EKLocalesGenerator.git" "$dir" > /dev/null && cd "$dir" && git checkout $(git describe --tags $(git rev-list --tags --max-count=1)) && bundle install
    fi

    cd "$dir"

    ./localizable-generator --client-id=someid-somehash.apps.googleusercontent.com --client-secret=someHexa64Secret -s Project_name -i "$projectDir/path_where_Localizable.strings_is_placed/" $@
    cd "$projectDir"

- - -

I hope this will help you in your projects. If you have any doubt just open an Issue and ask for it.

- Initial version created in [Mobivery](https://github.com/mobivery) (now [AuroraLabs](http://www.auroralabs.es/?lang=es)) with love
- Thanks also to [Christian Ronningen](https://github.com/ChristianRonningen) for the support!


text:
HIVE_HOST=''
HIVE_USER=''
HIVE_PASS=''
HIVE_PORT=3306
EHIVE_DRIVER="mysql" # This should not change unless you know what you are doing
KILL_HOST=''
KILL_USER=''
KILL_PASS=''
KILL_PORT=3306
KILL_DBNAME="gb_kill_list"

USAGE=0
INIT_PIPE=1
RUN_PIPE=1
BASE_UNIPROT_PATH="$BLASTDB_DIR/uniprot"
ENSEMBL_BASE=$ENSCODE
while getopts "s:d:h:u:p:P:IRj:k:l:m:n:" o; do
    case $o in
        d ) BASE_UNIPROT_PATH=$OPTARG;;
        s ) ENSEMBL_BASE=$OPTARG;;
        h ) HIVE_HOST=$OPTARG;;
        u ) HIVE_USER=$OPTARG;;
        p ) HIVE_PASS=$OPTARG;;
        P ) HIVE_PORT=$OPTARG;;
        j ) KILL_HOST=$OPTARG;;
        k ) KILL_USER=$OPTARG;;
        l ) KILL_PASS=$OPTARG;;
        m ) KILL_PORT=$OPTARG;;
        n ) KILL_DBNAME=$OPTARG;;
        I ) RUN_PIPE=0;;
        R ) INIT_PIPE=0;;
        * ) USAGE=1;;
    esac
done
export EMBL2FASTA_SCRIPT="$ENSEMBL_BASE/ensembl-analysis/scripts/databases/EMBL2fasta.pl"
export PROCESS_ISOFORMS_SCRIPT="$ENSEMBL_BASE/ensembl-analysis/scripts/databases/process_uniprot_isoforms.pl"

if [ $USAGE -eq 1 ]; then
  echo "You should not need to change anything, it should by default init the pipeline and start running it."
  echo "  d Destination directory, default is $BLASTDB_DIR/uniprot"
  echo "  s Base directory where your Perl API are, default is $ENSCODE"
  echo "  h Host server for the Hive pipeline database"
  echo "  u User name for the Hive pipeline database"
  echo "  p Password for the Hive pipeline database"
  echo "  P Port for the Hive pipeline database, default is 3306"
  echo "  j Host server for the kill list database, default to Hive host"
  echo "  k User name for the kill list database, default to Hive user"
  echo "  l Password for the kill list database, default to Hive password"
  echo "  m Port for the Hive pipeline database, default to Hive port"
  echo "  n Name of the kill list database, default is gb_kill_list"
  echo "  I To only run the init script"
  echo "  R To only run the pipeline"
  echo
  exit 1
fi

###
## You should only change values above this line.
## Parameters below this line should stay as they are
###
for S in "$EMBL2FASTA_SCRIPT" "$PROCESS_ISOFORMS_SCRIPT"; do
    if [ ! -e "$S" ]; then
        printf " \e[31m%s\e[0m does not exist\n" "$S"
    fi
done

for S in "ensembl-hive" "ensembl" "ensembl-analysis" "ensembl-killlist"; do
    if [ "`echo $PERL5LIB | sed \"s/$S\/modules//\"`" = "$PERL5LIB" ]; then
        printf " \e[31m%s\e[0m repository is not in your PERL5LIB\n" "$S"
    fi
done

if [ -z "$KILL_HOST" ]; then
  KILL_HOST="$HIVE_HOST";
fi

if [ -z "$KILL_PORT" ]; then
  KILL_PORT="$HIVE_PORT";
fi

if [ -z "$KILL_USER" ]; then
  KILL_USER="$HIVE_USER";
fi

if [ -z "$KILL_PASS" ]; then
  KILL_PASS="$HIVE_PASS";
fi

export UNIPROT_VERSION=`wget -S --spider www.uniprot.org 2>&1 | grep 'X-UniProt-Release' | awk '{print $2}'`
export UNIPROT_DIR="$BASE_UNIPROT_PATH/uniprot_$UNIPROT_VERSION"
if [ -e "$UNIPROT_DIR" ]; then
    printf "The directory \e[31m%s\e[0m already exists:\n \e[32m-\e[0m this database has already been successfully created\n \e[31m-\e[0m delete the directory %s and start the pipeline\n\n" "$UNIPROT_DIR" "$UNIPROT_DIR"
fi
export UNIPROT_DATE=`wget -S --spider www.uniprot.org 2>&1 | grep 'Last-Modified' | sed 's/\s*Last-Modified:\s\+//'`
# Full connection info for the hive pipeline db, needs write access
pipeline_name="create_uniprot_$UNIPROT_VERSION"
HIVE_DBNAME="${USER}_$pipeline_name"
echo "Using ${HIVE_DBNAME} on ${HIVE_HOST} as hive database"
echo "Using ${KILL_DBNAME} on ${KILL_HOST} as kill list database"

echo "Using $UNIPROT_DIR as working directory"

init_pipe="init_pipeline.pl"
if [ -e "$ENSEMBL_BASE/ensembl-hive/scripts/$init_pipe" ]; then
    init_pipe="$ENSEMBL_BASE/ensembl-hive/scripts/$init_pipe"
fi
if [ $INIT_PIPE -eq 1 ]; then
  perl $init_pipe Bio::EnsEMBL::Analysis::Hive::Config::UniProtDB_conf -host ${HIVE_HOST} -port ${HIVE_PORT} -user ${HIVE_USER} -password ${HIVE_PASS} -dbname ${HIVE_DBNAME} -pipeline_name ${pipeline_name} -kill -kill_list_host "$KILL_HOST" -kill_list_port "$KILL_PORT" -kill_list_user "$KILL_USER" -kill_list_pass "$KILL_PASS" -kill_list_dbname "$KILL_DBNAME"
  if [ $? -ne 0 ]; then
    echo "The init script failed"
    exit 1;
  fi
fi

export EHIVE_URL=$EHIVE_DRIVER://$HIVE_USER:$HIVE_PASS@$HIVE_HOST:$HIVE_PORT/$HIVE_DBNAME
echo "Hive URL: $EHIVE_URL"

beekeeper="beekeeper.pl"
if [ -e "$ENSEMBL_BASE/ensembl-hive/scripts/$beekeeper" ]; then
    beekeeper="$ENSEMBL_BASE/ensembl-hive/scripts/$beekeeper"
fi
if [ $RUN_PIPE -eq 1 ]; then
  perl $beekeeper -url $EHIVE_URL -loop -can_respecialize 1
  if [ $? -ne 0 ]; then
    echo "Beekeeper failed"
    exit 1;
  fi
fi


text:
package com.ning.http.client.webdav;

import com.ning.http.client.AsyncCompletionHandlerBase;
import com.ning.http.client.AsyncHandler;
import com.ning.http.client.HttpResponseBodyPart;
import com.ning.http.client.HttpResponseHeaders;
import com.ning.http.client.HttpResponseStatus;
import com.ning.http.client.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Simple {@link AsyncHandler} that add support for WebDav's response manipulation.
 *
 * @param <T>
 */
public abstract class WebDavCompletionHandlerBase<T> implements AsyncHandler<T> {
    private final Logger logger = LoggerFactory.getLogger(AsyncCompletionHandlerBase.class);

    private final List<HttpResponseBodyPart> bodies =
            Collections.synchronizedList(new ArrayList<HttpResponseBodyPart>());
    private HttpResponseStatus status;
    private HttpResponseHeaders headers;

    /**
     * {@inheritDoc}
     */
    /* @Override */
    public final STATE onBodyPartReceived(final HttpResponseBodyPart content) throws Exception {
        bodies.add(content);
        return STATE.CONTINUE;
    }

    /**
     * {@inheritDoc}
     */
    /* @Override */
    public final STATE onStatusReceived(final HttpResponseStatus status) throws Exception {
        this.status = status;
        return STATE.CONTINUE;
    }

    /**
     * {@inheritDoc}
     */
    /* @Override */
    public final STATE onHeadersReceived(final HttpResponseHeaders headers) throws Exception {
        this.headers = headers;
        return STATE.CONTINUE;
    }

    /**
     * {@inheritDoc}
     */
    /* @Override */
    public final T onCompleted() throws Exception {
        if (status != null) {
            Response response = status.provider().prepareResponse(status, headers, bodies);
            Document document = null;
            if (status.getStatusCode() == 207) {
                document = readXMLResponse(response.getResponseBodyAsStream());
            }
            return onCompleted(new WebDavResponse(status.provider().prepareResponse(status, headers, bodies), document));
        } else {
            throw new IllegalStateException("Status is null");
        }
    }

    /**
     * {@inheritDoc}
     */
    /* @Override */
    public void onThrowable(Throwable t) {
        logger.debug(t.getMessage(), t);
    }

    /**
     * Invoked once the HTTP response has been fully read.
     *
     * @param response The {@link com.ning.http.client.Response}
     * @return Type of the value that will be returned by the associated {@link java.util.concurrent.Future}
     */
    abstract public T onCompleted(WebDavResponse response) throws Exception;

    private class HttpStatusWrapper extends HttpResponseStatus {

        private final HttpResponseStatus wrapper;

        private final String statusText;

        private final int statusCode;

        public HttpStatusWrapper(HttpResponseStatus wrapper, String statusText, int statusCode) {
            super(wrapper.getUrl(), wrapper.provider());
            this.wrapper = wrapper;
            this.statusText = statusText;
            this.statusCode = statusCode;
        }

        @Override
        public int getStatusCode() {
            return (statusText == null ? wrapper.getStatusCode() : statusCode);
        }

        @Override
        public String getStatusText() {
            return (statusText == null ? wrapper.getStatusText() : statusText);
        }

        @Override
        public String getProtocolName() {
            return wrapper.getProtocolName();
        }

        @Override
        public int getProtocolMajorVersion() {
            return wrapper.getProtocolMajorVersion();
        }

        @Override
        public int getProtocolMinorVersion() {
            return wrapper.getProtocolMinorVersion();
        }

        @Override
        public String getProtocolText() {
            return wrapper.getStatusText();
        }
    }

    private Document readXMLResponse(InputStream stream) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        Document document = null;
        try {
            document = factory.newDocumentBuilder().parse(stream);
            parse(document);
        } catch (SAXException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e);
        } catch (ParserConfigurationException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
        return document;
    }

    private void parse(Document document) {
        Element element = document.getDocumentElement();
        NodeList statusNode = element.getElementsByTagName("status");
        for (int i = 0; i < statusNode.getLength(); i++) {
            Node node = statusNode.item(i);

            String value = node.getFirstChild().getNodeValue();
            int statusCode = Integer.valueOf(value.substring(value.indexOf(" "), value.lastIndexOf(" ")).trim());
            String statusText = value.substring(value.lastIndexOf(" "));
            status = new HttpStatusWrapper(status, statusText, statusCode);
        }
    }
}


text:
function runAtlasStepRecovery(perturbation, example_options)
% NOTEST
% This is an initial test of our newly developed recovery planner. It starts
% the robot with an initial perturbation and attempts to come to rest standing
% up.
% @param perturbation the disturbance, expressed as initial CoM velocity in [x; y]
% @option use_bullet
% @option use_angular_momentum
% @options navgoal
%

checkDependency('gurobi');
checkDependency('lcmgl');

if nargin<2, example_options=struct(); end
if ~isfield(example_options,'use_bullet'), example_options.use_bullet = false; end
if ~isfield(example_options,'use_angular_momentum'), example_options.use_angular_momentum = false; end
if ~isfield(example_options,'navgoal')
  example_options.navgoal = [1.5;0;0;0;0;0];
end
if ~isfield(example_options,'terrain'), example_options.terrain = RigidBodyFlatTerrain; end

% silence some warnings
warning('off','Drake:RigidBodyManipulator:UnsupportedContactPoints')
warning('off','Drake:RigidBodyManipulator:UnsupportedVelocityLimits')

% construct robot model
options.floating = true;
options.ignore_friction = true;
options.dt = 0.001;
r = Atlas(fullfile(getDrakePath,'examples','Atlas','urdf','atlas_minimal_contact.urdf'),options);
r = r.removeCollisionGroupsExcept({'heel','toe'});
r = compile(r);

% set initial state to fixed point
load(fullfile(getDrakePath,'examples','Atlas','data','atlas_fp.mat'));
% xstar(r.getNumPositions() + (1:2)) = [0.3; 0.3];
xstar = Point(r.getStateFrame(), xstar);
% xstar.r_leg_hpy = -0.9;
% xstar.r_leg_kny = 1.7;
% xstar = double(xstar);
x0 = xstar;
nq = r.getNumPositions();
x0(nq + (1:2)) = x0(nq + (1:2)) + perturbation;

v = r.constructVisualizer;
v.display_dt = 0.001;

recovery_planner = RecoveryPlanner([], [], false);

zmpact = [];

combined_xtraj = [];

for iter = 1:3
  r = r.setInitialState(x0);
  v.draw(0, x0)

  % profile on
  [walking_plan_data, recovery_plan] = planning_pipeline(recovery_planner, r, x0, zmpact, xstar, nq);
  % profile viewer

  walking_plan_data.robot = r;

  pm_biped = PointMassBiped(recovery_plan.omega);
  [pm_traj, pm_v] = walking_plan_data.simulatePointMassBiped(pm_biped);
  pm_v.playback(pm_traj, struct('slider', true));

  ts = walking_plan_data.zmptraj.getBreaks();

  % plot walking traj in drake viewer
  lcmgl = drake.util.BotLCMGLClient(lcm.lcm.LCM.getSingleton(),'walking-plan');

  for i=1:length(ts)
    lcmgl.glColor3f(0, 0, 1);
    lcmgl.sphere([walking_plan_data.comtraj.eval(ts(i));0], 0.01, 20, 20);
    lcmgl.glColor3f(0, 1, 0);
    lcmgl.sphere([walking_plan_data.zmptraj.eval(ts(i));0], 0.01, 20, 20);
  end
  lcmgl.switchBuffers();
  % keyboard()

  planeval = bipedControllers.BipedPlanEval(r, walking_plan_data);
  control = bipedControllers.InstantaneousQPController(r, []);
  plancontroller = bipedControllers.BipedPlanEvalAndControlSystem(r, control, planeval);
  sys = feedback(r, plancontroller);

  output_select(1).system=1;
  output_select(1).output=1;
  sys = mimoCascade(sys,v,[],[],output_select);

  T = walking_plan_data.duration;

  traj = simulate(sys, [0, T], x0, struct('gui_control_interface', true));

  playback(v,traj,struct('slider',true));

  tsample = 0:0.01:(T-0.01);
  rsole = zeros(6, length(tsample));
  lsole = zeros(6, length(tsample));
  for j = 1:length(tsample)
    t = tsample(j);
    x = traj.eval(t);
    kinsol = r.doKinematics(x(1:r.getNumPositions()));
    rsole(:,j) = r.forwardKin(kinsol, r.foot_frame_id.right, [0;0;0], 1);
    lsole(:,j) = r.forwardKin(kinsol, r.foot_frame_id.left, [0;0;0], 1);
  end
  figure(321)
  subplot 212
  hold on
  plot(tsample, rsole(3,:), 'b.-')
  plot(tsample, lsole(3,:), 'g.-')
  xlim([0, T]);

  x0 = traj.eval(tsample(end));

  r.plotWalkingTraj(traj, walking_plan_data);

  % keyboard();

  breaks = traj.getBreaks();
  traj = PPTrajectory(foh(breaks, traj.eval(breaks)));
  if isempty(combined_xtraj)
    combined_xtraj = traj;
  else
    b = combined_xtraj.getBreaks();
    traj = traj.shiftTime(b(end)-breaks(1));
    combined_xtraj = combined_xtraj.append(traj);
  end
  break;
end

combined_xtraj = combined_xtraj.setOutputFrame(r.getStateFrame());
v.playback(combined_xtraj, struct('slider', true));

% TIMEOUT 1500

end

function [walking_plan_data, recovery_plan] = planning_pipeline(recovery_planner, r, x0, zmpact, xstar, nq)
  % Put into its own function to make profiling easier
  t0 = tic();
  recovery_plan = recovery_planner.solveBipedProblem(r, x0, zmpact, 0);
  toc(t0);
  walking_plan_data = QPLocomotionPlan.from_point_mass_biped_plan(recovery_plan, r, x0);
  walking_plan_data.qtraj = xstar(1:nq);
  % walking_plan_data = DRCWalkingPlanData.from_walking_plan_t(walking_plan_data.to_walking_plan_t());
end


text:
<?php

require_once(dirname(__FILE__).'/../bootstrap.php');

use Bundle\sfFormBundle\Validator\FromDescription;
use Bundle\sfFormBundle\Validator\String;
use Bundle\sfFormBundle\Validator\Decorator;
use Bundle\sfFormBundle\Validator\Integer;

use Symfony\Components\Yaml\Yaml;

// var_dump(Yaml::load('[ { toto:titi } ]'));
// die();

$t = new lime_test(98);

// var_dump($results); die();
$tests = array(
  // 'Bundle\sfFormBundle\Validator\Integer',
  // 'Bundle\sfFormBundle\Validator\Integer()',
  // 'Bundle\\sfFormBundle\\Validator\\Integer({min: 18})',
  // 'Bundle\\sfFormBundle\\Validator\\Integer(  {  min:  18  }  )',
  // 'Bundle\\sfFormBundle\\Validator\\Integer({min: 18}, {required: "This is required"})',
  '(Bundle\\sfFormBundle\\Validator\\Integer)',
  // '
  //  (Bundle\\sfFormBundle\\Validator\\Integer)
  // ',
  // '(
  //   Bundle\\sfFormBundle\\Validator\\Integer
  //  )',
  //
  // 'Bundle\\sfFormBundle\\Validator\\Integer and Bundle\\sfFormBundle\\Validator\\String',
  // 'Bundle\\sfFormBundle\\Validator\\Integer or Bundle\\sfFormBundle\\Validator\\String',
  // 'Bundle\\sfFormBundle\\Validator\\Integer and (Bundle\\sfFormBundle\\Validator\\String or Bundle\\sfFormBundle\\Validator\\Email)',
  //
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer',
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer()',
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer({min: 18})',
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer({min: 18}, {required: "This is required"})',
  // '(age:Bundle\\sfFormBundle\\Validator\\Integer)',
  // '
  //   (age:Bundle\\sfFormBundle\\Validator\\Integer)
  // ',
  // '(
  //   age:Bundle\\sfFormBundle\\Validator\\Integer
  //  )',
  //
  // 'age == password',
  // 'age ==() password',
  // 'age ==({}, {invalid: "Not equal."}) password',
  // 'age ==(  {  },  {  invalid:  "Not equal."  }  ) password',
  // 'age ==({required: true}, {invalid: "Not equal."}) password',
  // 'age ==({}) password',
  // "age
  //  ==
  //  password",
  // '(age == password)',
  // '
  //   (age == password)
  // ',
  // '(
  //   age == password
  //  )',
  //
  // 'age != password',
  // 'age > password',
  // 'age >= password',
  // 'age <= password',
  // 'age > password',
  //
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer and password:Bundle\\sfFormBundle\\Validator\\String',
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer and() password:Bundle\\sfFormBundle\\Validator\\String()',
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer and({}, {invalid: "This is invalid."}) password:Bundle\\sfFormBundle\\Validator\\String({required: true}, {min_length: Min length error message.})',
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer and({required: true}, {invalid: "This is invalid."}) password:Bundle\\sfFormBundle\\Validator\\String',
  // 'age:Bundle\\sfFormBundle\\Validator\\Integer and({}) password:Bundle\\sfFormBundle\\Validator\\String({}, {})',
  // "age:Bundle\\sfFormBundle\\Validator\\Integer
  //  and
  //  password:Bundle\\sfFormBundle\\Validator\\String",
  //  '(age:Bundle\\sfFormBundle\\Validator\\Integer and password:Bundle\\sfFormBundle\\Validator\\String)',
  //  'age:Bundle\\sfFormBundle\\Validator\\Integer or password:Bundle\\sfFormBundle\\Validator\\String',
  //  '
  //   (age:Bundle\\sfFormBundle\\Validator\\Integer or password:Bundle\\sfFormBundle\\Validator\\String)
  //  ',
  //  '(age:Bundle\\sfFormBundle\\Validator\\Integer or password:Bundle\\sfFormBundle\\Validator\\String)',
  //  '(
  //    age:Bundle\\sfFormBundle\\Validator\\Integer or password:Bundle\\sfFormBundle\\Validator\\String
  //   )',
  // '
  //  (
  //   age:Bundle\\sfFormBundle\\Validator\\Integer
  //    or
  //   password:Bundle\\sfFormBundle\\Validator\\String
  //  )
  // ',
  //
  // "
  //  (first_name:Bundle\\sfFormBundle\\Validator\\String or age:Bundle\\sfFormBundle\\Validator\\Integer)
  //   and
  //  age:Bundle\\sfFormBundle\\Validator\\Integer({min: 18}, {required: \"This is required.\"})
  //   or
  //  (
  //    age:Bundle\\sfFormBundle\\Validator\\Integer({max: 18})
  //     and
  //    is_young:Bundle\\sfFormBundle\\Validator\\Boolean({required: true})
  //  )
  // ",
  //
  // 'email:Bundle\\sfFormBundle\\Validator\\Email and (age:Bundle\\sfFormBundle\\Validator\\Integer({min: 18}) or (age:Bundle\\sfFormBundle\\Validator\\Integer({max: 18}) and is_young:Boolean({required: true})))',
  // '(password == password_bis) and begin_date <= end_date and password:Bundle\\sfFormBundle\\Validator\\String({min_length: 4, max_length: 18})',
  // 'countries:Bundle\\sfFormBundle\\Validator\\Choice({choices: [France, USA, Italy, Spain]}) and password ==({}, {invalid: "Passwords must be the same (%left_field% != %right_field%)"}) password_bis and begin_date <= end_date and password:Bundle\\sfFormBundle\\Validator\\String({min_length: 4, max_length: 18})',
);

foreach ($tests as $test)
{
  $v = new FromDescription($test);

  $embedValidator = $v->getValidator();

  eval('$evaledValidator = '.$v->asPhp().';');

  $t->is($evaledValidator->asString(), $v->asString(), sprintf('FromDescription is able to parse "%s"', str_replace("\n", '\n', $test)));

  $v1 = new FromDescription($embedValidator->asString());
  $embedValidator1 = $v1->getValidator();

  $v2 = new FromDescription($embedValidator1->asString());

  $t->is($v1->asString(), $v2->asString(), sprintf('FromDescription is able to parse "%s"', str_replace("\n", '\n', $test)));

}


text:
package inflect

import (
	/* "bytes" */

	"fmt"
	"regexp"
	"strconv"
	"strings"
	"unicode"
)

// used by rulesets
type Rule struct {
	suffix      string
	replacement string
	exact       bool
}

// a Ruleset is the config of pluralization rules
// you can extend the rules with the Add* methods
type Ruleset struct {
	uncountables   map[string]bool
	plurals        []*Rule
	singulars      []*Rule
	humans         []*Rule
	acronyms       []*Rule
	acronymMatcher *regexp.Regexp
}

// create a blank ruleset. Unless you are going to
// build your own rules from scratch you probably
// won't need this and can just use the defaultRuleset
// via the global inflect.* methods
func NewRuleset() *Ruleset {
	rs := new(Ruleset)
	rs.uncountables = make(map[string]bool)
	rs.plurals = make([]*Rule, 0)
	rs.singulars = make([]*Rule, 0)
	rs.humans = make([]*Rule, 0)
	rs.acronyms = make([]*Rule, 0)
	return rs
}

// create a new ruleset and load it with the default
// set of common English pluralization rules
func NewDefaultRuleset() *Ruleset {
	rs := NewRuleset()
	rs.AddPlural("s", "s")
	rs.AddPlural("testis", "testes")
	rs.AddPlural("axis", "axes")
	rs.AddPlural("octopus", "octopi")
	rs.AddPlural("virus", "viri")
	rs.AddPlural("octopi", "octopi")
	rs.AddPlural("viri", "viri")
	rs.AddPlural("alias", "aliases")
	rs.AddPlural("status", "statuses")
	rs.AddPlural("bus", "buses")
	rs.AddPlural("buffalo", "buffaloes")
	rs.AddPlural("tomato", "tomatoes")
	rs.AddPlural("tum", "ta")
	rs.AddPlural("ium", "ia")
	rs.AddPlural("ta", "ta")
	rs.AddPlural("ia", "ia")
	rs.AddPlural("sis", "ses")
	rs.AddPlural("lf", "lves")
	rs.AddPlural("rf", "rves")
	rs.AddPlural("afe", "aves")
	rs.AddPlural("bfe", "bves")
	rs.AddPlural("cfe", "cves")
	rs.AddPlural("dfe", "dves")
	rs.AddPlural("efe", "eves")
	rs.AddPlural("gfe", "gves")
	rs.AddPlural("hfe", "hves")
	rs.AddPlural("ife", "ives")
	rs.AddPlural("jfe", "jves")
	rs.AddPlural("kfe", "kves")
	rs.AddPlural("lfe", "lves")
	rs.AddPlural("mfe", "mves")
	rs.AddPlural("nfe", "nves")
	rs.AddPlural("ofe", "oves")
	rs.AddPlural("pfe", "pves")
	rs.AddPlural("qfe", "qves")
	rs.AddPlural("rfe", "rves")
	rs.AddPlural("sfe", "sves")
	rs.AddPlural("tfe", "tves")
	rs.AddPlural("ufe", "uves")
	rs.AddPlural("vfe", "vves")
	rs.AddPlural("wfe", "wves")
	rs.AddPlural("xfe", "xves")
	rs.AddPlural("yfe", "yves")
	rs.AddPlural("zfe", "zves")
	rs.AddPlural("hive", "hives")
	rs.AddPlural("quy", "quies")
	rs.AddPlural("by", "bies")
	rs.AddPlural("cy", "cies")
	rs.AddPlural("dy", "dies")
	rs.AddPlural("fy", "fies")
	rs.AddPlural("gy", "gies")
	rs.AddPlural("hy", "hies")
	rs.AddPlural("jy", "jies")
	rs.AddPlural("ky", "kies")
	rs.AddPlural("ly", "lies")
	rs.AddPlural("my", "mies")
	rs.AddPlural("ny", "nies")
	rs.AddPlural("py", "pies")
	rs.AddPlural("qy", "qies")
	rs.AddPlural("ry", "ries")
	rs.AddPlural("sy", "sies")
	rs.AddPlural("ty", "ties")
	rs.AddPlural("vy", "vies")
	rs.AddPlural("wy", "wies")
	rs.AddPlural("xy", "xies")
	rs.AddPlural("zy", "zies")
	rs.AddPlural("x", "xes")
	rs.AddPlural("ch", "ches")
	rs.AddPlural("ss", "sses")
	rs.AddPlural("sh", "shes")
	rs.AddPlural("matrix", "matrices")
	rs.AddPlural("vertix", "vertices")
	rs.AddPlural("indix", "indices")
	rs.AddPlural("matrex", "matrices")
	rs.AddPlural("vertex", "vertices")
	rs.AddPlural("index", "indices")
	rs.AddPlural("mouse", "mice")
	rs.AddPlural("louse", "lice")
	rs.AddPlural("mice", "mice")
	rs.AddPlural("lice", "lice")
	rs.AddPluralExact("ox", "oxen", true)
	rs.AddPluralExact("oxen", "oxen", true)
	rs.AddPluralExact("quiz", "quizzes", true)
	rs.AddSingular("s", "")
	rs.AddSingular("news", "news")
	rs.AddSingular("ta", "tum")
	rs.AddSingular("ia", "ium")
	rs.AddSingular("analyses", "analysis")
	rs.AddSingular("bases", "basis")
	rs.AddSingular("diagnoses", "diagnosis")
	rs.AddSingular("parentheses", "parenthesis")
	rs.AddSingular("prognoses", "prognosis")
	rs.AddSingular("synopses", "synopsis")
	rs.AddSingular("theses", "thesis")
	rs.AddSingular("analyses", "analysis")
	rs.AddSingular("aves", "afe")
	rs.AddSingular("bves", "bfe")
	rs.AddSingular("cves", "cfe")
	rs.AddSingular("dves", "dfe")
	rs.AddSingular("eves", "efe")
	rs.AddSingular("gves", "gfe")
	rs.AddSingular("hves", "hfe")
	rs.AddSingular("ives", "ife")
	rs.AddSingular("jves", "jfe")
	rs.AddSingular("kves", "kfe")
	rs.AddSingular("lves", "lfe")
	rs.AddSingular("mves", "mfe")
	rs.AddSingular("nves", "nfe")
	rs.AddSingular("oves", "ofe")
	rs.AddSingular("pves", "pfe")
	rs.AddSingular("qves", "qfe")
	rs.AddSingular("rves", "rfe")
	rs.AddSingular("sves", "sfe")
	rs.AddSingular("tves", "tfe")
	rs.AddSingular("uves", "ufe")
	rs.AddSingular("vves", "vfe")
	rs.AddSingular("wves", "wfe")
	rs.AddSingular("xves", "xfe")
	rs.AddSingular("yves", "yfe")
	rs.AddSingular("zves", "zfe")
	rs.AddSingular("hives", "hive")
	rs.AddSingular("tives", "tive")
	rs.AddSingular("lves", "lf")
	rs.AddSingular("rves", "rf")
	rs.AddSingular("quies", "quy")
	rs.AddSingular("bies", "by")
	rs.AddSingular("cies", "cy")
	rs.AddSingular("dies", "dy")
	rs.AddSingular("fies", "fy")
	rs.AddSingular("gies", "gy")
	rs.AddSingular("hies", "hy")
	rs.AddSingular("jies", "jy")
	rs.AddSingular("kies", "ky")
	rs.AddSingular("lies", "ly")
	rs.AddSingular("mies", "my")
	rs.AddSingular("nies", "ny")
	rs.AddSingular("pies", "py")
	rs.AddSingular("qies", "qy")
	rs.AddSingular("ries", "ry")
	rs.AddSingular("sies", "sy")
	rs.AddSingular("ties", "ty")
	rs.AddSingular("vies", "vy")
	rs.AddSingular("wies", "wy")
	rs.AddSingular("xies", "xy")
	rs.AddSingular("zies", "zy")
	rs.AddSingular("series", "series")
	rs.AddSingular("movies", "movie")
	rs.AddSingular("xes", "x")
	rs.AddSingular("ches", "ch")
	rs.AddSingular("sses", "ss")
	rs.AddSingular("shes", "sh")
	rs.AddSingular("mice", "mouse")
	rs.AddSingular("lice", "louse")
	rs.AddSingular("buses", "bus")
	rs.AddSingular("oes", "o")
	rs.AddSingular("shoes", "shoe")
	rs.AddSingular("crises", "crisis")
	rs.AddSingular("axes", "axis")
	rs.AddSingular("testes", "testis")
	rs.AddSingular("octopi", "octopus")
	rs.AddSingular("viri", "virus")
	rs.AddSingular("statuses", "status")
	rs.AddSingular("aliases", "alias")
	rs.AddSingularExact("oxen", "ox", true)
	rs.AddSingular("vertices", "vertex")
	rs.AddSingular("indices", "index")
	rs.AddSingular("matrices", "matrix")
	rs.AddSingularExact("quizzes", "quiz", true)
	rs.AddSingular("databases", "database")
	rs.AddIrregular("person", "people")
	rs.AddIrregular("man", "men")
	rs.AddIrregular("child", "children")
	rs.AddIrregular("sex", "sexes")
	rs.AddIrregular("move", "moves")
	rs.AddIrregular("cow", "kine")
	rs.AddIrregular("zombie", "zombies")
	rs.AddUncountable("equipment")
	rs.AddUncountable("information")
	rs.AddUncountable("rice")
	rs.AddUncountable("money")
	rs.AddUncountable("species")
	rs.AddUncountable("series")
	rs.AddUncountable("fish")
	rs.AddUncountable("sheep")
	rs.AddUncountable("jeans")
	return rs
}

func (rs *Ruleset) Uncountables() map[string]bool {
	return rs.uncountables
}

// add a pluralization rule
func (rs *Ruleset) AddPlural(suffix, replacement string) {
	rs.AddPluralExact(suffix, replacement, false)
}

// add a pluralization rule with full string match
func (rs *Ruleset) AddPluralExact(suffix, replacement string, exact bool) {
	// remove uncountable
	delete(rs.uncountables, suffix)
	// create rule
	r := newRule(suffix, replacement, exact)
	// prepend
	rs.plurals = append([]*Rule{r}, rs.plurals...)
}

// add a singular rule
func (rs *Ruleset) AddSingular(suffix, replacement string) {
	rs.AddSingularExact(suffix, replacement, false)
}

// same as AddSingular but you can set `exact` to force
// a full string match
func (rs *Ruleset) AddSingularExact(suffix, replacement string, exact bool) {
	// remove from uncountable
	delete(rs.uncountables, suffix)
	// create rule
	r := newRule(suffix, replacement, exact)
	rs.singulars = append([]*Rule{r}, rs.singulars...)
}

// Human rules are applied by humanize to show more friendly
// versions of words
func (rs *Ruleset) AddHuman(suffix, replacement string) {
	r := newRule(suffix, replacement, false)
	rs.humans = append([]*Rule{r}, rs.humans...)
}

// Add any inconsistant pluralizing/sinularizing rules
// to the set here.
func (rs *Ruleset) AddIrregular(singular, plural string) {
	delete(rs.uncountables, singular)
	delete(rs.uncountables, plural)
	rs.AddPlural(singular, plural)
	rs.AddPlural(plural, plural)
	rs.AddSingular(plural, singular)
}

// if you use acronym you may need to add them to the ruleset
// to prevent Underscored words of things like "HTML" coming out
// as "h_t_m_l"
func (rs *Ruleset) AddAcronym(word string) {
	r := newRule(word, rs.Titleize(strings.ToLower(word)), false)
	rs.acronyms = append(rs.acronyms, r)
}

// add a word to this ruleset that has the same singular and plural form
// for example: "rice"
func (rs *Ruleset) AddUncountable(word string) {
	rs.uncountables[strings.ToLower(word)] = true
}

func (rs *Ruleset) isUncountable(word string) bool {
	// handle multiple words by using the last one
	words := strings.Split(word, " ")
	if _, exists := rs.uncountables[strings.ToLower(words[len(words)-1])]; exists {
		return true
	}
	return false
}

// returns the plural form of a singular word
func (rs *Ruleset) Pluralize(word string) string {
	if len(word) == 0 {
		return word
	}
	if rs.isUncountable(word) {
		return word
	}
	for _, rule := range rs.plurals {
		replaced, applied := rule.Apply(word)
		if applied {
			return replaced
		}
	}
	return word + "s"
}

// returns the singular form of a plural word
func (rs *Ruleset) Singularize(word string) string {
	if len(word) == 0 {
		return word
	}
	if rs.isUncountable(word) {
		return word
	}
	for _, rule := range rs.singulars {
		replaced, applied := rule.Apply(word)
		if applied {
			return replaced
		}
	}
	return word
}

// uppercase first character
func (rs *Ruleset) Capitalize(word string) string {
	return strings.ToUpper(word[:1]) + word[1:]
}

// "dino_party" -> "DinoParty"
func (rs *Ruleset) Camelize(word string) string {
	words := splitAtCaseChangeWithTitlecase(word)
	return strings.Join(words, "")
}

// same as Camelcase but with first letter downcased
func (rs *Ruleset) CamelizeDownFirst(word string) string {
	word = Camelize(word)
	return strings.ToLower(word[:1]) + word[1:]
}

// Captitilize every word in sentance "hello there" -> "Hello There"
func (rs *Ruleset) Titleize(word string) string {
	words := splitAtCaseChangeWithTitlecase(word)
	return strings.Join(words, " ")
}

func (rs *Ruleset) safeCaseAcronyms(word string) string {
	// convert an acroymn like HTML into Html
	for _, rule := range rs.acronyms {
		word = strings.Replace(word, rule.suffix, rule.replacement, -1)
	}
	return word
}

func (rs *Ruleset) seperatedWords(word, sep string) string {
	word = rs.safeCaseAcronyms(word)
	words := splitAtCaseChange(word)
	return strings.Join(words, sep)
}

// lowercase underscore version "BigBen" -> "big_ben"
func (rs *Ruleset) Underscore(word string) string {
	return rs.seperatedWords(word, "_")
}

// First letter of sentance captitilized
// Uses custom friendly replacements via AddHuman()
func (rs *Ruleset) Humanize(word string) string {
	word = replaceLast(word, "_id", "") // strip foreign key kinds
	// replace and strings in humans list
	for _, rule := range rs.humans {
		word = strings.Replace(word, rule.suffix, rule.replacement, -1)
	}
	sentance := rs.seperatedWords(word, " ")
	return strings.ToUpper(sentance[:1]) + sentance[1:]
}

// an underscored foreign key name "Person" -> "person_id"
func (rs *Ruleset) ForeignKey(word string) string {
	return rs.Underscore(rs.Singularize(word)) + "_id"
}

// a foreign key (with an underscore) "Person" -> "personid"
func (rs *Ruleset) ForeignKeyCondensed(word string) string {
	return rs.Underscore(word) + "id"
}

// Rails style pluralized table names: "SuperPerson" -> "super_people"
func (rs *Ruleset) Tableize(word string) string {
	return rs.Pluralize(rs.Underscore(rs.Typeify(word)))
}

var notUrlSafe *regexp.Regexp = regexp.MustCompile(`[^\w\d\-_ ]`)

// param safe dasherized names like "my-param"
func (rs *Ruleset) Parameterize(word string) string {
	return ParameterizeJoin(word, "-")
}

// param safe dasherized names with custom seperator
func (rs *Ruleset) ParameterizeJoin(word, sep string) string {
	word = strings.ToLower(word)
	word = rs.Asciify(word)
	word = notUrlSafe.ReplaceAllString(word, "")
	word = strings.Replace(word, " ", sep, -1)
	if len(sep) > 0 {
		squash, err := regexp.Compile(sep + "+")
		if err == nil {
			word = squash.ReplaceAllString(word, sep)
		}
	}
	word = strings.Trim(word, sep+" ")
	return word
}

var lookalikes map[string]*regexp.Regexp = map[string]*regexp.Regexp{
	"A":  regexp.MustCompile(`À|Á|Â|Ã|Ä|Å`),
	"AE": regexp.MustCompile(`Æ`),
	"C":  regexp.MustCompile(`Ç`),
	"E":  regexp.MustCompile(`È|É|Ê|Ë`),
	"I":  regexp.MustCompile(`Ì|Í|Î|Ï`),
	"N":  regexp.MustCompile(`Ñ`),
	"O":  regexp.MustCompile(`Ò|Ó|Ô|Õ|Ö|Ø`),
	"U":  regexp.MustCompile(`Ù|Ú|Û|Ü`),
	"Y":  regexp.MustCompile(`Ý`),
	"ss": regexp.MustCompile(`ß`),
	"a":  regexp.MustCompile(`à|á|â|ã|ä|å`),
	"ae": regexp.MustCompile(`æ`),
	"c":  regexp.MustCompile(`ç`),
	"e":  regexp.MustCompile(`è|é|ê|ë`),
	"i":  regexp.MustCompile(`ì|í|î|ï`),
	"n":  regexp.MustCompile(`ñ`),
	"o":  regexp.MustCompile(`ò|ó|ô|õ|ö|ø`),
	"u":  regexp.MustCompile(`ù|ú|û|ü|ũ|ū|ŭ|ů|ű|ų`),
	"y":  regexp.MustCompile(`ý|ÿ`),
}

// transforms latin characters like é -> e
func (rs *Ruleset) Asciify(word string) string {
	for repl, regex := range lookalikes {
		word = regex.ReplaceAllString(word, repl)
	}
	return word
}

var tablePrefix *regexp.Regexp = regexp.MustCompile(`^[^.]*\.`)

// "something_like_this" -> "SomethingLikeThis"
func (rs *Ruleset) Typeify(word string) string {
	word = tablePrefix.ReplaceAllString(word, "")
	return rs.Camelize(rs.Singularize(word))
}

// "SomeText" -> "some-text"
func (rs *Ruleset) Dasherize(word string) string {
	return rs.seperatedWords(word, "-")
}

// "1031" -> "1031st"
func (rs *Ruleset) Ordinalize(str string) string {
	number, err := strconv.Atoi(str)
	if err != nil {
		return str
	}
	switch abs(number) % 100 {
	case 11, 12, 13:
		return fmt.Sprintf("%dth", number)
	default:
		switch abs(number) % 10 {
		case 1:
			return fmt.Sprintf("%dst", number)
		case 2:
			return fmt.Sprintf("%dnd", number)
		case 3:
			return fmt.Sprintf("%drd", number)
		}
	}
	return fmt.Sprintf("%dth", number)
}

func newRule(suffix, replacement string, exact bool) *Rule {
	rule := &Rule{
		suffix:      strings.ToLower(suffix),
		replacement: replacement,
		exact:       exact,
	}
	return rule
}

func (rule *Rule) Apply(word string) (replaced string, applied bool) {
	lowercaseWord := strings.ToLower(word)

	if rule.exact {
		if lowercaseWord == rule.suffix {
			return rule.keepCapitalization(rule.replacement, word), true
		}
	} else {
		if strings.HasSuffix(lowercaseWord, rule.suffix) {
			replaced := replaceLast(lowercaseWord, rule.suffix, rule.replacement)
			return rule.keepCapitalization(replaced, word), true
		}
	}

	return
}

func (rule *Rule) keepCapitalization(word, originalWord string) string {
	isCapitalized := defaultRuleset.Capitalize(originalWord[:1]) == originalWord[:1]
	if !isCapitalized {
		return word
	}
	return defaultRuleset.Capitalize(word)
}

/////////////////////////////////////////
// the default global ruleset
//////////////////////////////////////////

var defaultRuleset *Ruleset

func init() {
	defaultRuleset = NewDefaultRuleset()
}

func Uncountables() map[string]bool {
	return defaultRuleset.Uncountables()
}

func AddPlural(suffix, replacement string) {
	defaultRuleset.AddPlural(suffix, replacement)
}

func AddSingular(suffix, replacement string) {
	defaultRuleset.AddSingular(suffix, replacement)
}

func AddHuman(suffix, replacement string) {
	defaultRuleset.AddHuman(suffix, replacement)
}

func AddIrregular(singular, plural string) {
	defaultRuleset.AddIrregular(singular, plural)
}

func AddAcronym(word string) {
	defaultRuleset.AddAcronym(word)
}

func AddUncountable(word string) {
	defaultRuleset.AddUncountable(word)
}

func Pluralize(word string) string {
	return defaultRuleset.Pluralize(word)
}

func Singularize(word string) string {
	return defaultRuleset.Singularize(word)
}

func Capitalize(word string) string {
	return defaultRuleset.Capitalize(word)
}

func Camelize(word string) string {
	return defaultRuleset.Camelize(word)
}

func CamelizeDownFirst(word string) string {
	return defaultRuleset.CamelizeDownFirst(word)
}

func Titleize(word string) string {
	return defaultRuleset.Titleize(word)
}

func Underscore(word string) string {
	return defaultRuleset.Underscore(word)
}

func Humanize(word string) string {
	return defaultRuleset.Humanize(word)
}

func ForeignKey(word string) string {
	return defaultRuleset.ForeignKey(word)
}

func ForeignKeyCondensed(word string) string {
	return defaultRuleset.ForeignKeyCondensed(word)
}

func Tableize(word string) string {
	return defaultRuleset.Tableize(word)
}

func Parameterize(word string) string {
	return defaultRuleset.Parameterize(word)
}

func ParameterizeJoin(word, sep string) string {
	return defaultRuleset.ParameterizeJoin(word, sep)
}

func Typeify(word string) string {
	return defaultRuleset.Typeify(word)
}

func Dasherize(word string) string {
	return defaultRuleset.Dasherize(word)
}

func Ordinalize(word string) string {
	return defaultRuleset.Ordinalize(word)
}

func Asciify(word string) string {
	return defaultRuleset.Asciify(word)
}

// helper funcs

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func isSpacerChar(c int) bool {
	switch {
	case c == int("_"[0]):
		return true
	case c == int(" "[0]):
		return true
	case c == int(":"[0]):
		return true
	case c == int("-"[0]):
		return true
	}
	return false
}

func splitAtCaseChange(s string) []string {
	words := make([]string, 0)
	word := make([]byte, 0)
	for _, c := range s {
		spacer := isSpacerChar(int(c))
		if len(word) > 0 {
			if unicode.IsUpper(c) || spacer {
				words = append(words, string(word))
				word = make([]byte, 0)
			}
		}
		if !spacer {
			word = append(word, byte(unicode.ToLower(c)))
		}
	}
	words = append(words, string(word))
	return words
}

func splitAtCaseChangeWithTitlecase(s string) []string {
	words := make([]string, 0)
	word := make([]byte, 0)
	for _, c := range s {
		spacer := isSpacerChar(int(c))
		if len(word) > 0 {
			if unicode.IsUpper(c) || spacer {
				words = append(words, string(word))
				word = make([]byte, 0)
			}
		}
		if !spacer {
			if len(word) > 0 {
				word = append(word, byte(unicode.ToLower(c)))
			} else {
				word = append(word, byte(unicode.ToUpper(c)))
			}
		}
	}
	words = append(words, string(word))
	return words
}

func replaceLast(s, match, repl string) string {
	// reverse strings
	srev := reverse(s)
	mrev := reverse(match)
	rrev := reverse(repl)
	// match first and reverse back
	return reverse(strings.Replace(srev, mrev, rrev, 1))
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}


text:
.. include:: /defs.txt
.. |streamline_props| image:: StreamlineProps.png

.. _vi_streamline:

Streamline Plot
===============

Display a vector field using streamlines.

Provide two 2D arrays, giving the **X Vector Component** and
**Y Vector Component** at each point on the grid.  Streamlines are
automatically generated; adjust the **Density** setting to control how
many are used.

By default, streamlines are plotted in black.  If a 2D array is supplied to the
**Colormap Value** input, its contents will be used to shade the streamlines
according to a colormap.  A solid color may also be specified via
**Line.Color**.  At present, line styles other than Automatic or Solid are
ignored.

.. note::
    Due to technical limitations, array dimensions of 2 and 4 are currently
    forbidden and will result in a blank plot; for example, a 2x9 or 7x4
    shape array.

.. image:: Streamline.png

.. include:: /stdid.txt

|double_1d_in| **X Coordinates**
    Optional 1-D array giving X axis coordinates.  Defaults to 0..NX-1, where
    NX is the size of the data's second dimension.  If provided, points must
    be monotonic and uniformly spaced, or :ref:`error_coordinates` will result.

|double_1d_in| **Y Coordinates**
    Optional 1-D array giving Y axis coordinates.  Defaults to 0..NY-1, where
    NY is the size of the data's first dimension.  If provided, points must
    be monotonic and uniformly spaced, or :ref:`error_coordinates` will result.

|double_2d_in| **X Vector Component**
    X vector component at each point.

|double_2d_in| **Y Vector Component**
    Y vector component at each point.

|double_2d_in| **Colormap Value**
    Optional 2D array which will be used to color the streamlines, according
    to a colormap.

|streamline_props| **Properties**
    Property cluster, available under the "Properties" subpalette.

    |double_in| **Density**
        Scale factor controlling density of streamlines.  Default is 1.

    |double_in| **Arrow Size**
        Scale factor controlling size of arrows on the streamlines.
        Default is 1.

    |cluster_in| **Line**
        Controls the appearance of the streamlines.  At the moment, only
        "Automatic" and "Solid" line styles are supported; others will
        be ignored.

        .. include:: /stdline.txt

    |cluster_in| **Colormap**
        Controls the colormap used to shade the arrows, when a
        **Colormap Value** array is given.

        .. include:: /stdcmap.txt

.. include:: /stderr.txt

.. only:: html

    Example
    -------

    Download :download:`Streamlines.vi </examples/Streamlines.vi>`,
    or see :ref:`guide_examples` for a complete list of examples.

    .. image:: StreamlineExample.png

Axis Types
----------

This VI supports rectangular axes.  Use with :ref:`polar axes <guide_polar>`
will result in :ref:`error_polar`.  Likewise, only linear scales are supported.
Use with log or symlog axes will result in :ref:`error_scale`.

Errors
------

* :ref:`error_coordinates`
* :ref:`error_scale`
* :ref:`error_polar`
* :ref:`error_invalid`
* :ref:`error_plotting`
* :ref:`error_init`

Other information
-----------------

If an empty array is provided for **X Vector Component** or **Y Vector Component**,
this VI does nothing.

If a non-finite value appears in **X Coordinates** or **Y Coordinates**,
:ref:`error_coordinates` will result.  A non-finite value in **X Vector Component** or
**Y Vector Component** has undefined results.

If the sizes of any of the inputs are not the same, only the overlapping
region will be displayed.  If a zero-size array is provided for any of
**X Coordinates**, **Y Coordinates**, or **Colormap Value**, it will be ignored.

A non-finite or negative value for **Density** or **Arrow Size** will
be ignored.

Values for **Line.Style** other than Automatic or Solid are currently ignored.


text:
FROM alpine:3.10

# Some ENV variables
ENV PATH="/mattermost/bin:${PATH}"
ENV MM_INSTALL_TYPE=docker

# Build argument to set Mattermost edition
ARG edition=enterprise
ARG PUID=2000
ARG PGID=2000
ARG MM_BINARY=
ARG MM_VERSION=5.36.0

# Install some needed packages
RUN apk add --no-cache \
	ca-certificates \
	curl \
	jq \
	libc6-compat \
	libffi-dev \
	libcap \
	linux-headers \
	mailcap \
	netcat-openbsd \
	xmlsec-dev \
	tzdata \
	&& rm -rf /tmp/*

# Get Mattermost
RUN mkdir -p /mattermost/data /mattermost/plugins /mattermost/client/plugins \
	&& if [ ! -z "$MM_BINARY" ]; then curl $MM_BINARY | tar -xvz ; \
		elif [ "$edition" = "team" ] ; then curl https://releases.mattermost.com/$MM_VERSION/mattermost-team-$MM_VERSION-linux-amd64.tar.gz?src=docker-app | tar -xvz ; \
		else curl https://releases.mattermost.com/$MM_VERSION/mattermost-$MM_VERSION-linux-amd64.tar.gz?src=docker-app | tar -xvz ; fi \
	&& cp /mattermost/config/config.json /config.json.save \
	&& rm -rf /mattermost/config/config.json \
	&& addgroup -g ${PGID} mattermost \
	&& adduser -D -u ${PUID} -G mattermost -h /mattermost -D mattermost \
	&& chown -R mattermost:mattermost /mattermost /config.json.save /mattermost/plugins /mattermost/client/plugins \
	&& setcap cap_net_bind_service=+ep /mattermost/bin/mattermost

USER mattermost

#Healthcheck to make sure container is ready
HEALTHCHECK CMD curl --fail http://localhost:8000 || exit 1

# Configure entrypoint and command
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
WORKDIR /mattermost
CMD ["mattermost"]

# Expose port 8000 of the container
EXPOSE 8000

# Declare volumes for mount point directories
VOLUME ["/mattermost/data", "/mattermost/logs", "/mattermost/config", "/mattermost/plugins", "/mattermost/client/plugins"]


text:
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
/**
 * Created by manojdobbala on 7/11/16.
 */
var core_1 = require('@angular/core');
var http_1 = require('@angular/http');
require('rxjs/Rx');
var CharacterService = (function () {
    function CharacterService(_http) {
        this._http = _http;
    }
    CharacterService.prototype.getCharacters = function (storyId) {
        return this._http.get('app/api/characters.json')
            .map(function (response) { return response.json().data; });
    };
    CharacterService = __decorate([
        core_1.Injectable(),
        __metadata('design:paramtypes', [http_1.Http])
    ], CharacterService);
    return CharacterService;
}());
exports.CharacterService = CharacterService;
//# sourceMappingURL=character.service.js.map


text:
import {Component} from "@angular/core";
import {LoggedInCallback, UserLoginService, UserParametersService, Callback} from "../../service/cognito.service";
import {Router} from "@angular/router";

declare var AWS: any;
@Component({
    selector: 'my-aws-console-app',
    templateUrl: './myprofile.html'
})
export class MyProfileComponent implements LoggedInCallback {

    public parameters: Array<Parameters> = [];
    public cognitoId: String;

    constructor(public router: Router, public userService: UserLoginService, public userParams: UserParametersService) {
        this.userService.isAuthenticated(this);
        console.log("In MyProfileComponent");
    }

    isLoggedIn(message: string, isLoggedIn: boolean) {
        if (!isLoggedIn) {
            this.router.navigate(['/home/login']);
        } else {
            this.userParams.getParameters(new GetParametersCallback(this));
        }
    }
}

export class Parameters {
    name: string;
    value: string;
}

export class GetParametersCallback implements Callback {

    constructor(public me: MyProfileComponent) {

    }

    callback() {

    }

    callbackWithParam(result: any) {

        for (let i = 0; i < result.length; i++) {
            let parameter = new Parameters();
            parameter.name = result[i].getName();
            parameter.value = result[i].getValue();
            this.me.parameters.push(parameter);
        }
        let param = new Parameters()
        param.name = "cognito ID";
        param.value = AWS.config.credentials.params.IdentityId;
        this.me.parameters.push(param)
    }
}


text:
namespace app {
namespace Uno {

::uDelegateType* Action__Outracks_Simulator_Bytecode_Return__Uno_IO_BinaryWriter__typeof();

}}

#endif


text:
package kafka.controller

import java.net.SocketTimeoutException
import java.util.concurrent.{BlockingQueue, LinkedBlockingQueue}

import com.yammer.metrics.core.Gauge
import kafka.api._
import kafka.cluster.Broker
import kafka.common.{KafkaException, TopicAndPartition}
import kafka.metrics.KafkaMetricsGroup
import kafka.server.KafkaConfig
import kafka.utils._
import org.apache.kafka.clients._
import org.apache.kafka.common.metrics.Metrics
import org.apache.kafka.common.network._
import org.apache.kafka.common.protocol.{ApiKeys, SecurityProtocol}
import org.apache.kafka.common.requests.UpdateMetadataRequest.EndPoint
import org.apache.kafka.common.requests.{UpdateMetadataRequest, _}
import org.apache.kafka.common.security.JaasContext
import org.apache.kafka.common.utils.Time
import org.apache.kafka.common.{Node, TopicPartition, requests}

import scala.collection.JavaConverters._
import scala.collection.mutable.HashMap
import scala.collection.{Set, mutable}

object ControllerChannelManager {
  val QueueSizeMetricName = "QueueSize"
}

class ControllerChannelManager(controllerContext: ControllerContext, config: KafkaConfig, time: Time, metrics: Metrics,
                               threadNamePrefix: Option[String] = None) extends Logging with KafkaMetricsGroup {
  import ControllerChannelManager._
  protected val brokerStateInfo = new HashMap[Int, ControllerBrokerStateInfo]//用来管理集群中每个broker对应的ControllerBrokerStateInfo对象
  private val brokerLock = new Object
  this.logIdent = "[Channel manager on controller " + config.brokerId + "]: "

  newGauge(
    "TotalQueueSize",
    new Gauge[Int] {
      def value: Int = brokerLock synchronized {
        brokerStateInfo.values.iterator.map(_.messageQueue.size).sum
      }
    }
  )

  controllerContext.liveBrokers.foreach(addNewBroker)

  def startup() = {
    brokerLock synchronized {
      //启动RequestSendThread线程
      brokerStateInfo.foreach(brokerState => startRequestSendThread(brokerState._1))
    }
  }

  def shutdown() = {
    brokerLock synchronized {
      brokerStateInfo.values.foreach(removeExistingBroker)
    }
  }

  def sendRequest(brokerId: Int, apiKey: ApiKeys, request: AbstractRequest.Builder[_ <: AbstractRequest],
                  callback: AbstractResponse => Unit = null) {
    brokerLock synchronized {
      val stateInfoOpt = brokerStateInfo.get(brokerId)
      stateInfoOpt match {
        case Some(stateInfo) =>
          //将消息放到缓存队列
          stateInfo.messageQueue.put(QueueItem(apiKey, request, callback))
        case None =>
          warn("Not sending request %s to broker %d, since it is offline.".format(request, brokerId))
      }
    }
  }

  def addBroker(broker: Broker) {
    // be careful here. Maybe the startup() API has already started the request send thread
    brokerLock synchronized {
      if(!brokerStateInfo.contains(broker.id)) {
        addNewBroker(broker)
        startRequestSendThread(broker.id)
      }
    }
  }

  def removeBroker(brokerId: Int) {
    brokerLock synchronized {
      removeExistingBroker(brokerStateInfo(brokerId))
    }
  }
  //添加每个broker对应的ControllerBrokerStateInfo
  private def addNewBroker(broker: Broker) {
    //创建消息队列
    val messageQueue = new LinkedBlockingQueue[QueueItem]
    debug("Controller %d trying to connect to broker %d".format(config.brokerId, broker.id))
    val brokerNode = broker.getNode(config.interBrokerListenerName)
    //创建NetworkClient对象
    val networkClient = {
      val channelBuilder = ChannelBuilders.clientChannelBuilder(
        config.interBrokerSecurityProtocol,
        JaasContext.Type.SERVER,
        config,
        config.interBrokerListenerName,
        config.saslMechanismInterBrokerProtocol,
        config.saslInterBrokerHandshakeRequestEnable
      )
      val selector = new Selector(
        NetworkReceive.UNLIMITED,
        Selector.NO_IDLE_TIMEOUT_MS,
        // 监控指标
        metrics,
        time,
        "controller-channel",
        Map("broker-id" -> broker.id.toString).asJava,
        false,
        channelBuilder
      )
      new NetworkClient(
        selector,
        new ManualMetadataUpdater(Seq(brokerNode).asJava),
        config.brokerId.toString,
        1,
        0,
        0,
        Selectable.USE_DEFAULT_BUFFER_SIZE,
        Selectable.USE_DEFAULT_BUFFER_SIZE,
        config.requestTimeoutMs,
        time,
        false,
        new ApiVersions
      )
    }
    val threadName = threadNamePrefix match {
      case None => "Controller-%d-to-broker-%d-send-thread".format(config.brokerId, broker.id)
      case Some(name) => "%s:Controller-%d-to-broker-%d-send-thread".format(name, config.brokerId, broker.id)
    }

    val requestThread = new RequestSendThread(config.brokerId, controllerContext, messageQueue, networkClient,
      brokerNode, config, time, threadName)
    requestThread.setDaemon(false)

    val queueSizeGauge = newGauge(
      QueueSizeMetricName,
      new Gauge[Int] {
        def value: Int = messageQueue.size
      },
      queueSizeTags(broker.id)
    )
    //填充brokerinfo对象
    brokerStateInfo.put(broker.id, new ControllerBrokerStateInfo(networkClient, brokerNode, messageQueue,
      requestThread, queueSizeGauge))
  }

  private def queueSizeTags(brokerId: Int) = Map("broker-id" -> brokerId.toString)

  //移除Broker对应的ControllerBrokerStateInfo对象
  private def removeExistingBroker(brokerState: ControllerBrokerStateInfo) {
    try {
      // Shutdown the RequestSendThread before closing the NetworkClient to avoid the concurrent use of the
      // non-threadsafe classes as described in KAFKA-4959.
      // The call to shutdownLatch.await() in ShutdownableThread.shutdown() serves as a synchronization barrier that
      // hands off the NetworkClient from the RequestSendThread to the ZkEventThread.
      //关闭底层连接
      brokerState.requestSendThread.shutdown()
      //关闭底层连接
      brokerState.networkClient.close()
      //清空队列
      brokerState.messageQueue.clear()
      removeMetric(QueueSizeMetricName, queueSizeTags(brokerState.brokerNode.id))
      //清除ControllerBrokerStateInfo对象
      brokerStateInfo.remove(brokerState.brokerNode.id)
    } catch {
      case e: Throwable => error("Error while removing broker by the controller", e)
    }
  }

  protected def startRequestSendThread(brokerId: Int) {
    val requestThread = brokerStateInfo(brokerId).requestSendThread
    if(requestThread.getState == Thread.State.NEW)
      requestThread.start()
  }
}

case class QueueItem(apiKey: ApiKeys, request: AbstractRequest.Builder[_ <: AbstractRequest],
                     callback: AbstractResponse => Unit)

class RequestSendThread(val controllerId: Int,
                        val controllerContext: ControllerContext,
                        val queue: BlockingQueue[QueueItem],
                        val networkClient: NetworkClient,
                        val brokerNode: Node,
                        val config: KafkaConfig,
                        val time: Time,
                        name: String)
  extends ShutdownableThread(name = name) {

  private val stateChangeLogger = KafkaController.stateChangeLogger
  private val socketTimeoutMs = config.controllerSocketTimeoutMs

  override def doWork(): Unit = {

    def backoff(): Unit = CoreUtils.swallowTrace(Thread.sleep(100))
    //获取缓冲队列中QueueItem
    val QueueItem(apiKey, requestBuilder, callback) = queue.take()
    var clientResponse: ClientResponse = null
    try {
      var isSendSuccessful = false
      while (isRunning.get() && !isSendSuccessful) {
        //当broker宕机后,会触发zk的监听器调用removeBroker方法将蛋清的线程停止
        // if a broker goes down for a long time, then at some point the controller's zookeeper listener will trigger a
        // removeBroker which will invoke shutdown() on this thread. At that point, we will stop retrying.
        try {
          if (!brokerReady()) {
            isSendSuccessful = false
            //规避
            backoff()
          }
          else {
            //创建ClientRequest对象
            val clientRequest = networkClient.newClientRequest(brokerNode.idString, requestBuilder,
              time.milliseconds(), true)
            //发送请求并阻塞等待响应
            clientResponse = NetworkClientUtils.sendAndReceive(networkClient, clientRequest, time)
            isSendSuccessful = true
          }
        } catch {
          case e: Throwable => // if the send was not successful, reconnect to broker and resend the message
            warn(("Controller %d epoch %d fails to send request %s to broker %s. " +
              "Reconnecting to broker.").format(controllerId, controllerContext.epoch,
                requestBuilder.toString, brokerNode.toString), e)
            networkClient.close(brokerNode.idString)
            isSendSuccessful = false
            backoff()
        }
      }
      if (clientResponse != null) {
        val requestHeader = clientResponse.requestHeader
        val api = ApiKeys.forId(requestHeader.apiKey)
        //检测请求类型
        if (api != ApiKeys.LEADER_AND_ISR && api != ApiKeys.STOP_REPLICA && api != ApiKeys.UPDATE_METADATA_KEY)
          throw new KafkaException(s"Unexpected apiKey received: $apiKey")

        val response = clientResponse.responseBody

        stateChangeLogger.trace("Controller %d epoch %d received response %s for a request sent to broker %s"
          .format(controllerId, controllerContext.epoch, response.toString(requestHeader.apiVersion), brokerNode.toString))
        //执行回调函数
        if (callback != null) {
          callback(response)
        }
      }
    } catch {
      case e: Throwable =>
        error("Controller %d fails to send a request to broker %s".format(controllerId, brokerNode.toString), e)
        // If there is any socket error (eg, socket timeout), the connection is no longer usable and needs to be recreated.
        networkClient.close(brokerNode.idString)
    }
  }

  private def brokerReady(): Boolean = {
    try {
      if (!NetworkClientUtils.isReady(networkClient, brokerNode, time.milliseconds())) {
        if (!NetworkClientUtils.awaitReady(networkClient, brokerNode, time, socketTimeoutMs))
          throw new SocketTimeoutException(s"Failed to connect within $socketTimeoutMs ms")

        info("Controller %d connected to %s for sending state change requests".format(controllerId, brokerNode.toString))
      }

      true
    } catch {
      case e: Throwable =>
        warn("Controller %d's connection to broker %s was unsuccessful".format(controllerId, brokerNode.toString), e)
        networkClient.close(brokerNode.idString)
        false
    }
  }

}
//批量发送消息
class ControllerBrokerRequestBatch(controller: KafkaController) extends  Logging {
  val controllerContext = controller.controllerContext
  val controllerId: Int = controller.config.brokerId
  //记录了发往指定Broker的leaderAndIsrRequest所需信息
  val leaderAndIsrRequestMap = mutable.Map.empty[Int, mutable.Map[TopicPartition, PartitionStateInfo]]
  //记录了发往指定broker的StopReplicaRequest所需的信息
  val stopReplicaRequestMap = mutable.Map.empty[Int, Seq[StopReplicaRequestInfo]]
  //记录了发往指定broker的UpdateMetadaRequest集合
  val updateMetadataRequestBrokerSet = mutable.Set.empty[Int]
  val updateMetadataRequestPartitionInfoMap = mutable.Map.empty[TopicPartition, PartitionStateInfo]
  private val stateChangeLogger = KafkaController.stateChangeLogger

  //检测三个请求集合
  def newBatch() {
    // raise error if the previous batch is not empty
    if (leaderAndIsrRequestMap.nonEmpty)
      throw new IllegalStateException("Controller to broker state change requests batch is not empty while creating " +
        "a new one. Some LeaderAndIsr state changes %s might be lost ".format(leaderAndIsrRequestMap.toString()))
    if (stopReplicaRequestMap.nonEmpty)
      throw new IllegalStateException("Controller to broker state change requests batch is not empty while creating a " +
        "new one. Some StopReplica state changes %s might be lost ".format(stopReplicaRequestMap.toString()))
    if (updateMetadataRequestBrokerSet.nonEmpty)
      throw new IllegalStateException("Controller to broker state change requests batch is not empty while creating a " +
        "new one. Some UpdateMetadata state changes to brokers %s with partition info %s might be lost ".format(
          updateMetadataRequestBrokerSet.toString(), updateMetadataRequestPartitionInfoMap.toString()))
  }

  //清空三个集合
  def clear() {
    leaderAndIsrRequestMap.clear()
    stopReplicaRequestMap.clear()
    updateMetadataRequestBrokerSet.clear()
    updateMetadataRequestPartitionInfoMap.clear()
  }

  //向LeaderAndIserRequestMap集合中添加要发送的LeaderAndIsrRequest所需的数据
  def addLeaderAndIsrRequestForBrokers(brokerIds: Seq[Int], topic: String, partition: Int,
                                       leaderIsrAndControllerEpoch: LeaderIsrAndControllerEpoch,
                                       replicas: Seq[Int], callback: AbstractResponse => Unit = null) {
    val topicPartition = new TopicPartition(topic, partition)
    //查找broker对应的集合
    brokerIds.filter(_ >= 0).foreach { brokerId =>
      val result = leaderAndIsrRequestMap.getOrElseUpdate(brokerId, mutable.Map.empty)
      result.put(topicPartition, PartitionStateInfo(leaderIsrAndControllerEpoch, replicas))
    }

    addUpdateMetadataRequestForBrokers(controllerContext.liveOrShuttingDownBrokerIds.toSeq,
                                       Set(TopicAndPartition(topic, partition)))
  }

  def addStopReplicaRequestForBrokers(brokerIds: Seq[Int], topic: String, partition: Int, deletePartition: Boolean,
                                      callback: (AbstractResponse, Int) => Unit = null) {
    brokerIds.filter(b => b >= 0).foreach { brokerId =>
      stopReplicaRequestMap.getOrElseUpdate(brokerId, Seq.empty[StopReplicaRequestInfo])
      val v = stopReplicaRequestMap(brokerId)
      if(callback != null)
        stopReplicaRequestMap(brokerId) = v :+ StopReplicaRequestInfo(PartitionAndReplica(topic, partition, brokerId),
          deletePartition, (r: AbstractResponse) => callback(r, brokerId))
      else
        stopReplicaRequestMap(brokerId) = v :+ StopReplicaRequestInfo(PartitionAndReplica(topic, partition, brokerId),
          deletePartition)
    }
  }

  /** Send UpdateMetadataRequest to the given brokers for the given partitions and partitions that are being deleted */
  def addUpdateMetadataRequestForBrokers(brokerIds: Seq[Int],
                                         partitions: collection.Set[TopicAndPartition] = Set.empty[TopicAndPartition]) {

    def updateMetadataRequestPartitionInfo(partition: TopicAndPartition, beingDeleted: Boolean) {
      val leaderIsrAndControllerEpochOpt = controllerContext.partitionLeadershipInfo.get(partition)
      leaderIsrAndControllerEpochOpt match {
        case Some(l @ LeaderIsrAndControllerEpoch(leaderAndIsr, controllerEpoch)) =>
          val replicas = controllerContext.partitionReplicaAssignment(partition)

          val leaderIsrAndControllerEpoch = if (beingDeleted) {
            val leaderDuringDelete = LeaderAndIsr.duringDelete(leaderAndIsr.isr)
            LeaderIsrAndControllerEpoch(leaderDuringDelete, controllerEpoch)
          } else {
            l
          }

          val partitionStateInfo = PartitionStateInfo(leaderIsrAndControllerEpoch, replicas)
          updateMetadataRequestPartitionInfoMap.put(new TopicPartition(partition.topic, partition.partition), partitionStateInfo)

        case None =>
          info("Leader not yet assigned for partition %s. Skip sending UpdateMetadataRequest.".format(partition))
      }
    }

    val filteredPartitions = {
      val givenPartitions = if (partitions.isEmpty)
        controllerContext.partitionLeadershipInfo.keySet
      else
        partitions
      if (controller.topicDeletionManager.partitionsToBeDeleted.isEmpty)
        givenPartitions
      else
        givenPartitions -- controller.topicDeletionManager.partitionsToBeDeleted
    }

    updateMetadataRequestBrokerSet ++= brokerIds.filter(_ >= 0)
    filteredPartitions.foreach(partition => updateMetadataRequestPartitionInfo(partition, beingDeleted = false))
    controller.topicDeletionManager.partitionsToBeDeleted.foreach(partition => updateMetadataRequestPartitionInfo(partition, beingDeleted = true))
  }

  def sendRequestsToBrokers(controllerEpoch: Int) {
    try {
      leaderAndIsrRequestMap.foreach { case (broker, partitionStateInfos) =>
        partitionStateInfos.foreach { case (topicPartition, state) =>
          val typeOfRequest =
            if (broker == state.leaderIsrAndControllerEpoch.leaderAndIsr.leader) "become-leader"
            else "become-follower"
          stateChangeLogger.trace(("Controller %d epoch %d sending %s LeaderAndIsr request %s to broker %d " +
                                   "for partition [%s,%d]").format(controllerId, controllerEpoch, typeOfRequest,
                                                                   state.leaderIsrAndControllerEpoch, broker,
                                                                   topicPartition.topic, topicPartition.partition))
        }
        val leaderIds = partitionStateInfos.map(_._2.leaderIsrAndControllerEpoch.leaderAndIsr.leader).toSet
        val leaders = controllerContext.liveOrShuttingDownBrokers.filter(b => leaderIds.contains(b.id)).map {
          _.getNode(controller.config.interBrokerListenerName)
        }
        val partitionStates = partitionStateInfos.map { case (topicPartition, partitionStateInfo) =>
          val LeaderIsrAndControllerEpoch(leaderIsr, controllerEpoch) = partitionStateInfo.leaderIsrAndControllerEpoch
          val partitionState = new requests.PartitionState(controllerEpoch, leaderIsr.leader,
            leaderIsr.leaderEpoch, leaderIsr.isr.map(Integer.valueOf).asJava, leaderIsr.zkVersion,
            partitionStateInfo.allReplicas.map(Integer.valueOf).asJava)
          topicPartition -> partitionState
        }
        val leaderAndIsrRequest = new LeaderAndIsrRequest.Builder(controllerId, controllerEpoch, partitionStates.asJava,
          leaders.asJava)
        controller.sendRequest(broker, ApiKeys.LEADER_AND_ISR, leaderAndIsrRequest)
      }
      leaderAndIsrRequestMap.clear()

      updateMetadataRequestPartitionInfoMap.foreach(p => stateChangeLogger.trace(("Controller %d epoch %d sending UpdateMetadata request %s " +
        "to brokers %s for partition %s").format(controllerId, controllerEpoch, p._2.leaderIsrAndControllerEpoch,
        updateMetadataRequestBrokerSet.toString(), p._1)))
      val partitionStates = updateMetadataRequestPartitionInfoMap.map { case (topicPartition, partitionStateInfo) =>
        val LeaderIsrAndControllerEpoch(leaderIsr, controllerEpoch) = partitionStateInfo.leaderIsrAndControllerEpoch
        val partitionState = new requests.PartitionState(controllerEpoch, leaderIsr.leader,
          leaderIsr.leaderEpoch, leaderIsr.isr.map(Integer.valueOf).asJava, leaderIsr.zkVersion,
          partitionStateInfo.allReplicas.map(Integer.valueOf).asJava)
        topicPartition -> partitionState
      }

      val version: Short =
        if (controller.config.interBrokerProtocolVersion >= KAFKA_0_10_2_IV0) 3
        else if (controller.config.interBrokerProtocolVersion >= KAFKA_0_10_0_IV1) 2
        else if (controller.config.interBrokerProtocolVersion >= KAFKA_0_9_0) 1
        else 0

      val updateMetadataRequest = {
        val liveBrokers = if (version == 0) {
          // Version 0 of UpdateMetadataRequest only supports PLAINTEXT.
          controllerContext.liveOrShuttingDownBrokers.map { broker =>
            val securityProtocol = SecurityProtocol.PLAINTEXT
            val listenerName = ListenerName.forSecurityProtocol(securityProtocol)
            val node = broker.getNode(listenerName)
            val endPoints = Seq(new EndPoint(node.host, node.port, securityProtocol, listenerName))
            new UpdateMetadataRequest.Broker(broker.id, endPoints.asJava, broker.rack.orNull)
          }
        } else {
          controllerContext.liveOrShuttingDownBrokers.map { broker =>
            val endPoints = broker.endPoints.map { endPoint =>
              new UpdateMetadataRequest.EndPoint(endPoint.host, endPoint.port, endPoint.securityProtocol, endPoint.listenerName)
            }
            new UpdateMetadataRequest.Broker(broker.id, endPoints.asJava, broker.rack.orNull)
          }
        }
        new UpdateMetadataRequest.Builder(version, controllerId, controllerEpoch, partitionStates.asJava,
          liveBrokers.asJava)
      }

      updateMetadataRequestBrokerSet.foreach { broker =>
        controller.sendRequest(broker, ApiKeys.UPDATE_METADATA_KEY, updateMetadataRequest, null)
      }
      updateMetadataRequestBrokerSet.clear()
      updateMetadataRequestPartitionInfoMap.clear()

      stopReplicaRequestMap.foreach { case (broker, replicaInfoList) =>
        val stopReplicaWithDelete = replicaInfoList.filter(_.deletePartition).map(_.replica).toSet
        val stopReplicaWithoutDelete = replicaInfoList.filterNot(_.deletePartition).map(_.replica).toSet
        debug("The stop replica request (delete = true) sent to broker %d is %s"
          .format(broker, stopReplicaWithDelete.mkString(",")))
        debug("The stop replica request (delete = false) sent to broker %d is %s"
          .format(broker, stopReplicaWithoutDelete.mkString(",")))

        val (replicasToGroup, replicasToNotGroup) = replicaInfoList.partition(r => !r.deletePartition && r.callback == null)

        // Send one StopReplicaRequest for all partitions that require neither delete nor callback. This potentially
        // changes the order in which the requests are sent for the same partitions, but that's OK.
        val stopReplicaRequest = new StopReplicaRequest.Builder(controllerId, controllerEpoch, false,
          replicasToGroup.map(r => new TopicPartition(r.replica.topic, r.replica.partition)).toSet.asJava)
        controller.sendRequest(broker, ApiKeys.STOP_REPLICA, stopReplicaRequest)

        replicasToNotGroup.foreach { r =>
          val stopReplicaRequest = new StopReplicaRequest.Builder(
              controllerId, controllerEpoch, r.deletePartition,
              Set(new TopicPartition(r.replica.topic, r.replica.partition)).asJava)
          controller.sendRequest(broker, ApiKeys.STOP_REPLICA, stopReplicaRequest, r.callback)
        }
      }
      stopReplicaRequestMap.clear()
    } catch {
      case e: Throwable =>
        if (leaderAndIsrRequestMap.nonEmpty) {
          error("Haven't been able to send leader and isr requests, current state of " +
              s"the map is $leaderAndIsrRequestMap. Exception message: $e")
        }
        if (updateMetadataRequestBrokerSet.nonEmpty) {
          error(s"Haven't been able to send metadata update requests to brokers $updateMetadataRequestBrokerSet, " +
                s"current state of the partition info is $updateMetadataRequestPartitionInfoMap. Exception message: $e")
        }
        if (stopReplicaRequestMap.nonEmpty) {
          error("Haven't been able to send stop replica requests, current state of " +
              s"the map is $stopReplicaRequestMap. Exception message: $e")
        }
        throw new IllegalStateException(e)
    }
  }
}
//表示与一个Broker连接的各种信息
case class ControllerBrokerStateInfo(networkClient: NetworkClient, //维护contoller对应broker通信的网络连接
                                     brokerNode: Node,//维护了对应的broker的网络位置信息,记录了Broker的ip、port等
                                     messageQueue: BlockingQueue[QueueItem],//缓冲队列,存放了发往对应的broker请求
                                     requestSendThread: RequestSendThread,//用于请求发送的线程
                                     queueSizeGauge: Gauge[Int])

case class StopReplicaRequestInfo(replica: PartitionAndReplica, deletePartition: Boolean, callback: AbstractResponse => Unit = null)

class Callbacks private (var leaderAndIsrResponseCallback: AbstractResponse => Unit = null,
                         var updateMetadataResponseCallback: AbstractResponse => Unit = null,
                         var stopReplicaResponseCallback: (AbstractResponse, Int) => Unit = null)

object Callbacks {
  class CallbackBuilder {
    var leaderAndIsrResponseCbk: AbstractResponse => Unit = null
    var updateMetadataResponseCbk: AbstractResponse => Unit = null
    var stopReplicaResponseCbk: (AbstractResponse, Int) => Unit = null

    def leaderAndIsrCallback(cbk: AbstractResponse => Unit): CallbackBuilder = {
      leaderAndIsrResponseCbk = cbk
      this
    }

    def updateMetadataCallback(cbk: AbstractResponse => Unit): CallbackBuilder = {
      updateMetadataResponseCbk = cbk
      this
    }

    def stopReplicaCallback(cbk: (AbstractResponse, Int) => Unit): CallbackBuilder = {
      stopReplicaResponseCbk = cbk
      this
    }

    def build: Callbacks = {
      new Callbacks(leaderAndIsrResponseCbk, updateMetadataResponseCbk, stopReplicaResponseCbk)
    }
  }
}