text:
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines contain the default error messages used by
    | the validator class. Some of these rules have multiple versions such
    | as the size rules. Feel free to tweak each of these messages here.
    |
    */

    'accepted'             => ':attribute skal accepteres.',
    'active_url'           => ':attribute er ikke en gyldig adresse.',
    'after'                => ':attribute skal være en dato efter :date.',
    'after_or_equal'       => 'The :attribute must be a date after or equal to :date.',
    'alpha'                => ':attribute må kun indeholde bogstaver.',
    'alpha_dash'           => ':attribute må kun indeholde bogstaver, tal og mellemstreger.',
    'alpha_num'            => ':attribute må kun indeholde bogstaver og tal.',
    'array'                => ':attribute skal være en liste.',
    'before'               => ':attribute skal være en dato før :date.',
    'before_or_equal'      => 'The :attribute must be a date before or equal to :date.',
    'between'              => [
        'numeric' => ':attribute skal være mellem :min og :max.',
        'file'    => ':attribute skal være mellem :min og :max kilobytes.',
        'string'  => ':attribute skal være mellem :min og :max tegn.',
        'array'   => ':attribute skal have mellem :min og :max elementer.',
    ],
    'boolean'              => ':attribute skal være sandt eller falsk.',
    'confirmed'            => ':attribute bekræftelse passer ikke sammen.',
    'date'                 => ':attribute er ikke en gyldig dato.',
    'date_format'          => ':attribute passer ikke til formatet :format.',
    'different'            => ':attribute og :other skal være forskellige.',
    'digits'               => ':attribute skal være på :digits cifre.',
    'digits_between'       => ':attribute skal være mellem :min og :max cifre.',
    'dimensions'           => ':attribute har ugyldige dimensioner.',
    'distinct'             => ':attribute skal være unik.',
    'email'                => ':attribute skal være en gyldig e-mailaddresse.',
    'exists'               => ':attribute findes ikke.',
    'file'                 => ':attribute skal være en fil.',
    'filled'               => ':attribute skal udfyldes.',
    'image'                => ':attribute skal være et billed.',
    'in'                   => ':attribute er ikke gyldig.',
    'in_array'             => ':attribute findes ikke i :other.',
    'integer'              => ':attribute skal være et heltal.',
    'ip'                   => ':attribute skal være en gyldig IP-adresse.',
    'ipv4'                 => 'The :attribute must be a valid IPv4 address.',
    'ipv6'                 => 'The :attribute must be a valid IPv6 address.',
    'json'                 => ':attribute skal være gyldig JSON format.',
    'max'                  => [
        'numeric' => ':attribute må ikke være større end :max.',
        'file'    => ':attribute må ikke være større end :max kilobytes.',
        'string'  => ':attribute må ikke være længere end :max tegn.',
        'array'   => ':attribute må ikke have flere end :max elementer.',
    ],
    'mimes'                => ':attribute skal være filtypen: :values.',
    'min'                  => [
        'numeric' => ':attribute skal være mindst :min.',
        'file'    => ':attribute skal være mindst :min kilobytes.',
        'string'  => ':attribute skal mindts være :min tegn.',
        'array'   => ':attribute skal have mindst :min elementer.',
    ],
    'not_in'               => ':attribute er ikke gyldig.',
    'numeric'              => ':attribute skal være et tal.',
    'present'              => 'Feltet :attribute mangler.',
    'regex'                => ':attribute er ikke et gyldigt format.',
    'required'             => ':attribute er påkrævet.',
    'required_if'          => ':attribute er påkrævet når :other er :value.',
    'required_unless'      => ':attribute er påkrævet med mindre :other er :values.',
    'required_with'        => ':attribute er påkrævet når :values er tilgængelig.',
    'required_with_all'    => ':attribute er påkrævet når :values er tilgængelig.',
    'required_without'     => ':attribute er påkrævet når :values ikke er tilgængelig.',
    'required_without_all' => ':attribute er påkrævet når ingen af værdierne :values er tilgængelig.',
    'same'                 => ':attribute og :other skal være ens.',
    'size'                 => [
        'numeric' => ':attribute skal være :size.',
        'file'    => ':attribute skal være :size kilobytes.',
        'string'  => ':attribute skal have :size tegn.',
        'array'   => ':attribute skal indeholde :size elementer.',
    ],
    'string'               => ':attribute skal være tekst.',
    'timezone'             => ':attribute skal være en gyldig tidszone.',
    'unique'               => ':attribute er allerede i brug.',
    'url'                  => ':attribute er ikke i det rigtige format.',

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | Here you may specify custom validation messages for attributes using the
    | convention "attribute.rule" to name the lines. This makes it quick to
    | specify a specific custom language line for a given attribute rule.
    |
    */

    'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Attributes
    |--------------------------------------------------------------------------
    |
    | The following language lines are used to swap attribute place-holders
    | with something more reader friendly such as E-Mail Address instead
    | of "email". This simply helps us make messages a little cleaner.
    |
    */

    'attributes' => [

        'backend' => [
            'access' => [
                'permissions' => [
                    'associated_roles' => 'Tilknyttede Roller',
                    'dependencies'     => 'Afhængigheder',
                    'display_name'     => 'Visningsnavn',
                    'group'            => 'Gruppe',
                    'group_sort'       => 'Gruppesortering',

                    'groups' => [
                        'name' => 'Gruppenavn',
                    ],

                    'name'   => 'Navn',
                    'system' => 'System?',
                ],

                'roles' => [
                    'associated_permissions' => 'Tilknyttede Rettigheder',
                    'name'                   => 'Navn',
                    'sort'                   => 'Sortér',
                ],

                'users' => [
                    'active'                  => 'Aktiv',
                    'associated_roles'        => 'Tilknyttede Roller',
                    'confirmed'               => 'Bekræftet',
                    'email'                   => 'E-mailadresse',
                    'name'                    => 'Navn',
                    'other_permissions'       => 'Andre Rettigheder',
                    'password'                => 'Adgangskode',
                    'password_confirmation'   => 'Bekræft adgangskode',
                    'send_confirmation_email' => 'Send bekræfelsesmail',
                ],
            ],
        ],

        'frontend' => [
            'email'                     => 'E-mailadresse',
            'name'                      => 'Navn',
            'password'                  => 'Adgangskode',
            'password_confirmation'     => 'Bekræft adgangskode',
            'phone' => 'Phone',
            'message' => 'Message',
            'old_password'              => 'Gammel adgangskode',
            'new_password'              => 'Ny adgangskode',
            'new_password_confirmation' => 'Bekræft ny adgangskode',
        ],
    ],
];


text:
TestTube helps you build, configure, run, and test your systems. It is
designed to run in a CI environemnt and provides the best way to build
high-fedility testing environments in an absolute minimum amount of
time.

The main components are:

- reciver
- configurator
- controller

## Installation

Add this line to your application's Gemfile:

    gem 'testtube'

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install testtube

## Usage

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

redpajama_set_name: RedPajamaGithub


text:
using Exceptionless.Core.Models;
using Foundatio.Utility;

namespace Exceptionless.Core.Extensions;

public static class UserExtensions {
    public static bool IsCorrectPassword(this User user, string password) {
        if (String.IsNullOrEmpty(user.Salt) || String.IsNullOrEmpty(user.Password))
            return false;

        string encodedPassword = password.ToSaltedHash(user.Salt);
        return String.Equals(encodedPassword, user.Password);
    }

    public static void ResetVerifyEmailAddressToken(this User user) {
        if (user == null)
            return;

        user.VerifyEmailAddressToken = null;
        user.VerifyEmailAddressTokenExpiration = DateTime.MinValue;
    }

    public static void CreateVerifyEmailAddressToken(this User user) {
        if (user == null)
            return;

        user.VerifyEmailAddressToken = StringExtensions.GetNewToken();
        user.VerifyEmailAddressTokenExpiration = SystemClock.UtcNow.AddMinutes(1440);
    }

    public static bool HasValidVerifyEmailAddressTokenExpiration(this User user) {
        if (user == null)
            return false;

        return user.VerifyEmailAddressTokenExpiration != DateTime.MinValue && user.VerifyEmailAddressTokenExpiration >= SystemClock.UtcNow;
    }

    public static void MarkEmailAddressVerified(this User user) {
        if (user == null)
            return;

        user.IsEmailAddressVerified = true;
        user.VerifyEmailAddressToken = null;
        user.VerifyEmailAddressTokenExpiration = DateTime.MinValue;
    }

    public static void ResetPasswordResetToken(this User user) {
        if (user == null)
            return;

        user.PasswordResetToken = null;
        user.PasswordResetTokenExpiration = DateTime.MinValue;
    }

    public static void CreatePasswordResetToken(this User user) {
        if (user == null)
            return;

        user.PasswordResetToken = StringExtensions.GetNewToken();
        user.PasswordResetTokenExpiration = SystemClock.UtcNow.AddMinutes(1440);
    }

    public static bool HasValidPasswordResetTokenExpiration(this User user) {
        if (user == null)
            return false;

        return user.PasswordResetTokenExpiration != DateTime.MinValue && user.PasswordResetTokenExpiration >= SystemClock.UtcNow;
    }

    public static void AddOAuthAccount(this User user, string providerName, string providerUserId, string username, SettingsDictionary data = null) {
        var account = new OAuthAccount {
            Provider = providerName.ToLowerInvariant(),
            ProviderUserId = providerUserId,
            Username = username
        };

        if (data != null)
            account.ExtraData.Apply(data);

        user.OAuthAccounts.Add(account);
    }

    public static bool RemoveOAuthAccount(this User user, string providerName, string providerUserId) {
        if (user.OAuthAccounts.Count <= 1 && String.IsNullOrEmpty(user.Password))
            return false;

        var account = user.OAuthAccounts.FirstOrDefault(o => o.Provider == providerName.ToLowerInvariant() && o.ProviderUserId == providerUserId);
        if (account == null)
            return true;

        return user.OAuthAccounts.Remove(account);
    }
}


text:
<!DOCTYPE html>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="referrer" content="always">
    <meta name="robots" content="index, follow">
    <link rel="icon" href="about:blank" type="image/x-icon">

    <title>
        Hong Kong-based Gatecoin and Bitspark Speaks Out Against Bank-imposed Limitations </title>

    <meta name="title" content="Hong Kong-based Gatecoin and Bitspark Speaks Out Against Bank-imposed Limitations">
    <meta name="description"
          content="Gatecoin faced with suspension and daily transaction limits from local banks, while Bitspark was denied setting up of bank accounts">
    <meta name="keywords"
          content="Cryptocurrency ; Gatecoin ; Bitspark ; Fubon Bank ; Hang Seng Bank ; Thomas Glucksmann ; Hong Kong">

    <link rel="stylesheet" type="text/css" href="../css/article-font.css">
    <link rel="stylesheet" href="../css/article.min.css">

                                        中文

                                 Unitalks

                                 News

                                 Knowledge

                                 Events

                                 Home

                                            Jiexiang

                                            <time> Nov 20, 2017</time>

                                        Hong Kong-based Gatecoin and Bitspark Speaks Out Against Bank-imposed
                                        Limitations

                                            "Gatecoin faced with suspension and daily transaction limits from local
                                            banks, while Bitspark was denied setting up of bank accounts"

Hong Kong-based Gatecoin was imposed
                                        with a daily transaction limit by Fubon Bank, forcing it suspend all
                                        cryptocurrency transfers conducted by its customers. Thomas Glucksmann, head of
                                        marketing at Gatecoin, added that the transaction limit was way below the
                                        allowance needed for their daily operations.

Reportedly, many Gatecoin customers were
                                        alarmed and perplexed, and some even contacted the police for fears that
                                        Gatecoin has collapsed, leading to complete losses in their investments.

This is not the first time that Gatecoin faced
                                        difficulties from banks in Hong Kong. Previously, their bank account was frozen
                                        by Hang Seng Bank – another bank in Hong Kong. Accordingly, Gatecoin was not
                                        offered a reason for the suspension, and they were not given notice prior to the
                                        suspension.

On the suspension of account by Hang Seng
                                        bank, "It was a major disruption to our business," Glucksmann said. "We had just
                                        tripled our customer base in a two to three month period, the price of bitcoin
                                        was rallying, the amount of money clients were depositing was increasing – the
                                        timing couldn't have been worse."

Bitspark, another cryptocurrency startup based
                                        in Hong Kong also faced difficulties with banks in the country. Bitspark was
                                        denied a bank account by many banks without being offered an explanation.

Both Gatecoin and Bitspark had to look for
                                        overseas banking solutions to meet their operational needs. They both leveraged
                                        on accounts set up in Europe.

Cryptocurrency regulation in Hong Kong

There is currently no cryptocurrency
                                        regulation in Hong Kong, and there has been no official statement from the
                                        government say that they will support or ban the blockchain-enabled currency.

Compared to neighbouring countries, Japan has
                                        officially recognized bitcoin exchanges in the country, and Singapore has
                                        recently announced its support for cryptocurrency via a regulatory sandbox for
                                        startups. In contrast, China has famously banned all new cryptocurrency
                                        ICOs.

                                            「 Declaration: Please indicate the source if repost the article in UNITIMES.
                                            Opinions expressed by Contributors belong to themselves. 」

                                            Tags:

                                                Cryptocurrency

                                                Gatecoin

                                                Bitspark

                                                Fubon Bank

                                                Hang Seng Bank

                                                Thomas Glucksmann

                                                Hong Kong

                                                        News

                                                        China Bans all Token Offering Financing Activities, Price of the
                                                        Virtual Currencies Decline

                                                                Xue Xu

                                                                    <time>4 Sept, 2017</time>

                                                        News

                                                        The 3rd Global Blockchain Summit Successfully Held in Shanghai

                                                                Qinghuan

                                                                    <time>18 Sept, 2017</time>

                                                        News

                                                        Ethereum's ERC-20 Token Standard Has Been Finalized

                                                                Qianxi

                                                                    <time>11 Sept, 2017</time>

© UNITIMES. All
                                    Rights Reserved.


text:
'use strict';

window.App = {};

$(function() {

	App.authorCollection = new App.AuthorCollection();
	App.mainContainer    = new App.Container({
		el: '#mainContainer'
	});

	App.authorCollection.fetch().then(function(authors) {
		var urlRegExp = /http:\/\/[htz]?\.?livetube\.cc\/([^\/]*)\/[^\/]*/;
		var query = {
			active  : true,
			windowId: chrome.windows.WINDOW_ID_CURRENT
		};

		chrome.tabs.query(query, function(tabs) {
			var currentTab = tabs[0];
			var currentURL = currentTab.url;
			var match = urlRegExp.exec(currentURL);

			if(match) {
				App.authorId = decodeURI(match[1]);
				App.tabId    = currentTab.id;

				var author = App.authorCollection.get(App.authorId);

				App.isNewAuthor = (typeof author === 'undefined');

				chrome.tabs.sendMessage(App.tabId, { action: 'getSelectedText' });
				chrome.runtime.onMessage.addListener(function(request, response, sendResponse) {
					App.selectedText = request.text;
					App.router = new App.Router();
					Backbone.history.start();
				});
			} else {
				App.router = new App.Router();
				Backbone.history.start();
			}
		});
	});
});


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
	<TextView
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:text="@string/hello"
	    />
	<Button
		android:id="@+id/record_button"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="@string/record_button"
		/>
	<Button
		android:id="@+id/stop_button"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:text="@string/stop_button"
		/>
	<net.appliedmadness.takingdictation.FileViewer
		android:id="@+id/file_viewer"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"
		/>
</LinearLayout>


text:
<!DOCTYPE HTML>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name='HandheldFriendly' content='True'>
<meta name='MobileOptimized' content='480'>
<meta name='format-detection' content='telephone=no'>
<meta name='viewport' content='initial-scale=1.0,width=device-width, minimum-scale=1.0, maximum-scale=1.0'>
<meta http-equiv='cleartype' content='on'>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="copyright" content="(C) 版权 2005"/>
<meta name="DC.rights.owner" content="(C) 版权 2005"/>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
<meta name="DC.Type" content="topic"/>
<meta name="DC.Title" content="浏览器"/>
<meta name="DC.Relation" scheme="URI" content="../../product_content/browser/task_browse_web_page.html"/>
<meta name="DC.Relation" scheme="URI" content="../../product_content/browser/task_add_new_bookmark.html"/>
<meta name="DC.Relation" scheme="URI" content="../../product_content/browser/task_set_home_page.html"/>
<meta name="DC.Relation" scheme="URI" content="../../product_content/browser/task_clear_visited_pages.html"/>
<meta name="DC.Relation" scheme="URI" content="../../index.html"/>
<meta name="DC.Format" content="XHTML"/>
<meta name="DC.Identifier" content="topic_browser"/>
<meta name="DC.Language" content="zh-cn"/>
<link rel="stylesheet" type="text/css" href="../../css/commonltr.css"/>
<link rel="stylesheet" type="text/css" href="../../css/my.css"/>
<title>浏览器</title>

    <link rel="stylesheet" type="text/css" href="css/my.css"/>

            浏览器

浏览网页

添加书签

设置主页

清除浏览记录


text:
package io.netty.handler.codec.spdy;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;

import java.util.zip.DataFormatException;
import java.util.zip.Inflater;

import static io.netty.handler.codec.spdy.SpdyCodecUtil.*;

final class SpdyHeaderBlockZlibDecoder extends SpdyHeaderBlockRawDecoder {

    private static final int DEFAULT_BUFFER_CAPACITY = 4096;

    private final Inflater decompressor = new Inflater();

    private ByteBuf decompressed;

    SpdyHeaderBlockZlibDecoder(SpdyVersion spdyVersion, int maxHeaderSize) {
        super(spdyVersion, maxHeaderSize);
    }

    @Override
    void decode(ByteBuf encoded, SpdyHeadersFrame frame) throws Exception {
        int len = setInput(encoded);

        int numBytes;
        do {
            numBytes = decompress(encoded.alloc(), frame);
        } while (numBytes > 0);

        if (decompressor.getRemaining() != 0) {
            throw new SpdyProtocolException("client sent extra data beyond headers");
        }

        encoded.skipBytes(len);
    }

    private int setInput(ByteBuf compressed) {
        int len = compressed.readableBytes();

        if (compressed.hasArray()) {
            decompressor.setInput(compressed.array(), compressed.arrayOffset() + compressed.readerIndex(), len);
        } else {
            byte[] in = new byte[len];
            compressed.getBytes(compressed.readerIndex(), in);
            decompressor.setInput(in, 0, in.length);
        }

        return len;
    }

    private int decompress(ByteBufAllocator alloc, SpdyHeadersFrame frame) throws Exception {
        ensureBuffer(alloc);
        byte[] out = decompressed.array();
        int off = decompressed.arrayOffset() + decompressed.writerIndex();
        try {
            int numBytes = decompressor.inflate(out, off, decompressed.writableBytes());
            if (numBytes == 0 && decompressor.needsDictionary()) {
                decompressor.setDictionary(SPDY_DICT);
                numBytes = decompressor.inflate(out, off, decompressed.writableBytes());
            }
            if (frame != null) {
                decompressed.writerIndex(decompressed.writerIndex() + numBytes);
                super.decode(decompressed, frame);
                decompressed.discardReadBytes();
            }

            return numBytes;
        } catch (DataFormatException e) {
            throw new SpdyProtocolException("Received invalid header block", e);
        }
    }

    private void ensureBuffer(ByteBufAllocator alloc) {
        if (decompressed == null) {
            decompressed = alloc.heapBuffer(DEFAULT_BUFFER_CAPACITY);
        }
        decompressed.ensureWritable(1);
    }

    @Override
    void reset() {
        releaseBuffer();
        super.reset();
    }

    @Override
    public void end() {
        releaseBuffer();
        decompressor.end();
        super.end();
    }

    private void releaseBuffer() {
        if (decompressed != null) {
            decompressed.release();
            decompressed = null;
        }
    }
}


text:
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddForeignKeysToMensagensTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
      Schema::table('mensagens', function(Blueprint $table)
      {
        $table->foreign('empresa_remetente', 'fk_remete_empresa2')->references('id')->on('empresas')->onUpdate('NO ACTION')->onDelete('NO ACTION');
        $table->foreign('freelancer_remetente', 'fk_remete_freela1')->references('id')->on('freelancers')->onUpdate('NO ACTION')->onDelete('NO ACTION');
      });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
     Schema::table('mensagens', function(Blueprint $table)
     {
      $table->dropForeign('fk_remete_empresa2');
      $table->dropForeign('fk_remete_freela1');
    });
   }
 }


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>RuleSetReference xref</title>
<link type="text/css" rel="stylesheet" href="../../../stylesheet.css" />

View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd;
5
6   import java.util.LinkedHashSet;
7   import java.util.Set;
8
9   /**
10   * This class represents a reference to RuleSet.
11   */
12  public class RuleSetReference {
13  	private String ruleSetFileName;
14  	private boolean allRules;
15  	private Set<String> excludes = new LinkedHashSet<String>(0);
16
17  	public RuleSetReference() {	}
18
19  	public RuleSetReference(String theFilename) {
20  		ruleSetFileName = theFilename;
21  	}
22
23  	public String getRuleSetFileName() {
24  		return ruleSetFileName;
25  	}
26
27  	public void setRuleSetFileName(String ruleSetFileName) {
28  		this.ruleSetFileName = ruleSetFileName;
29  	}
30
31  	public boolean isAllRules() {
32  		return allRules;
33  	}
34
35  	public void setAllRules(boolean allRules) {
36  		this.allRules = allRules;
37  	}
38
39  	public Set<String> getExcludes() {
40  		return excludes;
41  	}
42
43  	public void setExcludes(Set<String> excludes) {
44  		this.excludes = excludes;
45  	}
46
47  	public void addExclude(String name) {
48  		this.excludes.add(name);
49  	}
50  }

Copyright © 2002–2014 InfoEther. All rights reserved.


text:
from __future__ import annotations # isort:skip

import pytest ; pytest

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

# Standard library imports
import asyncio
import logging
import sys
from unittest.mock import MagicMock, patch

# External imports
from tornado.httpclient import HTTPError

# Bokeh imports
import bokeh.document as document
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.client import ClientSession, pull_session, push_session
from bokeh.core.properties import (
    AngleSpec,
    Any,
    Bytes,
    Dict,
    DistanceSpec,
    Instance,
    Int,
    Nullable,
    String,
)
from bokeh.core.types import ID
from bokeh.document import Document
from bokeh.document.events import ModelChangedEvent, TitleChangedEvent
from bokeh.model import Model
from bokeh.models import ColumnDataSource, Plot
from bokeh.util.token import generate_jwt_token
from tests.support.plugins.managed_server_loop import MSL
from tests.support.util.env import envset

from server._util_server import (
    http_get,
    url,
    websocket_open,
    ws_url,
)

# Module under test

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

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

class AnotherModelInTestClientServer(Model):
    bar = Int(1)

class SomeModelInTestClientServer(Model):
    foo = Int(2)
    child = Nullable(Instance(Model))
    data = Bytes()

class DictModel(Model):
    values = Dict(String, Any)

class UnitsSpecModel(Model):
    distance = DistanceSpec(42)
    angle = AngleSpec(0)

logging.basicConfig(level=logging.DEBUG)

class TestClientServer:
    def test_minimal_connect_and_disconnect(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            # we don't have to start the server because it
            # uses the same main loop as the client, so
            # if we start either one it starts both
            session = ClientSession(session_id=ID("test_minimal_connect_and_disconnect"),
                                    io_loop = server.io_loop,
                                    websocket_url = ws_url(server))
            session.connect()
            assert session.connected

    def test_disconnect_on_error(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            session = ClientSession(session_id=ID("test_disconnect_on_error"),
                                    websocket_url=ws_url(server),
                                    io_loop = server.io_loop)
            session.connect()
            assert session.connected
            # send a bogus message using private fields
            server.io_loop.add_callback(session._connection._socket.write_message, b"xx", binary=True)
            # connection should now close on the server side
            # and the client loop should end
            session._loop_until_closed()
            assert not session.connected
            session.close()
            session._loop_until_closed()
            assert not session.connected

    def test_connect_with_prefix(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application, prefix="foo") as server:
            # we don't have to start the server because it
            # uses the same main loop as the client, so
            # if we start either one it starts both
            session = ClientSession(io_loop = server.io_loop,
                                    websocket_url = ws_url(server, "/foo"))
            session.connect()
            assert session.connected
            session.close()
            session._loop_until_closed()

            session = ClientSession(io_loop = server.io_loop,
                                    websocket_url = ws_url(server))
            session.connect()
            assert not session.connected
            session.close()
            session._loop_until_closed()

    async def check_http_gets_fail(self, server):
        with pytest.raises(HTTPError):
            await http_get(server.io_loop, url(server))
        with pytest.raises(HTTPError):
            await http_get(server.io_loop, url(server) + "autoload.js?bokeh-autoload-element=foo")

    async def check_connect_session_fails(self, server, origin):
        with pytest.raises(HTTPError):
            subprotocols = ["bokeh", generate_jwt_token("foo")]
            await websocket_open(server.io_loop,
                                 ws_url(server),
                                 origin=origin,
                                 subprotocols=subprotocols)

    async def check_http_gets(self, server):
        await http_get(server.io_loop, url(server))
        await http_get(server.io_loop, url(server) + "autoload.js?bokeh-autoload-element=foo")

    async def check_connect_session(self, server, origin):
        subprotocols = ["bokeh", generate_jwt_token("foo")]
        await websocket_open(server.io_loop,
                             ws_url(server),
                             origin=origin,
                             subprotocols=subprotocols)

    async def check_http_ok_socket_ok(self, server, origin=None):
        await self.check_http_gets(server)
        await self.check_connect_session(server, origin=origin)

    async def check_http_ok_socket_blocked(self, server, origin=None):
        await self.check_http_gets(server)
        await self.check_connect_session_fails(server, origin=origin)

    async def check_http_blocked_socket_blocked(self, server, origin=None):
        await self.check_http_gets_fail(server)
        await self.check_connect_session_fails(server, origin=origin)

    async def test_allow_websocket_origin(self, ManagedServerLoop: MSL) -> None:
        application = Application()

        # allow good local origin with random port
        with ManagedServerLoop(application, port=0) as server:
            await self.check_http_ok_socket_ok(server, origin="http://localhost:%s" % server.port)

        # allow good origin
        with ManagedServerLoop(application, allow_websocket_origin=["example.com"]) as server:
            await self.check_http_ok_socket_ok(server, origin="http://example.com:80")

        # allow good origin from environment variable
        with ManagedServerLoop(application) as server:
            with envset(BOKEH_ALLOW_WS_ORIGIN="example.com"):
                await self.check_http_ok_socket_ok(server, origin="http://example.com:80")

        # allow good origin with port
        with ManagedServerLoop(application, allow_websocket_origin=["example.com:8080"]) as server:
            await self.check_http_ok_socket_ok(server, origin="http://example.com:8080")

        # allow good origin with port from environment variable
        with ManagedServerLoop(application) as server:
            with envset(BOKEH_ALLOW_WS_ORIGIN="example.com:8080"):
                await self.check_http_ok_socket_ok(server, origin="http://example.com:8080")

        # allow good origin header with an implicit 80
        with ManagedServerLoop(application, allow_websocket_origin=["example.com"]) as server:
            await self.check_http_ok_socket_ok(server, origin="http://example.com")

        # allow good origin header with an implicit 80
        with ManagedServerLoop(application) as server:
            with envset(BOKEH_ALLOW_WS_ORIGIN="example.com"):
                await self.check_http_ok_socket_ok(server, origin="http://example.com")

        # block non-Host origins by default even if no extra origins specified
        with ManagedServerLoop(application) as server:
            await self.check_http_ok_socket_blocked(server, origin="http://example.com:80")

        # block on a garbage Origin header
        with ManagedServerLoop(application) as server:
            await self.check_http_ok_socket_blocked(server, origin="hsdf:::///%#^$#:8080")

        # block bad origin
        with ManagedServerLoop(application, allow_websocket_origin=["example.com"]) as server:
            await self.check_http_ok_socket_blocked(server, origin="http://foobar.com:80")

        # block bad origin from environment variable
        with ManagedServerLoop(application) as server:
            with envset(BOKEH_ALLOW_WS_ORIGIN="example.com"):
                await self.check_http_ok_socket_blocked(server, origin="http://foobar.com:80")

        # block bad origin port
        with ManagedServerLoop(application, allow_websocket_origin=["example.com:8080"]) as server:
            await self.check_http_ok_socket_blocked(server, origin="http://example.com:8081")

        # block bad origin port from environment variable
        with ManagedServerLoop(application) as server:
            with envset(BOKEH_ALLOW_WS_ORIGIN="example.com:8080"):
                await self.check_http_ok_socket_blocked(server, origin="http://example.com:8081")

    def test_push_document(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()
            doc.add_root(AnotherModelInTestClientServer(bar=43))
            doc.add_root(SomeModelInTestClientServer(foo=42, data=bytes([0x00, 0x01, 0xFE, 0xFF])))

            client_session = push_session(doc,
                                          session_id=ID("test_push_document"),
                                          url=url(server),
                                          io_loop=server.io_loop)

            assert client_session.document == doc
            assert len(client_session.document.roots) == 2

            server_session = server.get_session('/', client_session.id)

            assert len(server_session.document.roots) == 2
            results = {}
            for r in server_session.document.roots:
                if hasattr(r, 'foo'):
                    results['foo'] = r.foo
                if hasattr(r, 'bar'):
                    results['bar'] = r.bar
            assert results['foo'] == 42
            assert results['bar'] == 43

            client_session.close()
            client_session._loop_until_closed()
            assert not client_session.connected

    def test_pull_document(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        def add_roots(doc: Document):
            doc.add_root(AnotherModelInTestClientServer(bar=43))
            doc.add_root(SomeModelInTestClientServer(foo=42, data=bytes([0x00, 0x01, 0xFE, 0xFF])))
        handler = FunctionHandler(add_roots)
        application.add(handler)

        with ManagedServerLoop(application) as server:
            client_session = pull_session(session_id=ID("test_pull_document"),
                                          url=url(server),
                                          io_loop=server.io_loop)
            assert len(client_session.document.roots) == 2

            server_session = server.get_session('/', client_session.id)
            assert len(server_session.document.roots) == 2

            results = {}
            for r in server_session.document.roots:
                if hasattr(r, 'foo'):
                    results['foo'] = r.foo
                if hasattr(r, 'bar'):
                    results['bar'] = r.bar
            assert results['foo'] == 42
            assert results['bar'] == 43

            client_session.close()
            client_session._loop_until_closed()
            assert not client_session.connected

    def test_pull_large_document(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        def add_roots(doc):
            import numpy as np
            rows, cols = (40000, 100)
            columns=['x'+str(i) for i in range(cols)]
            a = np.random.randn(cols, rows)
            source = ColumnDataSource(data=dict(zip(columns, a)))
            doc.add_root(source)
        handler = FunctionHandler(add_roots)
        application.add(handler)

        with ManagedServerLoop(application) as server:
            client_session = pull_session(session_id=ID("test_pull_document"),
                                          url=url(server),
                                          io_loop=server.io_loop,
                                          max_message_size=50000000)
            assert len(client_session.document.roots) == 1

            server_session = server.get_session('/', client_session.id)
            assert len(server_session.document.roots) == 1

            results = {}
            for r in server_session.document.roots:
                if hasattr(r, 'data'):
                    results['data'] = r.data
            assert len(list(results['data'].keys())) == 100
            assert all(len(x) == 40000 for x in results['data'].values())

            client_session.close()
            client_session._loop_until_closed()
            assert not client_session.connected

    def test__check_error_404(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            with pytest.raises(IOError):
                pull_session(session_id=ID("test__check_error_404"),
                                              url=url(server) + 'file_not_found',
                                              io_loop=server.io_loop)

    def test_request_server_info(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            session = ClientSession(session_id=ID("test_request_server_info"),
                                    websocket_url=ws_url(server),
                                    io_loop=server.io_loop)
            session.connect()
            assert session.connected
            assert session.document is None

            info = session.request_server_info()

            from bokeh import __version__

            assert info['version_info']['bokeh'] == __version__
            assert info['version_info']['server'] == __version__

            session.close()
            session._loop_until_closed()
            assert not session.connected

    @pytest.mark.skipif(sys.platform == "win32", reason="uninmportant failure on win")
    def test_ping(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application, keep_alive_milliseconds=0) as server:
            session = ClientSession(session_id=ID("test_ping"),
                                    websocket_url=ws_url(server),
                                    io_loop=server.io_loop)
            session.connect()
            assert session.connected
            assert session.document is None

            connection = next(iter(server._tornado._clients))
            expected_pong = connection._ping_count
            server._tornado._keep_alive() # send ping
            session.force_roundtrip()

            assert expected_pong == connection._socket.latest_pong

            # check that each ping increments by 1
            server._tornado._keep_alive()
            session.force_roundtrip()

            assert (expected_pong + 1) == connection._socket.latest_pong

            session.close()
            session._loop_until_closed()
            assert not session.connected

    def test_client_changes_go_to_server(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()
            client_root = SomeModelInTestClientServer(foo=42, data=bytes([0x00, 0x01, 0xFE, 0xFF]))

            client_session = push_session(doc, session_id=ID("test_client_changes_go_to_server"),
                                          url=url(server),
                                          io_loop=server.io_loop)
            server_session = server.get_session('/', client_session.id)

            assert len(server_session.document.roots) == 0

            doc.add_root(client_root)
            client_session.force_roundtrip() # be sure events have been handled on server

            assert len(server_session.document.roots) == 1
            server_root = next(iter(server_session.document.roots))

            assert client_root.foo == 42
            assert server_root.foo == 42

            # Now try setting title
            assert server_session.document.title == document.DEFAULT_TITLE
            doc.title = "Client Title"
            client_session.force_roundtrip() # be sure events have been handled on server

            assert server_session.document.title == "Client Title"

            # Now modify an attribute on a client model
            client_root.foo = 57

            # there is no great way to block until the server
            # has applied changes, since patches are sent
            # asynchronously. We use internal _loop_until API.
            def server_change_made():
                return server_root.foo == 57
            client_session._connection._loop_until(server_change_made)
            assert server_root.foo == 57

            doc.remove_root(client_root)
            client_session.force_roundtrip() # be sure events have been handled on server
            assert len(server_session.document.roots) == 0

            client_session.close()
            client_session._loop_until_closed()
            assert not client_session.connected

    def test_server_changes_go_to_client(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()

            client_session = push_session(doc,
                                          session_id=ID("test_server_changes_go_to_client"),
                                          url=url(server),
                                          io_loop=server.io_loop)
            server_session = server.get_session('/', client_session.id)

            assert len(client_session.document.roots) == 0
            server_root = SomeModelInTestClientServer(foo=42, data=bytes([0x00, 0x01, 0xFE, 0xFF]))

            def do_add_server_root():
                server_session.document.add_root(server_root)
            server.io_loop.add_callback(server_session.with_document_locked, do_add_server_root)

            def client_has_root():
                return len(doc.roots) > 0
            client_session._connection._loop_until(client_has_root)
            client_root = next(iter(client_session.document.roots))

            assert client_root.foo == 42
            assert server_root.foo == 42

            # Now try setting title on server side
            def do_set_server_title():
                server_session.document.title = "Server Title"
            server.io_loop.add_callback(server_session.with_document_locked, do_set_server_title)

            def client_title_set():
                return client_session.document.title != document.DEFAULT_TITLE
            client_session._connection._loop_until(client_title_set)

            assert client_session.document.title == "Server Title"

            # Now modify a model within the server document
            def do_set_property_on_server():
                server_root.foo = 57
            server.io_loop.add_callback(server_session.with_document_locked, do_set_property_on_server)

            # there is no great way to block until the server
            # has applied changes, since patches are sent
            # asynchronously. We use internal _loop_until API.
            def client_change_made():
                return client_root.foo == 57
            client_session._connection._loop_until(client_change_made)
            assert client_root.foo == 57

            def do_remove_server_root():
                server_session.document.remove_root(server_root)
            server.io_loop.add_callback(server_session.with_document_locked, do_remove_server_root)

            def client_lacks_root():
                return len(doc.roots) == 0
            client_session._connection._loop_until(client_lacks_root)
            assert len(client_session.document.roots) == 0

            client_session.close()
            client_session._loop_until_closed()
            assert not client_session.connected

    async def async_value(self, value):
        await asyncio.sleep(0) # this ensures we actually return to the loop
        return value

    def test_client_session_timeout_async(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()

            client_session = push_session(doc,
                                          session_id=ID("test_client_session_timeout_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)

            result = DictModel()
            doc.add_root(result)

            async def cb():
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = doc.add_timeout_callback(cb, 10)

            client_session._loop_until_closed()

            with pytest.raises(ValueError) as exc:
                doc.remove_timeout_callback(cb_id)
            assert 'already removed' in repr(exc.value)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    def test_client_session_timeout_async_added_before_push(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()

            result = DictModel()
            doc.add_root(result)

            async def cb():
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = doc.add_timeout_callback(cb, 10)

            client_session = push_session(doc,
                                          session_id=ID("test_client_session_timeout_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)

            client_session._loop_until_closed()

            with pytest.raises(ValueError) as exc:
                doc.remove_timeout_callback(cb_id)
            assert 'already removed' in repr(exc.value)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    @pytest.mark.skip(reason="broken (see PR #9426)")
    def test_server_session_timeout_async(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()
            doc.add_root(DictModel())

            client_session = push_session(doc,
                                          session_id=ID("test_server_session_timeout_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)
            server_session = server.get_session('/', client_session.id)

            result = next(iter(server_session.document.roots))

            async def cb():
                # we're testing that we can modify the doc and be
                # "inside" the document lock
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = server_session.document.add_timeout_callback(cb, 10)

            client_session._loop_until_closed()

            with pytest.raises(ValueError) as exc:
                server_session.document.remove_timeout_callback(cb_id)
            assert 'already removed' in repr(exc.value)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    def test_client_session_next_tick_async(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()

            client_session = push_session(doc,
                                          session_id=ID("test_client_session_next_tick_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)

            result = DictModel()
            doc.add_root(result)

            async def cb():
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = doc.add_next_tick_callback(cb)

            client_session._loop_until_closed()

            with pytest.raises(ValueError) as exc:
                doc.remove_next_tick_callback(cb_id)
            assert 'already removed' in repr(exc.value)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    def test_client_session_next_tick_async_added_before_push(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()

            result = DictModel()
            doc.add_root(result)

            async def cb():
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = doc.add_next_tick_callback(cb)

            client_session = push_session(doc,
                                          session_id=ID("test_client_session_next_tick_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)

            client_session._loop_until_closed()

            with pytest.raises(ValueError) as exc:
                doc.remove_next_tick_callback(cb_id)
            assert 'already removed' in repr(exc.value)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    @pytest.mark.skip(reason="broken (see PR #9426)")
    def test_server_session_next_tick_async(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server: # XXX io_loop=IOLoop()
            doc = document.Document()
            doc.add_root(DictModel())

            client_session = push_session(doc,
                                          session_id=ID("test_server_session_next_tick_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)
            server_session = server.get_session('/', client_session.id)

            result = next(iter(server_session.document.roots))

            async def cb():
                # we're testing that we can modify the doc and be
                # "inside" the document lock
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = server_session.document.add_next_tick_callback(cb)

            client_session._loop_until_closed()

            with pytest.raises(ValueError) as exc:
                server_session.document.remove_next_tick_callback(cb_id)
            assert 'already removed' in repr(exc.value)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    def test_client_session_periodic_async(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()

            client_session = push_session(doc,
                                          session_id=ID("test_client_session_periodic_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)

            result = DictModel()
            doc.add_root(result)

            async def cb():
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = doc.add_periodic_callback(cb, 10)

            client_session._loop_until_closed()

            doc.remove_periodic_callback(cb_id)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    def test_client_session_periodic_async_added_before_push(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()

            result = DictModel()
            doc.add_root(result)

            async def cb():
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = doc.add_periodic_callback(cb, 10)

            client_session = push_session(doc,
                                          session_id=ID("test_client_session_periodic_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)

            client_session._loop_until_closed()

            doc.remove_periodic_callback(cb_id)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    @pytest.mark.skip(reason="broken (see PR #9426)")
    def test_server_session_periodic_async(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        with ManagedServerLoop(application) as server:
            doc = document.Document()
            doc.add_root(DictModel())

            client_session = push_session(doc,
                                          session_id=ID("test_server_session_periodic_async"),
                                          url=url(server),
                                          io_loop=server.io_loop)
            server_session = server.get_session('/', client_session.id)

            result = next(iter(server_session.document.roots))

            async def cb():
                # we're testing that we can modify the doc and be
                # "inside" the document lock
                result.values['a'] = 0
                result.values['b'] = await self.async_value(1)
                result.values['c'] = await self.async_value(2)
                result.values['d'] = await self.async_value(3)
                result.values['e'] = await self.async_value(4)
                client_session.close()
                return 5

            cb_id = server_session.document.add_periodic_callback(cb, 10)

            client_session._loop_until_closed()

            server_session.document.remove_periodic_callback(cb_id)

            assert dict(a=0, b=1, c=2, d=3, e=4) == result.values

    @pytest.mark.skip(reason="broken (see PR #9426)")
    def test_lots_of_concurrent_messages(self, ManagedServerLoop: MSL) -> None:
        application = Application()
        def setup_stuff(doc):
            m1 = AnotherModelInTestClientServer(bar=43, name='m1')
            m2 = SomeModelInTestClientServer(foo=42, name='m2', data=bytes([0x00, 0x01, 0xFE, 0xFF]))
            m3 = SomeModelInTestClientServer(foo=68, name='m3', data=bytes([0x00, 0x01, 0xFE, 0xFF]))
            doc.add_root(m1)
            doc.add_root(m2)
            doc.add_root(m3)
            def timeout1():
                m1.bar += 1
            timeout1_cb_id = doc.add_timeout_callback(timeout1, 1)
            def timeout2():
                m2.foo +=1
            timeout2_cb_id = doc.add_timeout_callback(timeout2, 3)
            def periodic1():
                m1.bar += 1
                doc.remove_timeout_callback(timeout1_cb_id)
                doc.add_timeout_callback(timeout1, m1.bar % 7)
            doc.add_periodic_callback(periodic1, 3)
            def periodic2():
                m2.foo += 1
                doc.remove_timeout_callback(timeout2_cb_id)
                doc.add_timeout_callback(timeout2, m2.foo % 7)
            doc.add_periodic_callback(periodic2, 1)

            def server_on_change(event):
                if isinstance(event, ModelChangedEvent) and event.model is m3:
                    return
                m3.foo += 1

            doc.on_change(server_on_change)

        handler = FunctionHandler(setup_stuff)
        application.add(handler)

        # keep_alive_milliseconds=1 sends pings as fast as the OS will let us
        with ManagedServerLoop(application, keep_alive_milliseconds=1) as server:
            session = pull_session(session_id=ID("test_lots_of_concurrent_messages"),
                                   url=url(server),
                                   io_loop=server.io_loop)
            assert session.connected

            server_session = server.get_session('/', session.id)

            def client_timeout():
                m = session.document.roots[0]
                m.name = m.name[::-1]
            cb_id = session.document.add_timeout_callback(client_timeout, 3)

            def client_periodic():
                m = session.document.roots[1]
                m.name = m.name[::-1]
                session.document.remove_timeout_callback(cb_id)
                session.document.add_timeout_callback(client_timeout, 3)

            session.document.add_periodic_callback(client_periodic, 1)

            result = {}
            def end_test():
                result['connected'] = session.connected
                result['server_connection_count'] = server_session.connection_count
                result['server_close_code'] = next(iter(server._tornado._clients))._socket.close_code
                result['doc'] = session.document.to_json()
                session.close()

            # making this longer is more likely to trigger bugs, but it also
            # makes the test take however much time you put here
            session.document.add_timeout_callback(end_test, 250)

            def client_on_change(event):
                if not isinstance(event, TitleChangedEvent):
                    session.document.title = session.document.title[::-1]

            session.document.on_change(client_on_change)

            session._loop_until_closed()

            assert not session.connected

            # we should have still been connected at the end,
            # if we didn't have any crazy protocol errors
            assert 'connected' in result
            assert result['connected']

            # server should also still have been connected
            assert result['server_connection_count'] == 1
            assert result['server_close_code'] is None

def test_client_changes_do_not_boomerang(monkeypatch: pytest.MonkeyPatch, ManagedServerLoop: MSL) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        doc = document.Document()
        client_root = SomeModelInTestClientServer(foo=42, data=bytes([0x00, 0x01, 0xFE, 0xFF]))
        doc.add_root(client_root)

        client_session = push_session(doc,
                                      session_id=ID("test_client_changes_do_not_boomerang"),
                                      url=url(server),
                                      io_loop=server.io_loop)
        server_session = server.get_session('/', client_session.id)

        assert len(server_session.document.roots) == 1
        server_root = next(iter(server_session.document.roots))

        assert client_root.foo == 42
        assert server_root.foo == 42

        got_angry = {}
        got_angry['result'] = None
        # trap any boomerang
        def get_angry(message):
            got_angry['result'] = message
        monkeypatch.setattr(client_session, '_handle_patch', get_angry)

        # Now modify the client document
        client_root.foo = 57

        # wait until server side change made ... but we may not have the
        # boomerang yet
        def server_change_made():
            return server_root.foo == 57
        client_session._connection._loop_until(server_change_made)
        assert server_root.foo == 57

        # force a round trip to be sure we get the boomerang if we're going to
        client_session.force_roundtrip()

        assert got_angry['result'] is None

        client_session.close()
        client_session._loop_until_closed()
        assert not client_session.connected
        server.unlisten() # clean up so next test can run

def test_server_changes_do_not_boomerang(monkeypatch: pytest.MonkeyPatch, ManagedServerLoop: MSL) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        doc = document.Document()
        client_root = SomeModelInTestClientServer(foo=42, data=bytes([0x00, 0x01, 0xFE, 0xFF]))
        doc.add_root(client_root)

        client_session = push_session(doc,
                                      session_id=ID("test_server_changes_do_not_boomerang"),
                                      url=url(server),
                                      io_loop=server.io_loop)
        server_session = server.get_session('/', client_session.id)

        assert len(server_session.document.roots) == 1
        server_root = next(iter(server_session.document.roots))

        assert client_root.foo == 42
        assert server_root.foo == 42

        got_angry = {}
        got_angry['result'] = None
        # trap any boomerang
        def get_angry(message, connection):
            got_angry['result'] = message
        monkeypatch.setattr(server_session, '_handle_patch', get_angry)

        # Now modify the server document
        def do_set_foo_property():
            server_root.foo = 57
        server.io_loop.add_callback(server_session.with_document_locked, do_set_foo_property)

        # there is no great way to block until the server
        # has applied changes, since patches are sent
        # asynchronously. We use internal _loop_until API.
        def client_change_made():
            return client_root.foo == 57
        client_session._connection._loop_until(client_change_made)
        assert client_root.foo == 57

        # force a round trip to be sure we get the boomerang if we're going to
        client_session.force_roundtrip()

        assert got_angry['result'] is None

        client_session.close()
        client_session._loop_until_closed()
        assert not client_session.connected

# this test is because we do the funky get_value
# tricks with the units specs
def test_unit_spec_changes_do_not_boomerang(monkeypatch: pytest.MonkeyPatch, ManagedServerLoop: MSL) -> None:
    application = Application()
    with ManagedServerLoop(application) as server:
        doc = document.Document()
        client_root = UnitsSpecModel()
        doc.add_root(client_root)

        client_session = push_session(doc,
                                      session_id=ID("test_unit_spec_changes_do_not_boomerang"),
                                      url=url(server),
                                      io_loop=server.io_loop)
        server_session = server.get_session('/', client_session.id)

        assert len(server_session.document.roots) == 1
        server_root = next(iter(server_session.document.roots))

        assert client_root.distance == 42
        assert server_root.angle == 0

        def change_to(new_distance, new_angle):
            got_angry = {}
            got_angry['result'] = None
            # trap any boomerang
            def get_angry(message):
                got_angry['result'] = message
            monkeypatch.setattr(client_session, '_handle_patch', get_angry)

            server_previous_distance = server_root.distance
            server_previous_angle = server_root.angle

            # Now modify the client document
            client_root.distance = new_distance
            client_root.angle = new_angle

            # wait until server side change made ... but we may not have the
            # boomerang yet
            def server_change_made():
                return server_root.distance != server_previous_distance and \
                    server_root.angle != server_previous_angle
            client_session._connection._loop_until(server_change_made)

            # force a round trip to be sure we get the boomerang if we're going to
            client_session.force_roundtrip()

            assert got_angry['result'] is None

        change_to(57, 1)
        change_to({ 'value' : 58 }, { 'value' : 2 })
        change_to({ 'field' : 'foo' }, { 'field' : 'bar' })
        change_to({ 'value' : 59, 'units' : 'screen' }, { 'value' : 30, 'units' : 'deg' })

        client_session.close()
        server.unlisten() # clean up so next test can run
        client_session._loop_until_closed()
        assert not client_session.connected

@patch('bokeh.client.session.show_session')
def test_session_show_adds_obj_to_curdoc_if_necessary(m: MagicMock) -> None:
    session = ClientSession()
    session._document = Document()
    p = Plot()
    assert session.document.roots == []
    session.show(p)
    assert session.document.roots == [p]

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

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

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------


text:
// This file is automatically generated.

package adila.db;

/*
 * Huawei X2
 *
 * DEVICE: HWGemini
 * MODEL: GEM-702L
 */
final class hwgemini_gem2d702l {
    public static final String DATA = "Huawei|X2|";
}


text:
<?php
namespace Chamilo\Core\Repository\ContentObject\LearningPath\Display\Component;

use Chamilo\Libraries\Architecture\Application\ApplicationConfiguration;
use Chamilo\Libraries\Architecture\Application\ApplicationFactory;
use Chamilo\Libraries\Architecture\Interfaces\ApplicationSupport;

/**
 *
 * @package core\repository\content_object\learning_path\display
 * @author Hans De Bisschop <hans.de.bisschop@ehb.be>
 * @author Magali Gillard <magali.gillard@ehb.be>
 * @author Eduard Vossen <eduard.vossen@ehb.be>
 */
class TypeSpecificComponent extends BaseHtmlTreeComponent implements ApplicationSupport
{

    /**
     * Executes this component
     */
    public function build()
    {
        $this->validateSelectedTreeNodeData();

        $object_namespace = $this->getCurrentTreeNode()->getContentObject()->package();
        $integration_namespace = $object_namespace .
             '\Integration\Chamilo\Core\Repository\ContentObject\LearningPath\Display';

        $factory = new ApplicationFactory(
            $integration_namespace,
            new ApplicationConfiguration($this->getRequest(), $this->get_user(), $this));
        return $factory->run();
    }

    public function get_additional_parameters()
    {
        return array(self::PARAM_CHILD_ID, self::PARAM_FULL_SCREEN);
    }
}


text:
use std::{isize, i8, i16, i32, i64};
use std::thread;

fn main() {
    assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
    //~^ ERROR attempted to divide with overflow in a constant expression
    assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    //~^ ERROR attempted to divide with overflow in a constant expression
    assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    //~^ ERROR attempted to divide with overflow in a constant expression
    assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    //~^ ERROR attempted to divide with overflow in a constant expression
    assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    //~^ ERROR attempted to divide with overflow in a constant expression
    assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    //~^ ERROR attempted to divide by zero in a constant expression
    assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    //~^ ERROR attempted to divide by zero in a constant expression
    assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    //~^ ERROR attempted to divide by zero in a constant expression
    assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    //~^ ERROR attempted to divide by zero in a constant expression
    assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    //~^ ERROR attempted to divide by zero in a constant expression
    assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    //~^ ERROR attempted remainder with overflow in a constant expression
    assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    //~^ ERROR attempted remainder with overflow in a constant expression
    assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    //~^ ERROR attempted remainder with overflow in a constant expression
    assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    //~^ ERROR attempted remainder with overflow in a constant expression
    assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    //~^ ERROR attempted remainder with overflow in a constant expression
    assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    //~^ ERROR attempted remainder with a divisor of zero in a constant expression
    assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    //~^ ERROR attempted remainder with a divisor of zero in a constant expression
    assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    //~^ ERROR attempted remainder with a divisor of zero in a constant expression
    assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    //~^ ERROR attempted remainder with a divisor of zero in a constant expression
    assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    //~^ ERROR attempted remainder with a divisor of zero in a constant expression
}


text:
<BroadcastMonitor>
  <updated>2015-08-02T20:08:11</updated>
  <stationName>Radio 6</stationName>
  <Current>
    <startTime></startTime>
    <itemId></itemId>
    <titleId></titleId>
    <itemCode></itemCode>
    <itemReference></itemReference>
    <titleName></titleName>
    <artistName></artistName>
    <albumName></albumName>
    <CategoryCode></CategoryCode>
    <CategoryName></CategoryName>
    <itemDuration></itemDuration>
    <MultiMedia1></MultiMedia1>
    <MultiMedia2></MultiMedia2>
    <MultiMedia3></MultiMedia3>
    <MultiMedia4></MultiMedia4>
  </Current>
  <Next>
    <startTime>2015-08-02T20:08:10</startTime>
    <itemId>1000080498:0</itemId>
    <titleId>216110875</titleId>
    <itemCode></itemCode>
    <itemReference></itemReference>
    <titleName>*** SCHIJF VAN 6 - 2014 (KORT)</titleName>
    <artistName></artistName>
    <albumName></albumName>
    <CategoryCode>758</CategoryCode>
    <CategoryName>HOOFD UUROPENERS</CategoryName>
    <itemDuration>4</itemDuration>
    <MultiMedia1></MultiMedia1>
    <MultiMedia2></MultiMedia2>
    <MultiMedia3></MultiMedia3>
    <MultiMedia4></MultiMedia4>
  </Next>
</BroadcastMonitor>


text:
angular.module('proBebe.factories').factory('ScrollPositions', [
  function() {
    return {};
  }
]);


text:
layout: archive
lang: en
ref: python_ping_protocol_2_0
read_time: true
share: true
author_profile: false
permalink: /docs/en/software/dynamixel/dynamixel_sdk/sample_code/python_ping_protocol_2_0/
sidebar:
  title: DYNAMIXEL SDK
  nav: "dynamixel_sdk"
---

### [Python Ping Protocol 2.0](#python-ping-protocol-20)

- Description

  This example tries to ping Dynamixel and shows the model number responded from Dynamixel. The example is commonly used to check for Dynamixel's connection or to get model number to refer its specification.

- Available Dynamixel

  All series using protocol 2.0

#### Sample code

```python
#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# ping.py
#
#  Created on: 2016. 6. 16.
#      Author: Ryu Woon Jung (Leon)
#

#
# *********     ping Example      *********
#
#
# Available Dynamixel model on this example : All models using Protocol 2.0
# This example is designed for using a Dynamixel PRO 54-200, and an USB2DYNAMIXEL.
# To use another Dynamixel model, such as X series, see their details in E-Manual(support.robotis.com) and edit below variables yourself.
# Be sure that Dynamixel PRO properties are already set as %% ID : 1 / Baudnum : 3 (Baudrate : 1000000 [1M])
#

import os, sys

if os.name == 'nt':
    import msvcrt
    def getch():
        return msvcrt.getch().decode()
else:
    import tty, termios
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    tty.setraw(sys.stdin.fileno())
    def getch():
        return sys.stdin.read(1)

os.sys.path.append('../dynamixel_functions_py')             # Path setting

import dynamixel_functions as dynamixel                     # Uses DYNAMIXEL SDK library

# Protocol version
PROTOCOL_VERSION            = 2                             # See which protocol version is used in the Dynamixel

# Default setting
DXL_ID                      = 1                             # Dynamixel ID: 1
BAUDRATE                    = 1000000
DEVICENAME                  = "/dev/ttyUSB0".encode('utf-8')        # Check which port is being used on your controller
                                                            # ex) Windows: "COM1"   Linux: "/dev/ttyUSB0"

COMM_SUCCESS                = 0                             # Communication Success result value
COMM_TX_FAIL                = -1001                         # Communication Tx Failed

# Initialize PortHandler Structs
# Set the port path
# Get methods and members of PortHandlerLinux or PortHandlerWindows
port_num = dynamixel.portHandler(DEVICENAME)

# Initialize PacketHandler Structs
dynamixel.packetHandler()

dxl_comm_result = COMM_TX_FAIL                              # Communication result

# Open port
if dynamixel.openPort(port_num):
    print("Succeeded to open the port!")
else:
    print("Failed to open the port!")
    print("Press any key to terminate...")
    getch()
    quit()

# Set port baudrate
if dynamixel.setBaudRate(port_num, BAUDRATE):
    print("Succeeded to change the baudrate!")
else:
    print("Failed to change the baudrate!")
    print("Press any key to terminate...")
    getch()
    quit()

# Try to ping the Dynamixel
# Get Dynamixel model number
dxl_model_number = dynamixel.pingGetModelNum(port_num, PROTOCOL_VERSION, DXL_ID)
if dynamixel.getLastTxRxResult(port_num, PROTOCOL_VERSION) != COMM_SUCCESS:
    dynamixel.printTxRxResult(PROTOCOL_VERSION, dynamixel.getLastTxRxResult(port_num, PROTOCOL_VERSION))
elif dynamixel.getLastRxPacketError(port_num, PROTOCOL_VERSION) != 0:
    dynamixel.printRxPacketError(PROTOCOL_VERSION, dynamixel.getLastRxPacketError(port_num, PROTOCOL_VERSION))

print("[ID:%03d] ping Succeeded. Dynamixel model number : %d" % (DXL_ID, dxl_model_number))

# Close port
dynamixel.closePort(port_num)
```

#### Details

```python
import os, sys

if os.name == 'nt':
    import msvcrt
    def getch():
        return msvcrt.getch().decode()
else:
    import tty, termios
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    tty.setraw(sys.stdin.fileno())
    def getch():
        return sys.stdin.read(1)

os.sys.path.append('../dynamixel_functions_py')             # Path setting

import dynamixel_functions as dynamixel                     # Uses DYNAMIXEL SDK library
```

`getch()` gets the input which is for example code control.

`os.sys.path.append()` sets paths of function reference.

This example uses `dynamixel_functions` library as `dynamixel` imported from `dynamixel_functions_py` package.

```python
# Protocol version
PROTOCOL_VERSION            = 2                             # See which protocol version is used in the Dynamixel
```

Dynamixel uses either or both protocols: Protocol 1.0 and Protocol 2.0. Choose one of the Protocol which is appropriate in the Dynamixel.

```python
# Default setting
DXL_ID                      = 1                             # Dynamixel ID: 1
BAUDRATE                    = 1000000
DEVICENAME                  = "/dev/ttyUSB0".encode('utf-8')        # Check which port is being used on your controller
                                                            # ex) Windows: "COM1"   Linux: "/dev/ttyUSB0"
```

Here we set some variables to let you freely change them and use them to run the example code.

As the document previously said in [previous chapter](/docs/en/software/dynamixel/dynamixel_sdk/device_setup/#dynamixel), customize Dynamixel control table items, such as `DXL_ID` number, communication `BAUDRATE`, and the `DEVICENAME`, on your own terms of needs. In particular, `BAUDRATE` and `DEVICENAME` have systematical dependencies on your controller, so make clear what kind of communication method you will use.

```python
COMM_SUCCESS                = 0                             # Communication Success result value
COMM_TX_FAIL                = -1001                         # Communication Tx Failed
```

Each of the variables above show the meaning of the communication result value.

```python
# Initialize PortHandler Structs
# Set the port path
# Get methods and members of PortHandlerLinux or PortHandlerWindows
port_num = dynamixel.portHandler(DEVICENAME)
```

`portHandler()` function sets port path as `DEVICENAME` and get `port_num`, and prepares an appropriate functions for port control in controller OS automatically. `port_num` would be used in many functions in the body of the code to specify the port for use.

```python
# Initialize PacketHandler Structs
dynamixel.packetHandler()
```

`packetHandler()` function initializes parameters used for packet construction and packet storing.

```python
dxl_comm_result = COMM_TX_FAIL                              # Communication result
```

`dxl_comm_result` indicates which error has been occurred during packet communication.

```python
# Open port
if dynamixel.openPort(port_num):
    print("Succeeded to open the port!")
else:
    print("Failed to open the port!")
    print("Press any key to terminate...")
    getch()
    quit()
```

First, controller opens #`port_num` port to do serial communication with the Dynamixel. If it fails to open the port, the example will be terminated.

```python
# Set port baudrate
if dynamixel.setBaudRate(port_num, BAUDRATE):
    print("Succeeded to change the baudrate!")
else:
    print("Failed to change the baudrate!")
    print("Press any key to terminate...")
    getch()
    quit()
```

Secondly, the controller sets the communication `BAUDRATE` at #`port_num` port opened previously.

```python
# Try to ping the Dynamixel
# Get Dynamixel model number
dxl_model_number = dynamixel.pingGetModelNum(port_num, PROTOCOL_VERSION, DXL_ID)
if dynamixel.getLastTxRxResult(port_num, PROTOCOL_VERSION) != COMM_SUCCESS:
    dynamixel.printTxRxResult(PROTOCOL_VERSION, dynamixel.getLastTxRxResult(port_num, PROTOCOL_VERSION))
elif dynamixel.getLastRxPacketError(port_num, PROTOCOL_VERSION) != 0:
    dynamixel.printRxPacketError(PROTOCOL_VERSION, dynamixel.getLastRxPacketError(port_num, PROTOCOL_VERSION))
```

`pingGetModelNum()` function sends an instruction to the #`DXL_ID` Dynamixel through #`port_num` port. Then, it receives the `dxl_model_number`. The function checks Tx/Rx result and receives Hardware error.
`getLastTxRxResult()` function and `getLastRxPacketError()` function get either, and then `printTxRxResult()` function and `printRxPacketError()` function show results on the console window if any communication error or Hardware error has been occurred.

```python
# Close port
dynamixel.closePort(port_num)
```

Finally, port becomes disposed.


text:
RSpec.describe 'MPN::VERSION' do
  it 'should be set' do
    expect(MPN::VERSION).to_not be_nil
  end
end


text:
// Copyright (c) Solal Pirelli
// This code is licensed under the MIT License (see Licence.txt for details)

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ThriftSharp.Models;

namespace ThriftSharp.Internals
{
    /// <summary>
    /// Thrift type, either a primitive, a collection or a struct.
    /// </summary>
    internal sealed class ThriftType
    {
        private static readonly Dictionary<Type, ThriftTypeId> PrimitiveIds = new Dictionary<Type, ThriftTypeId>
        {
            { typeof( bool ), ThriftTypeId.Boolean },
            { typeof( sbyte ), ThriftTypeId.SByte },
            { typeof( double ), ThriftTypeId.Double },
            { typeof( short ), ThriftTypeId.Int16 },
            { typeof( int ), ThriftTypeId.Int32 },
            { typeof( long ), ThriftTypeId.Int64 },
            { typeof( string ), ThriftTypeId.Binary },
            { typeof( sbyte[] ), ThriftTypeId.Binary }
        };

        private static readonly ConcurrentDictionary<Type, ThriftType> _knownTypes = new ConcurrentDictionary<Type, ThriftType>();

        // Generic arguments if the type is a list, set or map
        private readonly Type[] _collectionGenericArgs;

        /// <summary>
        /// Gets the type's ID.
        /// </summary>
        public ThriftTypeId Id { get; private set; }

        /// <summary>
        /// Gets the TypeInfo of the underlying type.
        /// </summary>
        public TypeInfo TypeInfo { get; private set; }

        /// <summary>
        /// Gets a value indicating whether the type is an enum.
        /// </summary>
        public bool IsEnum { get; private set; }

        /// <summary>
        /// Gets the underlying type, if the type is a nullable type.
        /// </summary>
        public ThriftType NullableType { get; private set; }

        /// <summary>
        /// Gets the type of the collection elements, if the type is a list or set.
        /// </summary>
        public ThriftType ElementType { get; private set; }

        /// <summary>
        /// Gets the type of the map keys, if the type is a map.
        /// </summary>
        public ThriftType KeyType { get; private set; }

        /// <summary>
        /// Gets the type of the map values, if the type is a map.
        /// </summary>
        public ThriftType ValueType { get; private set; }

        /// <summary>
        /// Initializes a new instance of the ThriftType class from the specified .NET type.
        /// </summary>
        private ThriftType( Type type )
        {
            Id = ThriftTypeId.Empty;
            TypeInfo = type.GetTypeInfo();

            if( type == typeof( void ) )
            {
                return;
            }

            var underlyingNullableType = Nullable.GetUnderlyingType( type );
            if( underlyingNullableType != null )
            {
                NullableType = ThriftType.Get( underlyingNullableType );
                Id = NullableType.Id;
                IsEnum = NullableType.IsEnum;
                return;
            }

            if( PrimitiveIds.ContainsKey( type ) )
            {
                Id = PrimitiveIds[type];
                return;
            }

            if( TypeInfo.IsEnum )
            {
                if( TypeInfo.GetCustomAttribute<ThriftEnumAttribute>() == null )
                {
                    throw ThriftParsingException.EnumWithoutAttribute( TypeInfo );
                }
                if( Enum.GetUnderlyingType( type ) != typeof( int ) )
                {
                    throw ThriftParsingException.NonInt32Enum( TypeInfo );
                }

                Id = ThriftTypeId.Int32;
                IsEnum = true;
                return;
            }

            if( TypeInfo.IsValueType )
            {
                throw ThriftParsingException.UnknownValueType( TypeInfo );
            }

            if( TypeInfo.IsArray )
            {
                Id = ThriftTypeId.List;
                return;
            }

            var mapInterfaceAndArgs = GetInstantiableVersion( TypeInfo, typeof( IDictionary<,> ), typeof( Dictionary<,> ), p => ThriftParsingException.UnsupportedMap( p ) );
            if( mapInterfaceAndArgs != null )
            {
                Id = ThriftTypeId.Map;
                TypeInfo = mapInterfaceAndArgs.Item1;
                _collectionGenericArgs = mapInterfaceAndArgs.Item2;
            }

            var setInterfaceAndArgs = GetInstantiableVersion( TypeInfo, typeof( ISet<> ), typeof( HashSet<> ), p => ThriftParsingException.UnsupportedSet( p ) );
            if( setInterfaceAndArgs != null )
            {
                if( mapInterfaceAndArgs != null )
                {
                    throw ThriftParsingException.CollectionWithOrthogonalInterfaces( TypeInfo );
                }

                Id = ThriftTypeId.Set;
                TypeInfo = setInterfaceAndArgs.Item1;
                _collectionGenericArgs = setInterfaceAndArgs.Item2;
            }

            var listInterfaceAndArgs = GetInstantiableVersion( TypeInfo, typeof( IList<> ), typeof( List<> ), p => ThriftParsingException.UnsupportedList( p ) );
            if( listInterfaceAndArgs != null )
            {
                if( mapInterfaceAndArgs != null || setInterfaceAndArgs != null )
                {
                    throw ThriftParsingException.CollectionWithOrthogonalInterfaces( TypeInfo );
                }

                Id = ThriftTypeId.List;
                TypeInfo = listInterfaceAndArgs.Item1;
                _collectionGenericArgs = listInterfaceAndArgs.Item2;
            }

            if( Id == ThriftTypeId.Empty )
            {
                Id = ThriftTypeId.Struct;
            }
        }

        /// <summary>
        /// Gets the Thrift wire type associated with the specified type.
        /// </summary>
        public static ThriftType Get( Type type )
        {
            if( !_knownTypes.ContainsKey( type ) )
            {
                var thriftType = new ThriftType( type );

                _knownTypes.TryAdd( type, thriftType );

                // This has to be done this way because otherwise self-referencing types will loop
                // since they'd call ThriftType.Get before they were themselves added to _knownTypes
                switch( thriftType.Id )
                {
                    case ThriftTypeId.Map:
                        thriftType.KeyType = ThriftType.Get( thriftType._collectionGenericArgs[0] );
                        thriftType.ValueType = ThriftType.Get( thriftType._collectionGenericArgs[1] );
                        break;

                    case ThriftTypeId.List:
                    case ThriftTypeId.Set:
                        if( thriftType.TypeInfo.IsArray )
                        {
                            thriftType.ElementType = ThriftType.Get( thriftType.TypeInfo.GetElementType() );
                        }
                        else
                        {
                            thriftType.ElementType = ThriftType.Get( thriftType._collectionGenericArgs[0] );
                        }
                        break;
                }
            }

            return _knownTypes[type];
        }

        /// <summary>
        /// Gets an instantiable version of the specified type, for the specified interface type,
        /// with the specified concrete type if needed, throwing the specified exception if the type
        /// does implement the interface but cannot be instantiated.
        /// Returns null if the type does not implement the interface.
        /// </summary>
        private static Tuple<TypeInfo, Type[]> GetInstantiableVersion( TypeInfo typeInfo, Type interfaceType, Type concreteType, Func<TypeInfo, Exception> errorProvider )
        {
            if( typeInfo.IsInterface )
            {
                if( typeInfo.GenericTypeArguments.Length > 0 )
                {
                    var unbound = typeInfo.GetGenericTypeDefinition();
                    if( unbound == interfaceType )
                    {
                        return Tuple.Create(
                            concreteType.MakeGenericType( typeInfo.GenericTypeArguments ).GetTypeInfo(),
                            typeInfo.GenericTypeArguments
                        );
                    }
                }
            }

            Tuple<TypeInfo, Type[]> instantiableVersion = null;
            foreach( var iface in typeInfo.ImplementedInterfaces.Where( i => i.GenericTypeArguments.Length > 0 ) )
            {
                var unboundIface = iface.GetGenericTypeDefinition();
                if( unboundIface == interfaceType )
                {
                    if( typeInfo.IsAbstract || !typeInfo.DeclaredConstructors.Any( c => c.GetParameters().Length == 0 ) )
                    {
                        throw errorProvider( typeInfo );
                    }

                    if( instantiableVersion != null )
                    {
                        throw ThriftParsingException.CollectionWithMultipleGenericImplementations( typeInfo );
                    }

                    instantiableVersion = Tuple.Create( typeInfo, iface.GenericTypeArguments );
                }
            }

            return instantiableVersion;
        }
    }
}


text:
using UnityEngine;
using System.Collections;

public class Manager : MonoBehaviour {

	void Start() {
	}

}


text:
import React, { Component } from 'react'
import PublicNavbar from '../components/PublicNavbar'
import LoginForm from '../components/auth/LoginForm'
import { Segment, Grid } from 'semantic-ui-react'
import { Link } from 'react-router-dom'

class LoginPage extends Component {
  render () {
    return (
      <div>
        <PublicNavbar />
        <Grid centered verticalAlign='middle' columns={1}>
          <Grid.Column style={{'maxWidth': 450}}>
            <Segment textAlign='left' stacked secondary>
              <LoginForm />
            </Segment>
            <Segment stacked secondary>
              Don't have an account? Register one <Link to='/register'>here</Link>.
            </Segment>
          </Grid.Column>
        </Grid>
      </div>
    )
  }
}

export default LoginPage