<commit_before>
var /*const*/ READYSTATE_UNSENT = 0;
var /*const*/ READYSTATE_OPENED = 1;
var /*const*/ READYSTATE_HEADERSRECEIVED = 2;
var /*const*/ READYSTATE_LOADING = 3;
var /*const*/ READYSTATE_DONE = 4;
readyStates = {};
readyStates[READYSTATE_UNSENT] = "UNSENT";
readyStates[READYSTATE_OPENED] = "OPENED";
readyStates[READYSTATE_HEADERSRECEIVED] = "HEADERS_RECEIVED";
readyStates[READYSTATE_LOADING] = "LOADING";
readyStates[READYSTATE_DONE] = "DONE";

String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

/// Top-level user-facing abstraction of all Kanaloa client functionality.
/// Parameters:
/// server -- The url of the Kanaloa service to connect to.
/// Properties:
/// OnReceive -- Invoked when a message is received from the server. function(data)
/// OnConnectionLost -- Invoked when an application-level timeout occurs. The server process that is handling this client has died. function()
function KanaloaConnection(server) {
    this.Settings = new KanaloaHttpSettings();
    this.Server = server;
    this.ConnectionId = null;

    this._receiver = null;
    this._sendBatcher = null;

    this.OnReceive = function(data) { };
    this.OnConnectionLost = function() { };
    this.OnDebugEvent = function(message) { };

    this.Connect();
}

KanaloaConnection.prototype._ReportReceive = function(data) {
    if (this.OnReceive) {
	this.OnReceive(data);
    }
}

KanaloaConnection.prototype._ReportConnectionLost = function() {
    if (this.OnConnectionLost) {
	this.OnConnectionLost();
    }
}

KanaloaConnection.prototype._LogDebug = function(message) {
    if (this.OnDebugEvent) {
	this.OnDebugEvent("Connection: " + message);
    }
}

KanaloaConnection.prototype._BumpIncoming = function(statusCode) {
    if (statusCode == 410) {
	// GONE
	this.ConnectionId = null;
	this._ReportConnectionLost();
    }
}

KanaloaConnection.prototype._BumpOutgoing = function(statusCode) {
    // Same thing.
    this._BumpIncoming(statusCode);
}

KanaloaConnection.prototype.Connect = function() {
    var connection = this;
    connection._LogDebug("Using stream mode? " + connection.Settings.IsStreamMode);

    function ConnectionOpened(receiverPost) {
	connection._LogDebug("Opened");

	// Now that we have the ConnectionId, we can begin transmitting outgoing posts.
	connection.ConnectionId = receiverPost.ConnectionId;
	connection.Send();
    }

    function ConnectionClosed(receiverPost, statusCode) {
	connection._LogDebug("Closed with status: " + statusCode);

	connection._BumpIncoming(statusCode);
	connection.Settings.BumpIncoming(statusCode);
	connection._LogDebug("Waiting " + connection.Settings.IncomingWait + " ms before reconnect.");
	setTimeout(function() { connection.Connect(); }, connection.Settings.IncomingWait);
    }

    var receiver = new KanaloaHttpPost(this.Server + "/" + this.Settings.ConnectionSuffix,
				       this.ConnectionId,
				       this.Settings.ContentType,
				       this.Settings.IsStreamMode,
				       function() { ConnectionOpened(this); },
				       function(data) { connection._ReportReceive(data); },
				       function(httpStatusCode) { ConnectionClosed(this, httpStatusCode); },
				       function(message) { connection._LogDebug(message); }
				       );
    this._receiver = receiver;

    receiver.Send("");
}

KanaloaConnection.prototype.Send = function(data) {
    if (this._sendBatcher == null) {
	var connection = this;
	this._sendBatcher = new KanaloaHttpSendBatcher(this,
						       function(message) { connection._LogDebug(message); }
						       );
    }

    this._sendBatcher.Send(data);
}

var /*const*/ KANALOA_WAIT_INCOMING_BASE = 10;
var /*const*/ KANALOA_WAIT_OUTGOING_BASE = 10;

/// Manages timeouts and other settings for the client.
function KanaloaHttpSettings() {
    this.IsStreamMode = this._IsStreamMode();
    this.ContentType = "application/json";

    if (this.IsStreamMode) {
	this.ConnectionSuffix = "?t=stream";
    }
    else {
	this.ConnectionSuffix = "?t=longpoll";
    }

    this.Reset();
}

KanaloaHttpSettings.prototype._IsStreamMode = function() {
    var userAgent = navigator.userAgent;
    return (userAgent.indexOf("MSIE") == -1);
}

KanaloaHttpSettings.prototype.Reset = function() {
    this.IncomingWait = KANALOA_WAIT_INCOMING_BASE;
    this.OutgoingWait = KANALOA_WAIT_OUTGOING_BASE;
}

KanaloaHttpSettings.prototype.BumpIncoming = function(statusCode) {
    if (statusCode != 200) {
	if (this.IncomingWait == KANALOA_WAIT_INCOMING_BASE) {
	    this.IncomingWait = 1000;
	}
	else if (this.IncomingWait < 100000) {
	    this.IncomingWait *= 2;
	}
    }
}

KanaloaHttpSettings.prototype.BumpOutgoing = function(statusCode) {
    if (statusCode != 200) {
	if (this.OutgoingWait == KANALOA_WAIT_OUTGOING_BASE) {
	    this.OutgoingWait = 1000;
	}
	else if (this.OutgoingWait < 100000) {
	    this.OutgoingWait *= 2;
	}
    }
}

/// Once a ConnectionId is established by the initial request, this class batches outgoing data.
function KanaloaHttpSendBatcher(connection, onDebugEvent) {
    this._connection = connection;
    this._outgoing = [];
    this._post = null;

    this._onDebugEvent = onDebugEvent;
}

KanaloaHttpSendBatcher.prototype._LogDebug = function(message) {
    if (this._onDebugEvent) {
	this._onDebugEvent("HttpSendBatcher: " + message);
    }
}

KanaloaHttpSendBatcher.prototype.Send = function(data) {
    if (data) {
	this._LogDebug("Adding data \"" + data + "\" to outbox.");
	this._outgoing.push(data);
    }

    this._SendPost();
}

KanaloaHttpSendBatcher.prototype._SendPost = function() {
    if (this._outgoing.length == 0) {
	this._LogDebug("No messages to send.");
	return;
    }

    if (this._connection.ConnectionId == null) {
	this._LogDebug("ConnectionId not set yet.");
	return;
    }

    if (this._post && this._post.IsActive()) {
	// If the post is still working, wait for it to complete.
	this._LogDebug("A post is still active; waiting for it to complete.");
	return;
    }

    var batcher = this;
    var connection = batcher._connection;

    function PostCompleted(post, statusCode) {
	// If successful, remove sent messages from outbox.
	if (statusCode == 200) {
	    for (var i = 0; i < post.sentCount; i++) {
		batcher._outgoing.shift();
	    }
	}

	// Loop to pick up accumulated messages.
	connection._BumpOutgoing(statusCode);
	connection.Settings.BumpOutgoing(statusCode);
	connection._LogDebug("Waiting " + connection.Settings.OutgoingWait + " ms before reconnect.");
	setTimeout(function() { batcher._SendPost(); }, connection.Settings.OutgoingWait);
    }

    this._LogDebug("There is no active post; creating a new one.");
    // TODO: Reuse existing post or remove post reconnect logic.
    var post = new KanaloaHttpPost(connection.Server,
				   connection.ConnectionId,
				   connection.Settings.ContentType,
				   connection.Settings.IsStreamMode,
				   null,
				   null,
				   function(httpStatusCode) { PostCompleted(this, httpStatusCode); },
				   function(message) { batcher._LogDebug(message); }
				   );
    batcher._post = post;

    // TODO: Limit size of sent string to 1 kB
    var textOutgoing = JSON.stringify(this._outgoing);
    this._LogDebug("Sending batch \"" + textOutgoing + "\"");
    this._post.Send(textOutgoing);
    this._post.sentCount = this._outgoing.length;
}

/// Wraps XmlHttpRequest to provide lowest-level send and receive functionality.
/// server -- The full URL to post to.
/// connectionId -- The value to set for the ConnectionId header.
/// httpContentType -- The value to set for the Content-Type header.
/// isStreamMode -- If false, will not try to read headers or responseText before request complete (IE compat == false).
/// onReceiveChunk -- On stream-capable browsers, this is fired once per chunk. Otherwise, once per request.
/// onClose -- Fired when the underlying request dies.
/// onDebugEvent -- Reports interesting diagnostic information.
function KanaloaHttpPost(server, connectionId, httpContentType, isStreamMode, onOpen, onReceiveChunk, onClose, onDebugEvent) {
    this._server = server;
    this.ConnectionId = connectionId;
    this._contentType = httpContentType;
    this._isStreamMode = isStreamMode;
    this._request = null;

    this._onOpen = onOpen;
    this._onReceiveChunk = onReceiveChunk;
    this._onClose = onClose;
    this._onDebugEvent = onDebugEvent;
}

KanaloaHttpPost.prototype._ReportOpen = function() {
    if (this._onOpen) {
	this._onOpen();
    }
}

KanaloaHttpPost.prototype._ReportChunk = function(data) {
    if (this._onReceiveChunk) {
	this._onReceiveChunk(data);
    }
}

KanaloaHttpPost.prototype._ReportClose = function(httpStatusCode) {
    if (this._onClose) {
	this._onClose(httpStatusCode);
    }
}

KanaloaHttpPost.prototype._LogDebug = function(message) {
    if (this._onDebugEvent) {
	this._onDebugEvent("HttpPost: " + message);
    }
}

KanaloaHttpPost.prototype.IsActive = function() {
    if (this._request && (this._request.readyState != READYSTATE_UNSENT || this._request.readyState != READYSTATE_DONE)) {
	return false;
    }

    return true;
}

KanaloaHttpPost.prototype.Connect = function() {
    if (this._request) {
	if (this._request.readyState == READYSTATE_UNSENT) {
	    this._LogDebug("Connect: Using existing request.");
	    return false;
	}

	this._LogDebug("Connect: Aborting existing request.");
	this._request.abort();
	this._request = null;
    }

    this._LogDebug("Connect: Creating new request.");

    var connection = this;

    var request = new XMLHttpRequest();
    this._request = request;
    request.lenReceived = 0;
    request.open("POST", this._server);

    request.onreadystatechange = function() {
	var readyState = request.readyState;
	connection._LogDebug("State changed to " + readyStates[request.readyState]);

	//connection._LogDebug("responseText is \"" + request.responseText + "\"");

	if ((connection._isStreamMode && readyState == READYSTATE_HEADERSRECEIVED) ||
	    (!connection._isStreamMode && readyState == READYSTATE_DONE)) {
	    var headers = request.getAllResponseHeaders();
	    connection._LogDebug("AllResponseHeaders is \"" + headers + "\"");

	    var newConnectionId = request.getResponseHeader("ConnectionId");
	    if (newConnectionId) {
		connection._LogDebug("Set new ConnectionId \"" + newConnectionId + "\"");
		connection.ConnectionId = newConnectionId;
	    }

	    connection._LogDebug("status is \"" + request.status + "\"");

	    connection._ReportOpen();
	}

	if ((connection._isStreamMode && readyState == READYSTATE_LOADING) ||
	    readyState == READYSTATE_DONE) {
	    var allData = request.responseText;
	    var data = allData.substring(request.lenReceived);
	    data = data.trim();
	    request.lenReceived = allData.length;
	    if (data.length > 0) {
		connection._LogDebug("Received additional responseText \"" + data + "\"");

		var responses = [];
		try {
		    // The response should always be a JSON array.
		    responses = JSON.parse(data);
		}
		catch (ex) {
		    connection._LogDebug("Error parsing responseText \"" + data + "\"");
		}

		for (var i = 0; i < responses.length; i++) {
		    var response = responses[i];
		    connection._ReportChunk(response);
		}
	    }
	}

	if (readyState == READYSTATE_DONE) {
	    connection._ReportClose(request.status);
	}
    }

    if (this.ConnectionId) {
	connection._LogDebug("Setting ConnectionId header to \"" + this.ConnectionId + "\"");
	request.setRequestHeader("ConnectionId", this.ConnectionId);
    }
    if (this._contentType) {
	connection._LogDebug("Setting Content-Type header to \"" + this._contentType + "\"");
	request.setRequestHeader("Content-Type", this._contentType);
    }

    return true;
}

KanaloaHttpPost.prototype.Send = function(data) {
    this.Connect();
    this._request.send(data);
}
<commit_msg>Changes client js library so that the names of internal classes begin with an underscore.<commit_after>
var /*const*/ READYSTATE_UNSENT = 0;
var /*const*/ READYSTATE_OPENED = 1;
var /*const*/ READYSTATE_HEADERSRECEIVED = 2;
var /*const*/ READYSTATE_LOADING = 3;
var /*const*/ READYSTATE_DONE = 4;
readyStates = {};
readyStates[READYSTATE_UNSENT] = "UNSENT";
readyStates[READYSTATE_OPENED] = "OPENED";
readyStates[READYSTATE_HEADERSRECEIVED] = "HEADERS_RECEIVED";
readyStates[READYSTATE_LOADING] = "LOADING";
readyStates[READYSTATE_DONE] = "DONE";

String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

/// Top-level user-facing abstraction of all Kanaloa client functionality.
/// Parameters:
/// server -- The url of the Kanaloa service to connect to.
/// Properties:
/// OnReceive -- Invoked when a message is received from the server. function(data)
/// OnConnectionLost -- Invoked when an application-level timeout occurs. The server process that is handling this client has died. function()
function KanaloaConnection(server) {
    this.Settings = new _KanaloaHttpSettings();
    this.Server = server;
    this.ConnectionId = null;

    this._receiver = null;
    this._sendBatcher = null;

    this.OnReceive = function(data) { };
    this.OnConnectionLost = function() { };
    this.OnDebugEvent = function(message) { };

    this.Connect();
}

KanaloaConnection.prototype._ReportReceive = function(data) {
    if (this.OnReceive) {
	this.OnReceive(data);
    }
}

KanaloaConnection.prototype._ReportConnectionLost = function() {
    if (this.OnConnectionLost) {
	this.OnConnectionLost();
    }
}

KanaloaConnection.prototype._LogDebug = function(message) {
    if (this.OnDebugEvent) {
	this.OnDebugEvent("Connection: " + message);
    }
}

KanaloaConnection.prototype._BumpIncoming = function(statusCode) {
    if (statusCode == 410) {
	// GONE
	this.ConnectionId = null;
	this._ReportConnectionLost();
    }
}

KanaloaConnection.prototype._BumpOutgoing = function(statusCode) {
    // Same thing.
    this._BumpIncoming(statusCode);
}

KanaloaConnection.prototype.Connect = function() {
    var connection = this;
    connection._LogDebug("Using stream mode? " + connection.Settings.IsStreamMode);

    function ConnectionOpened(receiverPost) {
	connection._LogDebug("Opened");

	// Now that we have the ConnectionId, we can begin transmitting outgoing posts.
	connection.ConnectionId = receiverPost.ConnectionId;
	connection.Send();
    }

    function ConnectionClosed(receiverPost, statusCode) {
	connection._LogDebug("Closed with status: " + statusCode);

	connection._BumpIncoming(statusCode);
	connection.Settings.BumpIncoming(statusCode);
	connection._LogDebug("Waiting " + connection.Settings.IncomingWait + " ms before reconnect.");
	setTimeout(function() { connection.Connect(); }, connection.Settings.IncomingWait);
    }

    var receiver = new _KanaloaHttpPost(this.Server + "/" + this.Settings.ConnectionSuffix,
				       this.ConnectionId,
				       this.Settings.ContentType,
				       this.Settings.IsStreamMode,
				       function() { ConnectionOpened(this); },
				       function(data) { connection._ReportReceive(data); },
				       function(httpStatusCode) { ConnectionClosed(this, httpStatusCode); },
				       function(message) { connection._LogDebug(message); }
				       );
    this._receiver = receiver;

    receiver.Send("");
}

KanaloaConnection.prototype.Send = function(data) {
    if (this._sendBatcher == null) {
	var connection = this;
	this._sendBatcher = new _KanaloaHttpSendBatcher(this,
						       function(message) { connection._LogDebug(message); }
						       );
    }

    this._sendBatcher.Send(data);
}

var /*const*/ KANALOA_WAIT_INCOMING_BASE = 10;
var /*const*/ KANALOA_WAIT_OUTGOING_BASE = 10;

/// Manages timeouts and other settings for the client.
function _KanaloaHttpSettings() {
    this.IsStreamMode = this._IsStreamMode();
    this.ContentType = "application/json";

    if (this.IsStreamMode) {
	this.ConnectionSuffix = "?t=stream";
    }
    else {
	this.ConnectionSuffix = "?t=longpoll";
    }

    this.Reset();
}

_KanaloaHttpSettings.prototype._IsStreamMode = function() {
    var userAgent = navigator.userAgent;
    return (userAgent.indexOf("MSIE") == -1);
}

_KanaloaHttpSettings.prototype.Reset = function() {
    this.IncomingWait = KANALOA_WAIT_INCOMING_BASE;
    this.OutgoingWait = KANALOA_WAIT_OUTGOING_BASE;
}

_KanaloaHttpSettings.prototype.BumpIncoming = function(statusCode) {
    if (statusCode != 200) {
	if (this.IncomingWait == KANALOA_WAIT_INCOMING_BASE) {
	    this.IncomingWait = 1000;
	}
	else if (this.IncomingWait < 100000) {
	    this.IncomingWait *= 2;
	}
    }
}

_KanaloaHttpSettings.prototype.BumpOutgoing = function(statusCode) {
    if (statusCode != 200) {
	if (this.OutgoingWait == KANALOA_WAIT_OUTGOING_BASE) {
	    this.OutgoingWait = 1000;
	}
	else if (this.OutgoingWait < 100000) {
	    this.OutgoingWait *= 2;
	}
    }
}

/// Once a ConnectionId is established by the initial request, this class batches outgoing data.
function _KanaloaHttpSendBatcher(connection, onDebugEvent) {
    this._connection = connection;
    this._outgoing = [];
    this._post = null;

    this._onDebugEvent = onDebugEvent;
}

_KanaloaHttpSendBatcher.prototype._LogDebug = function(message) {
    if (this._onDebugEvent) {
	this._onDebugEvent("HttpSendBatcher: " + message);
    }
}

_KanaloaHttpSendBatcher.prototype.Send = function(data) {
    if (data) {
	this._LogDebug("Adding data \"" + data + "\" to outbox.");
	this._outgoing.push(data);
    }

    this._SendPost();
}

_KanaloaHttpSendBatcher.prototype._SendPost = function() {
    if (this._outgoing.length == 0) {
	this._LogDebug("No messages to send.");
	return;
    }

    if (this._connection.ConnectionId == null) {
	this._LogDebug("ConnectionId not set yet.");
	return;
    }

    if (this._post && this._post.IsActive()) {
	// If the post is still working, wait for it to complete.
	this._LogDebug("A post is still active; waiting for it to complete.");
	return;
    }

    var batcher = this;
    var connection = batcher._connection;

    function PostCompleted(post, statusCode) {
	// If successful, remove sent messages from outbox.
	if (statusCode == 200) {
	    for (var i = 0; i < post.sentCount; i++) {
		batcher._outgoing.shift();
	    }
	}

	// Loop to pick up accumulated messages.
	connection._BumpOutgoing(statusCode);
	connection.Settings.BumpOutgoing(statusCode);
	connection._LogDebug("Waiting " + connection.Settings.OutgoingWait + " ms before reconnect.");
	setTimeout(function() { batcher._SendPost(); }, connection.Settings.OutgoingWait);
    }

    this._LogDebug("There is no active post; creating a new one.");
    // TODO: Reuse existing post or remove post reconnect logic.
    var post = new _KanaloaHttpPost(connection.Server,
				   connection.ConnectionId,
				   connection.Settings.ContentType,
				   connection.Settings.IsStreamMode,
				   null,
				   null,
				   function(httpStatusCode) { PostCompleted(this, httpStatusCode); },
				   function(message) { batcher._LogDebug(message); }
				   );
    batcher._post = post;

    // TODO: Limit size of sent string to 1 MB to match server limit.
    var textOutgoing = JSON.stringify(this._outgoing);
    this._LogDebug("Sending batch \"" + textOutgoing + "\"");
    this._post.Send(textOutgoing);
    this._post.sentCount = this._outgoing.length;
}

/// Wraps XmlHttpRequest to provide lowest-level send and receive functionality.
/// server -- The full URL to post to.
/// connectionId -- The value to set for the ConnectionId header.
/// httpContentType -- The value to set for the Content-Type header.
/// isStreamMode -- If false, will not try to read headers or responseText before request complete (IE compat == false).
/// onReceiveChunk -- On stream-capable browsers, this is fired once per chunk. Otherwise, once per request.
/// onClose -- Fired when the underlying request dies.
/// onDebugEvent -- Reports interesting diagnostic information.
function _KanaloaHttpPost(server, connectionId, httpContentType, isStreamMode, onOpen, onReceiveChunk, onClose, onDebugEvent) {
    this._server = server;
    this.ConnectionId = connectionId;
    this._contentType = httpContentType;
    this._isStreamMode = isStreamMode;
    this._request = null;

    this._onOpen = onOpen;
    this._onReceiveChunk = onReceiveChunk;
    this._onClose = onClose;
    this._onDebugEvent = onDebugEvent;
}

_KanaloaHttpPost.prototype._ReportOpen = function() {
    if (this._onOpen) {
	this._onOpen();
    }
}

_KanaloaHttpPost.prototype._ReportChunk = function(data) {
    if (this._onReceiveChunk) {
	this._onReceiveChunk(data);
    }
}

_KanaloaHttpPost.prototype._ReportClose = function(httpStatusCode) {
    if (this._onClose) {
	this._onClose(httpStatusCode);
    }
}

_KanaloaHttpPost.prototype._LogDebug = function(message) {
    if (this._onDebugEvent) {
	this._onDebugEvent("HttpPost: " + message);
    }
}

_KanaloaHttpPost.prototype.IsActive = function() {
    if (this._request && (this._request.readyState != READYSTATE_UNSENT || this._request.readyState != READYSTATE_DONE)) {
	return false;
    }

    return true;
}

_KanaloaHttpPost.prototype.Connect = function() {
    if (this._request) {
	if (this._request.readyState == READYSTATE_UNSENT) {
	    this._LogDebug("Connect: Using existing request.");
	    return false;
	}

	this._LogDebug("Connect: Aborting existing request.");
	this._request.abort();
	this._request = null;
    }

    this._LogDebug("Connect: Creating new request.");

    var connection = this;

    var request = new XMLHttpRequest();
    this._request = request;
    request.lenReceived = 0;
    request.open("POST", this._server);

    request.onreadystatechange = function() {
	var readyState = request.readyState;
	connection._LogDebug("State changed to " + readyStates[request.readyState]);

	//connection._LogDebug("responseText is \"" + request.responseText + "\"");

	if ((connection._isStreamMode && readyState == READYSTATE_HEADERSRECEIVED) ||
	    (!connection._isStreamMode && readyState == READYSTATE_DONE)) {
	    var headers = request.getAllResponseHeaders();
	    connection._LogDebug("AllResponseHeaders is \"" + headers + "\"");

	    var newConnectionId = request.getResponseHeader("ConnectionId");
	    if (newConnectionId) {
		connection._LogDebug("Set new ConnectionId \"" + newConnectionId + "\"");
		connection.ConnectionId = newConnectionId;
	    }

	    connection._LogDebug("status is \"" + request.status + "\"");

	    connection._ReportOpen();
	}

	if ((connection._isStreamMode && readyState == READYSTATE_LOADING) ||
	    readyState == READYSTATE_DONE) {
	    var allData = request.responseText;
	    var data = allData.substring(request.lenReceived);
	    data = data.trim();
	    request.lenReceived = allData.length;
	    if (data.length > 0) {
		connection._LogDebug("Received additional responseText \"" + data + "\"");

		var responses = [];
		try {
		    // The response should always be a JSON array.
		    responses = JSON.parse(data);
		}
		catch (ex) {
		    connection._LogDebug("Error parsing responseText \"" + data + "\"");
		}

		for (var i = 0; i < responses.length; i++) {
		    var response = responses[i];
		    connection._ReportChunk(response);
		}
	    }
	}

	if (readyState == READYSTATE_DONE) {
	    connection._ReportClose(request.status);
	}
    }

    if (this.ConnectionId) {
	connection._LogDebug("Setting ConnectionId header to \"" + this.ConnectionId + "\"");
	request.setRequestHeader("ConnectionId", this.ConnectionId);
    }
    if (this._contentType) {
	connection._LogDebug("Setting Content-Type header to \"" + this._contentType + "\"");
	request.setRequestHeader("Content-Type", this._contentType);
    }

    return true;
}

_KanaloaHttpPost.prototype.Send = function(data) {
    this.Connect();
    this._request.send(data);
}
<|endoftext|>


<commit_before>const path = require('path');
const cleanWebPackPlugin = require('clean-webpack-plugin');

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/',
  },
  plugins: [
    new cleanWebPackPlugin(['dist']),
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
        },
        exclude: /node_modules/,
      },
      {
        test: /\.scss$/,
        use: [
          { loader: "style-loader" },
          { loader: "css-loader" },
          { loader: "sass-loader" },
        ]
      },
      {
        test: /\.(png|svg|gif|jpg)$/,
        use: {
          loader: 'file-loader',
        },
      },
    ],
  },
};
<commit_msg>Set up hot module replacement for react components<commit_after>const path = require('path');
const cleanWebPackPlugin = require('clean-webpack-plugin');

module.exports = {
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/',
  },
  plugins: [
    new cleanWebPackPlugin(['dist']),
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        options: {
          cacheDirectory: true,
          plugins: ['react-hot-loader/babel'],
        },
        exclude: /node_modules/,
      },
      {
        test: /\.scss$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          { loader: 'sass-loader' },
        ]
      },
      {
        test: /\.(png|svg|gif|jpg)$/,
        use: {
          loader: 'file-loader',
        },
      },
    ],
  },
};
<|endoftext|>


<commit_before>let windows = {app: 0, devtools: 0};

const MENU_APP = 'MENU_APP';

function addToMenu(id, title, contexts, onClick) {
  chrome.contextMenus.create({
    id: id,
    title: title,
    contexts: contexts,
    onclick: onClick
  });
}

function closeIfExist(type) {
  if (windows[type] > 0) {
    chrome.windows.remove(windows[type]);
    windows[type] = chrome.windows.WINDOW_ID_NONE;
  }
}

function popWindow(action, url, type, customOptions) {
  closeIfExist(type);
  let options = {
    type: 'popup',
    left: 100, top: 100,
    width: 800, height: 700,
    ...customOptions
  };
  if (action === 'open') {
    options.url = chrome.extension.getURL(url);
    chrome.windows.create(options, (win) => {
      windows[type] = win.id;
    });
  }
}

function createMenu() {
  addToMenu(MENU_APP, 'Redux Counter App', ['all'], () => popWindow('open', 'window.html', 'app', {left: 0, width: 1080}));
}

export default createMenu;
<commit_msg>Remove unnecessary properties from contextMenus<commit_after>let windows = {};

const MENU_APP = 'MENU_APP';

function addToMenu(id, title, contexts, onClick) {
  chrome.contextMenus.create({
    id: id,
    title: title,
    contexts: contexts,
    onclick: onClick
  });
}

function closeIfExist(type) {
  if (windows[type] > 0) {
    chrome.windows.remove(windows[type]);
    windows[type] = chrome.windows.WINDOW_ID_NONE;
  }
}

function popWindow(action, url, type, customOptions) {
  closeIfExist(type);
  let options = {
    type: 'popup',
    left: 100, top: 100,
    width: 800, height: 700,
    ...customOptions
  };
  if (action === 'open') {
    options.url = chrome.extension.getURL(url);
    chrome.windows.create(options, (win) => {
      windows[type] = win.id;
    });
  }
}

function createMenu() {
  addToMenu(MENU_APP, 'Redux Counter App', ['all'], () => popWindow('open', 'window.html', MENU_APP, {left: 0, width: 1080}));
}

export default createMenu;
<|endoftext|>


<commit_before>/*
 * Copyrights phwang
 * Written by Paul Hwang
 * File name: AjxObject.js
 */

function AjxObject(root_object_val) {
    "use strict";
    this.theRootObject = root_object_val;

    this.rootObject = function () {
        return this.theRootObject;
    };

    this.utilObject = function () {
        return this.rootObject().utilObject();
    };

    this.ajxRoute = function () {
        return "/go_msg";
    };

    this.jsonContext = function () {
        return "application/json; charset=utf-8";
    }
    this.plainTextContext = function () {
        return "text/plain; charset=utf-8";
    }

    this.formJsonString = function (msg_val, session_val) {
        var s = JSON.stringify({
            his_name: session_val.hisName(),
            my_name: session_val.myName(),
            data: msg_val,
            xmt_seq: session_val.xmtSeq(),
            link_id: this.rootObject().linkId(),
            session_id: session_val.sessionId(),
        });
        session_val.incrementXmtSeq();
        return s;
    };

    this.setupLink = function (request_val, session_val) {
        var this0 = this;
        var request0 = request_val;

        this.logit("setupLinkf", session_val.myName());
        request_val.open("GET", this.ajxRoute(), false);
        request_val.setRequestHeader("Content-Type", this.jsonContext());
        request_val.setRequestHeader("setup_link", "yes");
        request_val.setRequestHeader("my_name", session_val.myName());
        request_val.setRequestHeader("his_name", session_val.hisName());

        request_val.onreadystatechange = function() {
            if ((request0.readyState === 4) && (request0.status === 200)) {
                var context_type = request0.getResponseHeader("Content-Type");
                var link_id = request0.responseText;
                this0.logit("getMessage", "link_id= " + request0.responseText);
                session_val.setLinkId(Number(link_id));
                //this0.logit("getMessage", "link_id= " + session_val.linkId());
            }
            else {
                //this0.logit("getMessage", "error=" + request0.readyState + ", " + request0.status);
            }
        };
        request_val.send(null);
    };

    this.setupSession = function (request_val, session_val) {
        var this0 = this;
        var request0 = request_val;

        this.logit("setupLinkf", session_val.myName());
        request_val.open("GET", this.ajxRoute(), false);
        request_val.setRequestHeader("Content-Type", this.jsonContext());
        request_val.setRequestHeader("setup_session", "yes");
        request_val.setRequestHeader("my_name", session_val.myName());
        request_val.setRequestHeader("his_name", session_val.hisName());

        request_val.onreadystatechange = function() {
            if ((request0.readyState === 4) && (request0.status === 200)) {
                var context_type = request0.getResponseHeader("Content-Type");
                var session_id = request0.responseText;
                this0.logit("getMessage", "session_id= " + request0.responseText);
                session_val.setSessionId(Number(session_id));
                //this0.logit("getMessage", "session_id= " + session_val.linkId());
            }
            else {
                //this0.logit("getMessage", "error=" + request0.readyState + ", " + request0.status);
            }
        };
        request_val.send(null);
    };

    this.getMessage = function (request_val, sesson_mgr_val, session_val) {
        var this0 = this;
        var request0 = request_val;

        request_val.open("GET", this.ajxRoute(), true);
        request_val.setRequestHeader("Content-Type", this.jsonContext());
        request_val.setRequestHeader("my_name", session_val.myName());
        request_val.setRequestHeader("his_name", session_val.hisName());
        request_val.setRequestHeader("link_id", this.rootObject().linkId());
        request_val.setRequestHeader("session_id", session_val.sessionId());

        request_val.onreadystatechange = function() {
            if ((request0.readyState === 4) && (request0.status === 200)) {
                var context_type = request0.getResponseHeader("Content-Type");
                this0.logit("getMessage", "data= " + request0.responseText);
                sesson_mgr_val.receiveStringData(request0.responseText);
                //func_val(request0.responseText);
            }
            else {
                //this0.logit("getMessage", "error=" + request0.readyState + ", " + request0.status);
            }
        };
        request_val.send(null);
    };

    this.postMessage = function (request_val, msg_val, session_val) {
        request_val.open("POST", this.ajxRoute(), true);
        request_val.setRequestHeader("Content-Type", this.jsonContext());

        var json_str = this.formJsonString(msg_val, session_val);
        this.logit("postMessage", "json=" + json_str);
        request_val.send(json_str);

/*
        $.ajax({
            data: {data: msg_val},
            url: dir_val,
            type: 'post',
            dataType: 'json',

        });
*/
    };

    this.newHttpRequest = function () {
        var request = new XMLHttpRequest();
        return request;
    };

    this.abend = function (str1_val, str2_val) {
        return this.utilObject().utilAbend("AjxObject." + str1_val, str2_val);
    };

    this.logit = function (str1_val, str2_val) {
        return this.utilObject().utilLogit("AjxObject." + str1_val, str2_val);
    };
}

<commit_msg>session<commit_after>/*
 * Copyrights phwang
 * Written by Paul Hwang
 * File name: AjxObject.js
 */

function AjxObject(root_object_val) {
    "use strict";
    this.theRootObject = root_object_val;

    this.rootObject = function () {
        return this.theRootObject;
    };

    this.utilObject = function () {
        return this.rootObject().utilObject();
    };

    this.ajxRoute = function () {
        return "/go_msg";
    };

    this.jsonContext = function () {
        return "application/json; charset=utf-8";
    }
    this.plainTextContext = function () {
        return "text/plain; charset=utf-8";
    }

    this.httpGetRequest = function () {
        return this.theHttpGetRequest;
    };

    this.httpPostRequest = function () {
        return this.theHttpPostRequest;
    };

    this.formJsonString = function (msg_val, session_val) {
        var s = JSON.stringify({
            his_name: session_val.hisName(),
            my_name: session_val.myName(),
            data: msg_val,
            xmt_seq: session_val.xmtSeq(),
            link_id: this.rootObject().linkId(),
            session_id: session_val.sessionId(),
        });
        session_val.incrementXmtSeq();
        return s;
    };

    this.setupLink = function (request_val, session_val) {
        var this0 = this;
        var request0 = this.httpGetRequest();

        this.logit("setupLinkf", session_val.myName());
        this.httpGetRequest().open("GET", this.ajxRoute(), false);
        this.httpGetRequest().setRequestHeader("Content-Type", this.jsonContext());
        this.httpGetRequest().setRequestHeader("setup_link", "yes");
        this.httpGetRequest().setRequestHeader("my_name", session_val.myName());
        this.httpGetRequest().setRequestHeader("his_name", session_val.hisName());

        this.httpGetRequest().onreadystatechange = function() {
            if ((request0.readyState === 4) && (request0.status === 200)) {
                var context_type = request0.getResponseHeader("Content-Type");
                var link_id = request0.responseText;
                this0.logit("getMessage", "link_id= " + request0.responseText);
                session_val.setLinkId(Number(link_id));
                //this0.logit("getMessage", "link_id= " + session_val.linkId());
            }
            else {
                //this0.logit("getMessage", "error=" + request0.readyState + ", " + request0.status);
            }
        };
        this.httpGetRequest().send(null);
    };

    this.setupSession = function (request_val, session_val) {
        var this0 = this;
        var request0 = this.httpGetRequest();

        this.logit("setupLinkf", session_val.myName());
        this.httpGetRequest().open("GET", this.ajxRoute(), false);
        this.httpGetRequest().setRequestHeader("Content-Type", this.jsonContext());
        this.httpGetRequest().setRequestHeader("setup_session", "yes");
        this.httpGetRequest().setRequestHeader("my_name", session_val.myName());
        this.httpGetRequest().setRequestHeader("his_name", session_val.hisName());

        this.httpGetRequest().onreadystatechange = function() {
            if ((request0.readyState === 4) && (request0.status === 200)) {
                var context_type = request0.getResponseHeader("Content-Type");
                var session_id = request0.responseText;
                this0.logit("getMessage", "session_id= " + request0.responseText);
                session_val.setSessionId(Number(session_id));
                //this0.logit("getMessage", "session_id= " + session_val.linkId());
            }
            else {
                //this0.logit("getMessage", "error=" + request0.readyState + ", " + request0.status);
            }
        };
        this.httpGetRequest().send(null);
    };

    this.getMessage = function (request_val, sesson_mgr_val, session_val) {
        var this0 = this;
        var request0 = this.httpGetRequest();

        this.httpGetRequest().open("GET", this.ajxRoute(), true);
        this.httpGetRequest().setRequestHeader("Content-Type", this.jsonContext());
        this.httpGetRequest().setRequestHeader("my_name", session_val.myName());
        this.httpGetRequest().setRequestHeader("his_name", session_val.hisName());
        this.httpGetRequest().setRequestHeader("link_id", this.rootObject().linkId());
        this.httpGetRequest().setRequestHeader("session_id", session_val.sessionId());

        this.httpGetRequest().onreadystatechange = function() {
            if ((request0.readyState === 4) && (request0.status === 200)) {
                var context_type = request0.getResponseHeader("Content-Type");
                this0.logit("getMessage", "data= " + request0.responseText);
                sesson_mgr_val.receiveStringData(request0.responseText);
                //func_val(request0.responseText);
            }
            else {
                //this0.logit("getMessage", "error=" + request0.readyState + ", " + request0.status);
            }
        };
        this.httpGetRequest().send(null);
    };

    this.postMessage = function (request_val, msg_val, session_val) {
        request_val.open("POST", this.ajxRoute(), true);
        request_val.setRequestHeader("Content-Type", this.jsonContext());

        var json_str = this.formJsonString(msg_val, session_val);
        this.logit("postMessage", "json=" + json_str);
        request_val.send(json_str);

/*
        $.ajax({
            data: {data: msg_val},
            url: dir_val,
            type: 'post',
            dataType: 'json',

        });
*/
    };

    this.newHttpRequest = function () {
        var request = new XMLHttpRequest();
        return request;
    };

    this.abend = function (str1_val, str2_val) {
        return this.utilObject().utilAbend("AjxObject." + str1_val, str2_val);
    };

    this.logit = function (str1_val, str2_val) {
        return this.utilObject().utilLogit("AjxObject." + str1_val, str2_val);
    };

    this.theHttpGetRequest = new XMLHttpRequest();
    this.theHttpPostRequest = new XMLHttpRequest();
}

<|endoftext|>


<commit_before>import * as React from 'react';
import { isFragment } from 'react-is';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';
import Typography from '../Typography';
import BreadcrumbCollapsed from './BreadcrumbCollapsed';

export const styles = {
  /* Styles applied to the root element. */
  root: {},
  /* Styles applied to the ol element. */
  ol: {
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'center',
    padding: 0,
    margin: 0,
    listStyle: 'none',
  },
  /* Styles applied to the li element. */
  li: {},
  /* Styles applied to the separator element. */
  separator: {
    display: 'flex',
    userSelect: 'none',
    marginLeft: 8,
    marginRight: 8,
  },
};

function insertSeparators(items, className, separator) {
  return items.reduce((acc, current, index) => {
    if (index < items.length - 1) {
      acc = acc.concat(
        current,
        <li aria-hidden key={`separator-${index}`} className={className}>
          {separator}

,
      );
    } else {
      acc.push(current);
    }

    return acc;
  }, []);
}

const Breadcrumbs = React.forwardRef(function Breadcrumbs(props, ref) {
  const {
    children,
    classes,
    className,
    component: Component = 'nav',
    expandText = 'Show path',
    itemsAfterCollapse = 1,
    itemsBeforeCollapse = 1,
    maxItems = 8,
    separator = '/',
    ...other
  } = props;

  const [expanded, setExpanded] = React.useState(false);

  const renderItemsBeforeAndAfter = (allItems) => {
    const handleClickExpand = (event) => {
      setExpanded(true);

      // The clicked element received the focus but gets removed from the DOM.
      // Let's keep the focus in the component after expanding.
      const focusable = event.currentTarget.parentNode.parentNode.querySelector(
        'a[href],button,[tabindex]',
      );

      if (focusable) {
        focusable.focus();
      }
    };

    // This defends against someone passing weird input, to ensure that if all
    // items would be shown anyway, we just show all items without the EllipsisItem
    if (itemsBeforeCollapse + itemsAfterCollapse >= allItems.length) {
      if (process.env.NODE_ENV !== 'production') {
        console.error(
          [
            'Material-UI: You have provided an invalid combination of props to the Breadcrumbs.',
            `itemsAfterCollapse={${itemsAfterCollapse}} + itemsBeforeCollapse={${itemsBeforeCollapse}} >= maxItems={${maxItems}}`,
          ].join('\n'),
        );
      }
      return allItems;
    }

    return [
      ...allItems.slice(0, itemsBeforeCollapse),
      <BreadcrumbCollapsed aria-label={expandText} key="ellipsis" onClick={handleClickExpand} />,
      ...allItems.slice(allItems.length - itemsAfterCollapse, allItems.length),
    ];
  };

  const allItems = React.Children.toArray(children)
    .filter((child) => {
      if (process.env.NODE_ENV !== 'production') {
        if (isFragment(child)) {
          console.error(
            [
              "Material-UI: The Breadcrumbs component doesn't accept a Fragment as a child.",
              'Consider providing an array instead.',
            ].join('\n'),
          );
        }
      }

      return React.isValidElement(child);
    })
    .map((child, index) => (
      <li className={classes.li} key={`child-${index}`}>
        {child}

    ));

  return (
    <Typography
      ref={ref}
      component={Component}
      color="textSecondary"
      className={clsx(classes.root, className)}
      {...other}
    >

        {insertSeparators(
          expanded || (maxItems && allItems.length <= maxItems)
            ? allItems
            : renderItemsBeforeAndAfter(allItems),
          classes.separator,
          separator,
        )}

    </Typography>
  );
});

Breadcrumbs.propTypes = {
  // ----------------------------- Warning --------------------------------
  // | These PropTypes are generated from the TypeScript type definitions |
  // |     To update them edit the d.ts file and run "yarn proptypes"     |
  // ----------------------------------------------------------------------
  /**
   * The breadcrumb children.
   */
  children: PropTypes.node,
  /**
   * Override or extend the styles applied to the component.
   */
  classes: PropTypes.object,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * The component used for the root node.
   * Either a string to use a HTML element or a component.
   */
  component: PropTypes.elementType,
  /**
   * Override the default label for the expand button.
   *
   * For localization purposes, you can use the provided [translations](/guides/localization/).
   */
  expandText: PropTypes.string,
  /**
   * If max items is exceeded, the number of items to show after the ellipsis.
   */
  itemsAfterCollapse: PropTypes.number,
  /**
   * If max items is exceeded, the number of items to show before the ellipsis.
   */
  itemsBeforeCollapse: PropTypes.number,
  /**
   * Specifies the maximum number of breadcrumbs to display. When there are more
   * than the maximum number, only the first `itemsBeforeCollapse` and last `itemsAfterCollapse`
   * will be shown, with an ellipsis in between.
   */
  maxItems: PropTypes.number,
  /**
   * Custom separator node.
   */
  separator: PropTypes.node,
};

export default withStyles(styles, { name: 'MuiBreadcrumbs' })(Breadcrumbs);
<commit_msg>[Breadcrumbs] More robust focus capture (#22374)<commit_after>import * as React from 'react';
import { isFragment } from 'react-is';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import withStyles from '../styles/withStyles';
import Typography from '../Typography';
import BreadcrumbCollapsed from './BreadcrumbCollapsed';

export const styles = {
  /* Styles applied to the root element. */
  root: {},
  /* Styles applied to the ol element. */
  ol: {
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'center',
    padding: 0,
    margin: 0,
    listStyle: 'none',
  },
  /* Styles applied to the li element. */
  li: {},
  /* Styles applied to the separator element. */
  separator: {
    display: 'flex',
    userSelect: 'none',
    marginLeft: 8,
    marginRight: 8,
  },
};

function insertSeparators(items, className, separator) {
  return items.reduce((acc, current, index) => {
    if (index < items.length - 1) {
      acc = acc.concat(
        current,
        <li aria-hidden key={`separator-${index}`} className={className}>
          {separator}

,
      );
    } else {
      acc.push(current);
    }

    return acc;
  }, []);
}

const Breadcrumbs = React.forwardRef(function Breadcrumbs(props, ref) {
  const {
    children,
    classes,
    className,
    component: Component = 'nav',
    expandText = 'Show path',
    itemsAfterCollapse = 1,
    itemsBeforeCollapse = 1,
    maxItems = 8,
    separator = '/',
    ...other
  } = props;

  const [expanded, setExpanded] = React.useState(false);

  const listRef = React.useRef(null);
  const renderItemsBeforeAndAfter = (allItems) => {
    const handleClickExpand = () => {
      setExpanded(true);

      // The clicked element received the focus but gets removed from the DOM.
      // Let's keep the focus in the component after expanding.
      // Moving it the the
 or  does not cause any announcement in NVDA.
      // By moving it to some link/button at least we have some announcement.
      const focusable = listRef.current.querySelector('a[href],button,[tabindex]');
      if (focusable) {
        focusable.focus();
      }
    };

    // This defends against someone passing weird input, to ensure that if all
    // items would be shown anyway, we just show all items without the EllipsisItem
    if (itemsBeforeCollapse + itemsAfterCollapse >= allItems.length) {
      if (process.env.NODE_ENV !== 'production') {
        console.error(
          [
            'Material-UI: You have provided an invalid combination of props to the Breadcrumbs.',
            `itemsAfterCollapse={${itemsAfterCollapse}} + itemsBeforeCollapse={${itemsBeforeCollapse}} >= maxItems={${maxItems}}`,
          ].join('\n'),
        );
      }
      return allItems;
    }

    return [
      ...allItems.slice(0, itemsBeforeCollapse),
      <BreadcrumbCollapsed aria-label={expandText} key="ellipsis" onClick={handleClickExpand} />,
      ...allItems.slice(allItems.length - itemsAfterCollapse, allItems.length),
    ];
  };

  const allItems = React.Children.toArray(children)
    .filter((child) => {
      if (process.env.NODE_ENV !== 'production') {
        if (isFragment(child)) {
          console.error(
            [
              "Material-UI: The Breadcrumbs component doesn't accept a Fragment as a child.",
              'Consider providing an array instead.',
            ].join('\n'),
          );
        }
      }

      return React.isValidElement(child);
    })
    .map((child, index) => (
      <li className={classes.li} key={`child-${index}`}>
        {child}

    ));

  return (
    <Typography
      ref={ref}
      component={Component}
      color="textSecondary"
      className={clsx(classes.root, className)}
      {...other}
    >

        {insertSeparators(
          expanded || (maxItems && allItems.length <= maxItems)
            ? allItems
            : renderItemsBeforeAndAfter(allItems),
          classes.separator,
          separator,
        )}

    </Typography>
  );
});

Breadcrumbs.propTypes = {
  // ----------------------------- Warning --------------------------------
  // | These PropTypes are generated from the TypeScript type definitions |
  // |     To update them edit the d.ts file and run "yarn proptypes"     |
  // ----------------------------------------------------------------------
  /**
   * The breadcrumb children.
   */
  children: PropTypes.node,
  /**
   * Override or extend the styles applied to the component.
   */
  classes: PropTypes.object,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * The component used for the root node.
   * Either a string to use a HTML element or a component.
   */
  component: PropTypes.elementType,
  /**
   * Override the default label for the expand button.
   *
   * For localization purposes, you can use the provided [translations](/guides/localization/).
   */
  expandText: PropTypes.string,
  /**
   * If max items is exceeded, the number of items to show after the ellipsis.
   */
  itemsAfterCollapse: PropTypes.number,
  /**
   * If max items is exceeded, the number of items to show before the ellipsis.
   */
  itemsBeforeCollapse: PropTypes.number,
  /**
   * Specifies the maximum number of breadcrumbs to display. When there are more
   * than the maximum number, only the first `itemsBeforeCollapse` and last `itemsAfterCollapse`
   * will be shown, with an ellipsis in between.
   */
  maxItems: PropTypes.number,
  /**
   * Custom separator node.
   */
  separator: PropTypes.node,
};

export default withStyles(styles, { name: 'MuiBreadcrumbs' })(Breadcrumbs);
<|endoftext|>


<commit_before>module.exports = function(grunt) {

	// Project configuration.
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		clean: ['./public/patterns'],
		copy: {
			main: {
				files: [
					{ expand: true, cwd: './source/js/', src: '*', dest: './public/js/'},
					{ expand: true, cwd: './source/css/', src: 'style.css', dest: './public/css/' },
					{ expand: true, cwd: './source/images/', src: '*', dest: './public/images/' },
					{ expand: true, cwd: './source/images/sample/', src: '*', dest: './public/images/sample/'},
					{ expand: true, cwd: './source/fonts/', src: '*', dest: './public/fonts/'}
				]
			}
		},
		jshint: {
			options: {
				"curly": true,
				"eqnull": true,
				"eqeqeq": true,
				"undef": true,
				"forin": true,
				//"unused": true,
				"node": true
			},
			patternlab: ['Gruntfile.js', './builder/lib/patternlab.js']
		},
		watch: {
			// scss: { //scss can be watched if you like
			// 	files: ['source/css/**/*.scss', 'public/styleguide/css/*.scss'],
			// 	tasks: ['default']
			// },
			mustache: {
				files: ['source/_patterns/**/*.mustache'],
				tasks: ['default']
			},
			data: {
				files: ['source/_patterns/**/*.json'],
				tasks: ['default']
			}
		},
		sass: {
			build: {
				options: {
					style: 'expanded',
					precision: 8
				},
				files: {
					'./source/css/style.css': './source/css/style.scss',
					'./public/styleguide/css/static.css': './public/styleguide/css/static.scss',
					'./public/styleguide/css/styleguide.css': './public/styleguide/css/styleguide.scss'
				}
			}
		}
	});

	// load all grunt tasks
 	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

	//load the patternlab task
	grunt.task.loadTasks('./builder/');

	//if you choose to use scss, or any preprocessor, you can add it here
	grunt.registerTask('default', ['clean', 'patternlab', /*'sass',*/ 'copy']);
};<commit_msg>only copy images<commit_after>module.exports = function(grunt) {

	// Project configuration.
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		clean: ['./public/patterns'],
		copy: {
			main: {
				files: [
					{ expand: true, cwd: './source/js/', src: '*', dest: './public/js/'},
					{ expand: true, cwd: './source/css/', src: 'style.css', dest: './public/css/' },
					{ expand: true, cwd: './source/images/', src: ['*.png', '*.jpg', '*.gif', '*.jpeg'], dest: './public/images/' },
					{ expand: true, cwd: './source/images/sample/', src: ['*.png', '*.jpg', '*.gif', '*.jpeg'], dest: './public/images/sample/'},
					{ expand: true, cwd: './source/fonts/', src: '*', dest: './public/fonts/'}
				]
			}
		},
		jshint: {
			options: {
				"curly": true,
				"eqnull": true,
				"eqeqeq": true,
				"undef": true,
				"forin": true,
				//"unused": true,
				"node": true
			},
			patternlab: ['Gruntfile.js', './builder/lib/patternlab.js']
		},
		watch: {
			// scss: { //scss can be watched if you like
			// 	files: ['source/css/**/*.scss', 'public/styleguide/css/*.scss'],
			// 	tasks: ['default']
			// },
			mustache: {
				files: ['source/_patterns/**/*.mustache'],
				tasks: ['default']
			},
			data: {
				files: ['source/_patterns/**/*.json'],
				tasks: ['default']
			}
		},
		sass: {
			build: {
				options: {
					style: 'expanded',
					precision: 8
				},
				files: {
					'./source/css/style.css': './source/css/style.scss',
					'./public/styleguide/css/static.css': './public/styleguide/css/static.scss',
					'./public/styleguide/css/styleguide.css': './public/styleguide/css/styleguide.scss'
				}
			}
		}
	});

	// load all grunt tasks
 	require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

	//load the patternlab task
	grunt.task.loadTasks('./builder/');

	//if you choose to use scss, or any preprocessor, you can add it here
	grunt.registerTask('default', ['clean', 'patternlab', /*'sass',*/ 'copy']);
};<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

'use strict';

var path = require('path');
var fs = require('fs');
var util = require('util');

var SSL_ROOTS_PATH = path.resolve(__dirname, 'deps', 'grpc', 'etc', 'roots.pem');

var _ = require('lodash');

var ProtoBuf = require('protobufjs');

var client = require('./src/client.js');

var server = require('./src/server.js');

var common = require('./src/common.js');

var Metadata = require('./src/metadata.js');

var grpc = require('./src/grpc_extension');

var protobuf_js_5_common = require('./src/protobuf_js_5_common');
var protobuf_js_6_common = require('./src/protobuf_js_6_common');

var constants = require('./src/constants.js');

grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii'));

/**
 * @namespace grpc
 */

/**
 * Load a ProtoBuf.js object as a gRPC object.
 * @memberof grpc
 * @alias grpc.loadObject
 * @param {Object} value The ProtoBuf.js reflection object to load
 * @param {Object=} options Options to apply to the loaded file
 * @param {bool=} [options.binaryAsBase64=false] deserialize bytes values as
 *     base64 strings instead of Buffers
 * @param {bool=} [options.longsAsStrings=true] deserialize long values as
 *     strings instead of objects
 * @param {bool=} [options.enumsAsStrings=true] deserialize enum values as
 *     strings instead of numbers. Only works with Protobuf.js 6 values.
 * @param {bool=} [options.deprecatedArgumentOrder=false] use the beta method
 *     argument order for client methods, with optional arguments after the
 *     callback. This option is only a temporary stopgap measure to smooth an
 *     API breakage. It is deprecated, and new code should not use it.
 * @param {(number|string)=} [options.protobufjsVersion='detect'] 5 and 6
 *     respectively indicate that an object from the corresponding version of
 *     Protobuf.js is provided in the value argument. If the option is 'detect',
 *     gRPC will guess what the version is based on the structure of the value.
 * @return {Object<string, *>} The resulting gRPC object.
 */
exports.loadObject = function loadObject(value, options) {
  options = _.defaults(options, common.defaultGrpcOptions);
  options = _.defaults(options, {'protobufjsVersion': 'detect'});
  var protobufjsVersion;
  if (options.protobufjsVersion === 'detect') {
    if (protobuf_js_6_common.isProbablyProtobufJs6(value)) {
      protobufjsVersion = 6;
    } else if (protobuf_js_5_common.isProbablyProtobufJs5(value)) {
      protobufjsVersion = 5;
    } else {
      var error_message = 'Could not detect ProtoBuf.js version. Please ' +
          'specify the version number with the "protobufjsVersion" option';
      throw new Error(error_message);
    }
  } else {
    protobufjsVersion = options.protobufjsVersion;
  }
  switch (protobufjsVersion) {
    case 6: return protobuf_js_6_common.loadObject(value, options);
    case 5:
    return protobuf_js_5_common.loadObject(value, options);
    default:
    throw new Error('Unrecognized protobufjsVersion', protobufjsVersion);
  }
};

var loadObject = exports.loadObject;

/**
 * Load a gRPC object from a .proto file.
 * @memberof grpc
 * @alias grpc.load
 * @param {string|{root: string, file: string}} filename The file to load
 * @param {string=} format The file format to expect. Must be either 'proto' or
 *     'json'. Defaults to 'proto'
 * @param {Object=} options Options to apply to the loaded file
 * @param {bool=} [options.convertFieldsToCamelCase=false] Load this file with
 *     field names in camel case instead of their original case
 * @param {bool=} [options.binaryAsBase64=false] deserialize bytes values as
 *     base64 strings instead of Buffers
 * @param {bool=} [options.longsAsStrings=true] deserialize long values as
 *     strings instead of objects
 * @param {bool=} [options.deprecatedArgumentOrder=false] use the beta method
 *     argument order for client methods, with optional arguments after the
 *     callback. This option is only a temporary stopgap measure to smooth an
 *     API breakage. It is deprecated, and new code should not use it.
 * @return {Object<string, *>} The resulting gRPC object
 */
exports.load = util.deprecate(function load(filename, format, options) {
  options = _.defaults(options, common.defaultGrpcOptions);
  options.protobufjsVersion = 5;
  if (!format) {
    format = 'proto';
  }
  var convertFieldsToCamelCaseOriginal = ProtoBuf.convertFieldsToCamelCase;
  if(options && options.hasOwnProperty('convertFieldsToCamelCase')) {
    ProtoBuf.convertFieldsToCamelCase = options.convertFieldsToCamelCase;
  }
  var builder;
  try {
    switch(format) {
      case 'proto':
      builder = ProtoBuf.loadProtoFile(filename);
      break;
      case 'json':
      builder = ProtoBuf.loadJsonFile(filename);
      break;
      default:
      throw new Error('Unrecognized format "' + format + '"');
    }
  } finally {
    ProtoBuf.convertFieldsToCamelCase = convertFieldsToCamelCaseOriginal;
  }

  if (!builder) {
    throw new Error('Could not load file "' + filename + '"');
  }

  return loadObject(builder.ns, options);
}, 'grpc.load: Use the @grpc/proto-loader module with grpc.loadPackageDefinition instead');

/**
 * Load a gRPC package definition as a gRPC object hierarchy
 * @param packageDef grpc~PackageDefinition The package definition object
 * @return {Object<string, *>} The resulting gRPC object
 */
exports.loadPackageDefinition = function loadPackageDefintion(packageDef) {
  const result = {};
  for (const serviceFqn in packageDef) {
    const service = packageDef[serviceFqn];
    const nameComponents = serviceFqn.split('.');
    const serviceName = nameComponents[nameComponents.length-1];
    let current = result;
    for (const packageName of nameComponents.slice(0, -1)) {
      if (!current[packageName]) {
        current[packageName] = {};
      }
      current = current[packageName];
    }
    current[serviceName] = client.makeClientConstructor(service, serviceName, {});
  }
  return result;
};

var log_template = function(args) {
  var file = args.file;
  var line = args.line;
  var severity = args.severity;
  var message = args.message;
  var timestamp = args.timestamp;
  return `${severity} ${timestamp}\t${file}:${line}]\t${message}`;
};

/**
 * Sets the logger function for the gRPC module. For debugging purposes, the C
 * core will log synchronously directly to stdout unless this function is
 * called. Note: the output format here is intended to be informational, and
 * is not guaranteed to stay the same in the future.
 * Logs will be directed to logger.error.
 * @memberof grpc
 * @alias grpc.setLogger
 * @param {Console} logger A Console-like object.
 */
exports.setLogger = function setLogger(logger) {
  common.logger = logger;
  grpc.setDefaultLoggerCallback(function(file, line, severity,
                                         message, timestamp) {
    logger.error(log_template({
      file: path.basename(file),
      line: line,
      severity: severity,
      message: message,
      timestamp: timestamp.toISOString()
    }));
  });
};

/**
 * Sets the logger verbosity for gRPC module logging. The options are members
 * of the grpc.logVerbosity map.
 * @memberof grpc
 * @alias grpc.setLogVerbosity
 * @param {Number} verbosity The minimum severity to log
 */
exports.setLogVerbosity = function setLogVerbosity(verbosity) {
  common.logVerbosity = verbosity;
  grpc.setLogVerbosity(verbosity);
};

exports.Server = server.Server;

exports.Metadata = Metadata;

exports.status = constants.status;

exports.propagate = constants.propagate;

exports.callError = constants.callError;

exports.writeFlags = constants.writeFlags;

exports.logVerbosity = constants.logVerbosity;

exports.methodTypes = constants.methodTypes;

exports.connectivityState = constants.connectivityState;

exports.credentials = require('./src/credentials.js');

/**
 * ServerCredentials factories
 * @constructor ServerCredentials
 * @memberof grpc
 */
exports.ServerCredentials = grpc.ServerCredentials;

/**
 * Create insecure server credentials
 * @name grpc.ServerCredentials.createInsecure
 * @kind function
 * @return {grpc.ServerCredentials}
 */

/**
 * A private key and certificate pair
 * @typedef {Object} grpc.ServerCredentials~keyCertPair
 * @property {Buffer} private_key The server's private key
 * @property {Buffer} cert_chain The server's certificate chain
 */

/**
 * Create SSL server credentials
 * @name grpc.ServerCredentials.createSsl
 * @kind function
 * @param {?Buffer} rootCerts Root CA certificates for validating client
 *     certificates
 * @param {Array<grpc.ServerCredentials~keyCertPair>} keyCertPairs A list of
 *     private key and certificate chain pairs to be used for authenticating
 *     the server
 * @param {boolean} [checkClientCertificate=false] Indicates that the server
 *     should request and verify the client's certificates
 * @return {grpc.ServerCredentials}
 */

exports.makeGenericClientConstructor = client.makeClientConstructor;

exports.getClientChannel = client.getClientChannel;

exports.waitForClientReady = client.waitForClientReady;

exports.StatusBuilder = client.StatusBuilder;
exports.ListenerBuilder = client.ListenerBuilder;
exports.RequesterBuilder = client.RequesterBuilder;
exports.InterceptingCall = client.InterceptingCall;

/**
 * @memberof grpc
 * @alias grpc.closeClient
 * @param {grpc.Client} client_obj The client to close
 */
exports.closeClient = function closeClient(client_obj) {
  client.Client.prototype.close.apply(client_obj);
};

exports.Client = client.Client;

/**
 * @typedef {Object.<string, string | number>} grpc~ChannelOptions
 */

/**
 * This constructor API is almost identical to the Client constructor,
 * except that some of the options for the Client constructor are not valid
 * here.
 * @constructor Channel
 * @memberof grpc
 * @param {string} target The address of the server to connect to
 * @param {grpc.ChannelCredentials} credentials Channel credentials to use when connecting
 * @param {grpc~ChannelOptions} options A map of channel options that will be passed to the core
 */
exports.Channel = grpc.Channel;

/**
 * Close the channel. This has the same functionality as the existing grpc.Client#close
 * @name grpc.Channel#close
 * @kind function
 */

/**
 * Return the target that this channel connects to
 * @name grpc.Channel#getTarget
 * @kind function
 * @return {string} The target
 */

/**
 * Get the channel's current connectivity state.
 * @name grpc.Channel#getConnectivityState
 * @kind function
 * @param {boolean} tryToConnect If true, the channel will start connecting if it is
 *     idle. Otherwise, idle channels will only start connecting when a
 *     call starts.
 * @return {grpc.connectivityState} The current connectivity state
 */

/**
 * @callback grpc.Channel~watchConnectivityStateCallback
 * @param {Error?} error
 */

/**
 * Watch for connectivity state changes.
 * @name grpc.Channel#watchConnectivityState
 * @kind function
 * @param {grpc.ConnectivityState} currentState The state to watch for
 *     transitions from. This should always be populated by calling
 *     getConnectivityState immediately before.
 * @param {grpc~Deadline} deadline A deadline for waiting for a state change
 * @param {grpc.Channel~watchConnectivityStateCallback} callback Called with no
 *     error when the state changes, or with an error if the deadline passes
 *     without a state change
 */

/**
 * @name grpc~Call
 * @kind class
 */

/**
 * Create a call object. Call is an opaque type used by the {@link grpc.Client}
 * and {@link grpc.Server} classes. This function is called by the gRPC library
 * when starting a request. Implementers should return an instance of Call that
 * is returned from calling createCall on an instance of the provided Channel
 * class.
 * @name grpc.Channel#createCall
 * @kind function
 * @param {string} method The full method string to request
 * @param {grpc~Deadline} deadline The call deadline
 * @param {string|null} host A host string override for making the request
 * @param {grpc~Call|null} parentCall A server call to propagate some
 *     information from
 * @param {number|null} propagateFlags A bitwise combination of elements of
 *     {@link grpc.propagate} that indicates what information to propagate
 *     from parentCall
 * @return {grpc~Call}
 */<commit_msg>Add a jsdoc @deprecated for grpc.load.<commit_after>/**
 * @license
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

'use strict';

var path = require('path');
var fs = require('fs');
var util = require('util');

var SSL_ROOTS_PATH = path.resolve(__dirname, 'deps', 'grpc', 'etc', 'roots.pem');

var _ = require('lodash');

var ProtoBuf = require('protobufjs');

var client = require('./src/client.js');

var server = require('./src/server.js');

var common = require('./src/common.js');

var Metadata = require('./src/metadata.js');

var grpc = require('./src/grpc_extension');

var protobuf_js_5_common = require('./src/protobuf_js_5_common');
var protobuf_js_6_common = require('./src/protobuf_js_6_common');

var constants = require('./src/constants.js');

grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii'));

/**
 * @namespace grpc
 */

/**
 * Load a ProtoBuf.js object as a gRPC object.
 * @memberof grpc
 * @alias grpc.loadObject
 * @param {Object} value The ProtoBuf.js reflection object to load
 * @param {Object=} options Options to apply to the loaded file
 * @param {bool=} [options.binaryAsBase64=false] deserialize bytes values as
 *     base64 strings instead of Buffers
 * @param {bool=} [options.longsAsStrings=true] deserialize long values as
 *     strings instead of objects
 * @param {bool=} [options.enumsAsStrings=true] deserialize enum values as
 *     strings instead of numbers. Only works with Protobuf.js 6 values.
 * @param {bool=} [options.deprecatedArgumentOrder=false] use the beta method
 *     argument order for client methods, with optional arguments after the
 *     callback. This option is only a temporary stopgap measure to smooth an
 *     API breakage. It is deprecated, and new code should not use it.
 * @param {(number|string)=} [options.protobufjsVersion='detect'] 5 and 6
 *     respectively indicate that an object from the corresponding version of
 *     Protobuf.js is provided in the value argument. If the option is 'detect',
 *     gRPC will guess what the version is based on the structure of the value.
 * @return {Object<string, *>} The resulting gRPC object.
 */
exports.loadObject = function loadObject(value, options) {
  options = _.defaults(options, common.defaultGrpcOptions);
  options = _.defaults(options, {'protobufjsVersion': 'detect'});
  var protobufjsVersion;
  if (options.protobufjsVersion === 'detect') {
    if (protobuf_js_6_common.isProbablyProtobufJs6(value)) {
      protobufjsVersion = 6;
    } else if (protobuf_js_5_common.isProbablyProtobufJs5(value)) {
      protobufjsVersion = 5;
    } else {
      var error_message = 'Could not detect ProtoBuf.js version. Please ' +
          'specify the version number with the "protobufjsVersion" option';
      throw new Error(error_message);
    }
  } else {
    protobufjsVersion = options.protobufjsVersion;
  }
  switch (protobufjsVersion) {
    case 6: return protobuf_js_6_common.loadObject(value, options);
    case 5:
    return protobuf_js_5_common.loadObject(value, options);
    default:
    throw new Error('Unrecognized protobufjsVersion', protobufjsVersion);
  }
};

var loadObject = exports.loadObject;

/**
 * Load a gRPC object from a .proto file.
 * @deprecated Use the {@link https://www.npmjs.com/package/@grpc/proto-loader|proto-loader module}
       with grpc.loadPackageDefinition instead.
 * @memberof grpc
 * @alias grpc.load
 * @param {string|{root: string, file: string}} filename The file to load
 * @param {string=} format The file format to expect. Must be either 'proto' or
 *     'json'. Defaults to 'proto'
 * @param {Object=} options Options to apply to the loaded file
 * @param {bool=} [options.convertFieldsToCamelCase=false] Load this file with
 *     field names in camel case instead of their original case
 * @param {bool=} [options.binaryAsBase64=false] deserialize bytes values as
 *     base64 strings instead of Buffers
 * @param {bool=} [options.longsAsStrings=true] deserialize long values as
 *     strings instead of objects
 * @param {bool=} [options.deprecatedArgumentOrder=false] use the beta method
 *     argument order for client methods, with optional arguments after the
 *     callback. This option is only a temporary stopgap measure to smooth an
 *     API breakage. It is deprecated, and new code should not use it.
 * @return {Object<string, *>} The resulting gRPC object
 */
exports.load = util.deprecate(function load(filename, format, options) {
  options = _.defaults(options, common.defaultGrpcOptions);
  options.protobufjsVersion = 5;
  if (!format) {
    format = 'proto';
  }
  var convertFieldsToCamelCaseOriginal = ProtoBuf.convertFieldsToCamelCase;
  if(options && options.hasOwnProperty('convertFieldsToCamelCase')) {
    ProtoBuf.convertFieldsToCamelCase = options.convertFieldsToCamelCase;
  }
  var builder;
  try {
    switch(format) {
      case 'proto':
      builder = ProtoBuf.loadProtoFile(filename);
      break;
      case 'json':
      builder = ProtoBuf.loadJsonFile(filename);
      break;
      default:
      throw new Error('Unrecognized format "' + format + '"');
    }
  } finally {
    ProtoBuf.convertFieldsToCamelCase = convertFieldsToCamelCaseOriginal;
  }

  if (!builder) {
    throw new Error('Could not load file "' + filename + '"');
  }

  return loadObject(builder.ns, options);
}, 'grpc.load: Use the @grpc/proto-loader module with grpc.loadPackageDefinition instead');

/**
 * Load a gRPC package definition as a gRPC object hierarchy
 * @param packageDef grpc~PackageDefinition The package definition object
 * @return {Object<string, *>} The resulting gRPC object
 */
exports.loadPackageDefinition = function loadPackageDefintion(packageDef) {
  const result = {};
  for (const serviceFqn in packageDef) {
    const service = packageDef[serviceFqn];
    const nameComponents = serviceFqn.split('.');
    const serviceName = nameComponents[nameComponents.length-1];
    let current = result;
    for (const packageName of nameComponents.slice(0, -1)) {
      if (!current[packageName]) {
        current[packageName] = {};
      }
      current = current[packageName];
    }
    current[serviceName] = client.makeClientConstructor(service, serviceName, {});
  }
  return result;
};

var log_template = function(args) {
  var file = args.file;
  var line = args.line;
  var severity = args.severity;
  var message = args.message;
  var timestamp = args.timestamp;
  return `${severity} ${timestamp}\t${file}:${line}]\t${message}`;
};

/**
 * Sets the logger function for the gRPC module. For debugging purposes, the C
 * core will log synchronously directly to stdout unless this function is
 * called. Note: the output format here is intended to be informational, and
 * is not guaranteed to stay the same in the future.
 * Logs will be directed to logger.error.
 * @memberof grpc
 * @alias grpc.setLogger
 * @param {Console} logger A Console-like object.
 */
exports.setLogger = function setLogger(logger) {
  common.logger = logger;
  grpc.setDefaultLoggerCallback(function(file, line, severity,
                                         message, timestamp) {
    logger.error(log_template({
      file: path.basename(file),
      line: line,
      severity: severity,
      message: message,
      timestamp: timestamp.toISOString()
    }));
  });
};

/**
 * Sets the logger verbosity for gRPC module logging. The options are members
 * of the grpc.logVerbosity map.
 * @memberof grpc
 * @alias grpc.setLogVerbosity
 * @param {Number} verbosity The minimum severity to log
 */
exports.setLogVerbosity = function setLogVerbosity(verbosity) {
  common.logVerbosity = verbosity;
  grpc.setLogVerbosity(verbosity);
};

exports.Server = server.Server;

exports.Metadata = Metadata;

exports.status = constants.status;

exports.propagate = constants.propagate;

exports.callError = constants.callError;

exports.writeFlags = constants.writeFlags;

exports.logVerbosity = constants.logVerbosity;

exports.methodTypes = constants.methodTypes;

exports.connectivityState = constants.connectivityState;

exports.credentials = require('./src/credentials.js');

/**
 * ServerCredentials factories
 * @constructor ServerCredentials
 * @memberof grpc
 */
exports.ServerCredentials = grpc.ServerCredentials;

/**
 * Create insecure server credentials
 * @name grpc.ServerCredentials.createInsecure
 * @kind function
 * @return {grpc.ServerCredentials}
 */

/**
 * A private key and certificate pair
 * @typedef {Object} grpc.ServerCredentials~keyCertPair
 * @property {Buffer} private_key The server's private key
 * @property {Buffer} cert_chain The server's certificate chain
 */

/**
 * Create SSL server credentials
 * @name grpc.ServerCredentials.createSsl
 * @kind function
 * @param {?Buffer} rootCerts Root CA certificates for validating client
 *     certificates
 * @param {Array<grpc.ServerCredentials~keyCertPair>} keyCertPairs A list of
 *     private key and certificate chain pairs to be used for authenticating
 *     the server
 * @param {boolean} [checkClientCertificate=false] Indicates that the server
 *     should request and verify the client's certificates
 * @return {grpc.ServerCredentials}
 */

exports.makeGenericClientConstructor = client.makeClientConstructor;

exports.getClientChannel = client.getClientChannel;

exports.waitForClientReady = client.waitForClientReady;

exports.StatusBuilder = client.StatusBuilder;
exports.ListenerBuilder = client.ListenerBuilder;
exports.RequesterBuilder = client.RequesterBuilder;
exports.InterceptingCall = client.InterceptingCall;

/**
 * @memberof grpc
 * @alias grpc.closeClient
 * @param {grpc.Client} client_obj The client to close
 */
exports.closeClient = function closeClient(client_obj) {
  client.Client.prototype.close.apply(client_obj);
};

exports.Client = client.Client;

/**
 * @typedef {Object.<string, string | number>} grpc~ChannelOptions
 */

/**
 * This constructor API is almost identical to the Client constructor,
 * except that some of the options for the Client constructor are not valid
 * here.
 * @constructor Channel
 * @memberof grpc
 * @param {string} target The address of the server to connect to
 * @param {grpc.ChannelCredentials} credentials Channel credentials to use when connecting
 * @param {grpc~ChannelOptions} options A map of channel options that will be passed to the core
 */
exports.Channel = grpc.Channel;

/**
 * Close the channel. This has the same functionality as the existing grpc.Client#close
 * @name grpc.Channel#close
 * @kind function
 */

/**
 * Return the target that this channel connects to
 * @name grpc.Channel#getTarget
 * @kind function
 * @return {string} The target
 */

/**
 * Get the channel's current connectivity state.
 * @name grpc.Channel#getConnectivityState
 * @kind function
 * @param {boolean} tryToConnect If true, the channel will start connecting if it is
 *     idle. Otherwise, idle channels will only start connecting when a
 *     call starts.
 * @return {grpc.connectivityState} The current connectivity state
 */

/**
 * @callback grpc.Channel~watchConnectivityStateCallback
 * @param {Error?} error
 */

/**
 * Watch for connectivity state changes.
 * @name grpc.Channel#watchConnectivityState
 * @kind function
 * @param {grpc.ConnectivityState} currentState The state to watch for
 *     transitions from. This should always be populated by calling
 *     getConnectivityState immediately before.
 * @param {grpc~Deadline} deadline A deadline for waiting for a state change
 * @param {grpc.Channel~watchConnectivityStateCallback} callback Called with no
 *     error when the state changes, or with an error if the deadline passes
 *     without a state change
 */

/**
 * @name grpc~Call
 * @kind class
 */

/**
 * Create a call object. Call is an opaque type used by the {@link grpc.Client}
 * and {@link grpc.Server} classes. This function is called by the gRPC library
 * when starting a request. Implementers should return an instance of Call that
 * is returned from calling createCall on an instance of the provided Channel
 * class.
 * @name grpc.Channel#createCall
 * @kind function
 * @param {string} method The full method string to request
 * @param {grpc~Deadline} deadline The call deadline
 * @param {string|null} host A host string override for making the request
 * @param {grpc~Call|null} parentCall A server call to propagate some
 *     information from
 * @param {number|null} propagateFlags A bitwise combination of elements of
 *     {@link grpc.propagate} that indicates what information to propagate
 *     from parentCall
 * @return {grpc~Call}
 */
<|endoftext|>