<commit_before>"use strict";
var sdk = require("../..");
var HttpBackend = require("../mock-request");
var utils = require("../test-utils");
function MockStorageApi() {
    this.data = {};
}
MockStorageApi.prototype = {
    setItem: function(k, v) {
        this.data[k] = v;
    },
    getItem: function(k) {
        return this.data[k] || null;
    },
    removeItem: function(k) {
        delete this.data[k];
    }
};

describe("MatrixClient crypto", function() {
    var baseUrl = "http://localhost.or.something";
    var httpBackend;
    var aliClient;
    var roomId = "!room:localhost";
    var aliUserId = "@ali:localhost";
    var aliDeviceId = "zxcvb";
    var aliAccessToken = "aseukfgwef";
    var bobClient;
    var bobUserId = "@bob:localhost";
    var bobDeviceId = "bvcxz";
    var bobAccessToken = "fewgfkuesa";
    var bobOneTimeKeys;
    var bobDeviceKeys;
    var bobDeviceCurve25519Key;
    var aliLocalStore;
    var aliStorage;
    var bobStorage;
    var aliMessage;

    beforeEach(function() {
        aliLocalStore = new MockStorageApi();
        aliStorage = new sdk.WebStorageSessionStore(aliLocalStore);
        bobStorage = new sdk.WebStorageSessionStore(new MockStorageApi());
        utils.beforeEach(this);
        httpBackend = new HttpBackend();
        sdk.request(httpBackend.requestFn);

        aliClient = sdk.createClient({
            baseUrl: baseUrl,
            userId: aliUserId,
            accessToken: aliAccessToken,
            deviceId: aliDeviceId,
            sessionStore: aliStorage
        });

        bobClient = sdk.createClient({
            baseUrl: baseUrl,
            userId: bobUserId,
            accessToken: bobAccessToken,
            deviceId: bobDeviceId,
            sessionStore: bobStorage
        });

        httpBackend.when("GET", "/pushrules").respond(200, {});
    });

    describe("Ali account setup", function() {
        it("should have device keys", function(done) {
            expect(aliClient.deviceKeys).toBeDefined();
            expect(aliClient.deviceKeys.user_id).toEqual(aliUserId);
            expect(aliClient.deviceKeys.device_id).toEqual(aliDeviceId);
            done();
        });
        it("should have a curve25519 key", function(done) {
            expect(aliClient.deviceCurve25519Key).toBeDefined();
            done();
        });
    });

    function bobUploadsKeys(done) {
        var uploadPath = "/keys/upload/bvcxz";
        httpBackend.when("POST", uploadPath).respond(200, function(path, content) {
            expect(content.one_time_keys).toEqual({});
            httpBackend.when("POST", uploadPath).respond(200, function(path, content) {
                expect(content.one_time_keys).not.toEqual({});
                bobDeviceKeys = content.device_keys;
                bobOneTimeKeys = content.one_time_keys;
                var count = 0;
                for (var key in content.one_time_keys) {
                    if (content.one_time_keys.hasOwnProperty(key)) {
                        count++;
                    }
                }
                expect(count).toEqual(5);
                return {one_time_key_counts: {curve25519: count}};
            });
            return {one_time_key_counts: {}};
        });
        bobClient.uploadKeys(5);
        httpBackend.flush().done(function() {
            expect(bobDeviceKeys).toBeDefined();
            expect(bobOneTimeKeys).toBeDefined();
            bobDeviceCurve25519Key = bobDeviceKeys.keys["curve25519:bvcxz"];
            done();
        });
    }

    it("Bob uploads without one-time keys and with one-time keys", bobUploadsKeys);

    function aliDownloadsKeys(done) {
        var bobKeys = {};
        bobKeys[bobDeviceId] = bobDeviceKeys;
        httpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
            expect(content.device_keys[bobUserId]).toEqual({});
            var result = {};
            result[bobUserId] = bobKeys;
            return {device_keys: result};
        });
        aliClient.downloadKeys([bobUserId]);
        httpBackend.flush().done(function() {
            var devices = aliStorage.getEndToEndDevicesForUser(bobUserId);
            expect(devices).toEqual(bobKeys);
            done();
        });
    }

    it("Ali downloads Bobs keys", function(done) {
        bobUploadsKeys(function() {aliDownloadsKeys(done);});
    });

    function aliEnablesEncryption(done) {
        httpBackend.when("POST", "/keys/claim").respond(200, function(path, content) {
            expect(content.one_time_keys[bobUserId][bobDeviceId]).toEqual("curve25519");
            for (var keyId in bobOneTimeKeys) {
                if (bobOneTimeKeys.hasOwnProperty(keyId)) {
                    if (keyId.indexOf("curve25519:") === 0) {
                        break;
                    }
                }
            }
            var result = {};
            result[bobUserId] = {};
            result[bobUserId][bobDeviceId] = {};
            result[bobUserId][bobDeviceId][keyId] = bobOneTimeKeys[keyId];
            return {one_time_keys: result};
        });
        aliClient.setRoomEncryption(roomId, {
            algorithm: "m.olm.v1.curve25519-aes-sha2",
            members: [aliUserId, bobUserId]
        }).then(function(res) {
            expect(res.missingUsers).toEqual([]);
            expect(res.missingDevices).toEqual({});
            done();
        });
        httpBackend.flush();
    }

    it("Ali enables encryption", function(done) {
        bobUploadsKeys(function() {
            aliDownloadsKeys(function() {
                aliEnablesEncryption(done);
            });
        });
    });

    function aliSendsMessage(done) {
        var txnId = "a.transaction.id";
        var path = "/send/m.room.encrypted/" + txnId;
        httpBackend.when("PUT", path).respond(200, function(path, content) {
            aliMessage = content;
            expect(aliMessage.ciphertext[bobDeviceCurve25519Key]).toBeDefined();
            return {};
        });
        aliClient.sendMessage(
            roomId, {msgtype: "m.text", body: "Hello, World"}, txnId
        );
        httpBackend.flush().done(function() {done();});
    }

    it("Ali sends a message", function(done) {
        bobUploadsKeys(function() {
            aliDownloadsKeys(function() {
                aliEnablesEncryption(function() {
                    aliSendsMessage(done);
                });
            });
        });
    });

    function bobRecvMessage(done) {
        var initialSync = {
            end: "alpha",
            presence: [],
            rooms: []
        };
        var events = {
            start: "alpha",
            end: "beta",
            chunk: [utils.mkEvent({
                type: "m.room.encrypted",
                room: roomId,
                content: aliMessage
            })]
        };
        httpBackend.when("GET", "initialSync").respond(200, initialSync);
        httpBackend.when("GET", "events").respond(200, events);
        bobClient.on("event", function(event) {
            expect(event.getType()).toEqual("m.room.message");
            expect(event.getContent()).toEqual({
                msgtype: "m.text",
                body: "Hello, World"
            });
            done();
        });
        bobClient.startClient();
    }

    it("Bob receives a message", function(done) {
        bobUploadsKeys(function() {
            aliDownloadsKeys(function() {
                aliEnablesEncryption(function() {
                    aliSendsMessage(function() {
                        bobRecvMessage(done);
                    });
                });
            });
        });
    }, 30000); //timeout after 30s

});
<commit_msg>Flush the httpBackend in the last crypto test<commit_after>"use strict";
var sdk = require("../..");
var HttpBackend = require("../mock-request");
var utils = require("../test-utils");
function MockStorageApi() {
    this.data = {};
}
MockStorageApi.prototype = {
    setItem: function(k, v) {
        this.data[k] = v;
    },
    getItem: function(k) {
        return this.data[k] || null;
    },
    removeItem: function(k) {
        delete this.data[k];
    }
};

describe("MatrixClient crypto", function() {
    var baseUrl = "http://localhost.or.something";
    var httpBackend;
    var aliClient;
    var roomId = "!room:localhost";
    var aliUserId = "@ali:localhost";
    var aliDeviceId = "zxcvb";
    var aliAccessToken = "aseukfgwef";
    var bobClient;
    var bobUserId = "@bob:localhost";
    var bobDeviceId = "bvcxz";
    var bobAccessToken = "fewgfkuesa";
    var bobOneTimeKeys;
    var bobDeviceKeys;
    var bobDeviceCurve25519Key;
    var aliLocalStore;
    var aliStorage;
    var bobStorage;
    var aliMessage;

    beforeEach(function() {
        aliLocalStore = new MockStorageApi();
        aliStorage = new sdk.WebStorageSessionStore(aliLocalStore);
        bobStorage = new sdk.WebStorageSessionStore(new MockStorageApi());
        utils.beforeEach(this);
        httpBackend = new HttpBackend();
        sdk.request(httpBackend.requestFn);

        aliClient = sdk.createClient({
            baseUrl: baseUrl,
            userId: aliUserId,
            accessToken: aliAccessToken,
            deviceId: aliDeviceId,
            sessionStore: aliStorage
        });

        bobClient = sdk.createClient({
            baseUrl: baseUrl,
            userId: bobUserId,
            accessToken: bobAccessToken,
            deviceId: bobDeviceId,
            sessionStore: bobStorage
        });

        httpBackend.when("GET", "/pushrules").respond(200, {});
    });

    describe("Ali account setup", function() {
        it("should have device keys", function(done) {
            expect(aliClient.deviceKeys).toBeDefined();
            expect(aliClient.deviceKeys.user_id).toEqual(aliUserId);
            expect(aliClient.deviceKeys.device_id).toEqual(aliDeviceId);
            done();
        });
        it("should have a curve25519 key", function(done) {
            expect(aliClient.deviceCurve25519Key).toBeDefined();
            done();
        });
    });

    function bobUploadsKeys(done) {
        var uploadPath = "/keys/upload/bvcxz";
        httpBackend.when("POST", uploadPath).respond(200, function(path, content) {
            expect(content.one_time_keys).toEqual({});
            httpBackend.when("POST", uploadPath).respond(200, function(path, content) {
                expect(content.one_time_keys).not.toEqual({});
                bobDeviceKeys = content.device_keys;
                bobOneTimeKeys = content.one_time_keys;
                var count = 0;
                for (var key in content.one_time_keys) {
                    if (content.one_time_keys.hasOwnProperty(key)) {
                        count++;
                    }
                }
                expect(count).toEqual(5);
                return {one_time_key_counts: {curve25519: count}};
            });
            return {one_time_key_counts: {}};
        });
        bobClient.uploadKeys(5);
        httpBackend.flush().done(function() {
            expect(bobDeviceKeys).toBeDefined();
            expect(bobOneTimeKeys).toBeDefined();
            bobDeviceCurve25519Key = bobDeviceKeys.keys["curve25519:bvcxz"];
            done();
        });
    }

    it("Bob uploads without one-time keys and with one-time keys", bobUploadsKeys);

    function aliDownloadsKeys(done) {
        var bobKeys = {};
        bobKeys[bobDeviceId] = bobDeviceKeys;
        httpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
            expect(content.device_keys[bobUserId]).toEqual({});
            var result = {};
            result[bobUserId] = bobKeys;
            return {device_keys: result};
        });
        aliClient.downloadKeys([bobUserId]);
        httpBackend.flush().done(function() {
            var devices = aliStorage.getEndToEndDevicesForUser(bobUserId);
            expect(devices).toEqual(bobKeys);
            done();
        });
    }

    it("Ali downloads Bobs keys", function(done) {
        bobUploadsKeys(function() {aliDownloadsKeys(done);});
    });

    function aliEnablesEncryption(done) {
        httpBackend.when("POST", "/keys/claim").respond(200, function(path, content) {
            expect(content.one_time_keys[bobUserId][bobDeviceId]).toEqual("curve25519");
            for (var keyId in bobOneTimeKeys) {
                if (bobOneTimeKeys.hasOwnProperty(keyId)) {
                    if (keyId.indexOf("curve25519:") === 0) {
                        break;
                    }
                }
            }
            var result = {};
            result[bobUserId] = {};
            result[bobUserId][bobDeviceId] = {};
            result[bobUserId][bobDeviceId][keyId] = bobOneTimeKeys[keyId];
            return {one_time_keys: result};
        });
        aliClient.setRoomEncryption(roomId, {
            algorithm: "m.olm.v1.curve25519-aes-sha2",
            members: [aliUserId, bobUserId]
        }).then(function(res) {
            expect(res.missingUsers).toEqual([]);
            expect(res.missingDevices).toEqual({});
            done();
        });
        httpBackend.flush();
    }

    it("Ali enables encryption", function(done) {
        bobUploadsKeys(function() {
            aliDownloadsKeys(function() {
                aliEnablesEncryption(done);
            });
        });
    });

    function aliSendsMessage(done) {
        var txnId = "a.transaction.id";
        var path = "/send/m.room.encrypted/" + txnId;
        httpBackend.when("PUT", path).respond(200, function(path, content) {
            aliMessage = content;
            expect(aliMessage.ciphertext[bobDeviceCurve25519Key]).toBeDefined();
            return {};
        });
        aliClient.sendMessage(
            roomId, {msgtype: "m.text", body: "Hello, World"}, txnId
        );
        httpBackend.flush().done(function() {done();});
    }

    it("Ali sends a message", function(done) {
        bobUploadsKeys(function() {
            aliDownloadsKeys(function() {
                aliEnablesEncryption(function() {
                    aliSendsMessage(done);
                });
            });
        });
    });

    function bobRecvMessage(done) {
        var initialSync = {
            end: "alpha",
            presence: [],
            rooms: []
        };
        var events = {
            start: "alpha",
            end: "beta",
            chunk: [utils.mkEvent({
                type: "m.room.encrypted",
                room: roomId,
                content: aliMessage
            })]
        };
        httpBackend.when("GET", "initialSync").respond(200, initialSync);
        httpBackend.when("GET", "events").respond(200, events);
        bobClient.on("event", function(event) {
            expect(event.getType()).toEqual("m.room.message");
            expect(event.getContent()).toEqual({
                msgtype: "m.text",
                body: "Hello, World"
            });
            done();
        });
        bobClient.startClient();
        httpBackend.flush();
    }

    it("Bob receives a message", function(done) {
        bobUploadsKeys(function() {
            aliDownloadsKeys(function() {
                aliEnablesEncryption(function() {
                    aliSendsMessage(function() {
                        bobRecvMessage(done);
                    });
                });
            });
        });
    }, 30000); //timeout after 30s

});
<|endoftext|>


<commit_before>/* Adapted from https://gist.github.com/299789 */

/* Ismael Celis 2010
Simplified WebSocket events dispatcher (no channels, no users)

var socket = new FancyWebSocket();

// bind to server events
socket.bind('some_event', function(data){
  alert(data.name + ' says: ' + data.message)
});

// broadcast events to all connected users
socket.send( 'some_event', {name: 'ismael', message : 'Hello world'} );

WebSocket onopen/onclose events are mapped to the 'open'/'close' event channels.

The server has to send websocket data of form
  JSON.stringify({ event: EVENT_NAME, data: DATA })
*/

define(['jsschema', 'schemas'], function(_, schemas) {
  return {
    FancyWebSocket: function(url) {
      if (typeof WebSocket !== 'undefined') {
        var conn = new WebSocket(url);
      } else if (typeof MozWebSocket !== 'undefined') {
        var conn = new MozWebSocket(url);
      } else {
        throw 'WebSocket seems to not be supported by this browser!';
      }

      var callbacks = {};
      var defaultCallback = function(_) { };

      this.bind = function(event_name, callback) {
        callbacks[event_name] = callbacks[event_name] || [];
        callbacks[event_name].push(callback);
        return this; // chainable
      };

      this.bindMethod = function(method_name, okCallback, errorCallback) {
        this.bind(method_name + ".ok", okCallback);
        this.bind(method_name + ".error", errorCallback);
      };

      this.bindDefault = function(callback) {
        defaultCallback = callback;
      }

      this.send = function(event_name, event_data) {
        var payload = JSON.stringify({event:event_name, data: event_data});
        conn.send(payload); // <= send JSON data to socket server
        return this;
      };

      this.close = function() {
        conn.close();
      }

      this.inject = function (event_name, message) {
        console.log("Receiving injected message from socket on channel '" + channel +"': ", message);
        dispatch(event_name, message);
      }

      // dispatch to the right handlers
      conn.onmessage = function(evt) {
        var json = JSON.parse(evt.data);

        // not an event, throw exception
        if (!jsschema.valid(schemas.event, json))
          throw new Error("received object that is not an event, ignoring: " + JSON.stringify(evt.data));

        var eventName = json.event;
        var eventData = json.data;

        // not a defined schema: warn but permit
        var eventSchema = schemas.events[eventName];
        if (eventSchema === undefined)
          console.error("Warning: received object without defined schema on event '" + eventName + "': ", eventData, " received JSON: ", json);
        else if (!jsschema.valid(eventSchema, eventData))
          console.error("Warning: received object ", eventData, " does not mach declared schema ", eventSchema, "for event '" + eventName + "'; received JSON: ", json);

        dispatch(eventName, eventData);
      };

      conn.onclose = function() {
        dispatch('close',null);
      };

      conn.onopen = function() {
        dispatch('open',null);
      };

      var dispatch = function(event_name, message) {
        var chain = callbacks[event_name];
        if (typeof chain == 'undefined') {
          if (typeof defaultCallback != 'undefined') {
            defaultCallback(event_name, message);
          }
          return; // no callbacks for this event
        }
        for(var i = 0; i < chain.length; i++) {
          chain[i](message);
        }
      }
    }

  }

});
<commit_msg>Fix injection<commit_after>/* Adapted from https://gist.github.com/299789 */

/* Ismael Celis 2010
Simplified WebSocket events dispatcher (no channels, no users)

var socket = new FancyWebSocket();

// bind to server events
socket.bind('some_event', function(data){
  alert(data.name + ' says: ' + data.message)
});

// broadcast events to all connected users
socket.send( 'some_event', {name: 'ismael', message : 'Hello world'} );

WebSocket onopen/onclose events are mapped to the 'open'/'close' event channels.

The server has to send websocket data of form
  JSON.stringify({ event: EVENT_NAME, data: DATA })
*/

define(['jsschema', 'schemas'], function(_, schemas) {
  return {
    FancyWebSocket: function(url) {
      if (typeof WebSocket !== 'undefined') {
        var conn = new WebSocket(url);
      } else if (typeof MozWebSocket !== 'undefined') {
        var conn = new MozWebSocket(url);
      } else {
        throw 'WebSocket seems to not be supported by this browser!';
      }

      var callbacks = {};
      var defaultCallback = function(_) { };

      this.bind = function(event_name, callback) {
        callbacks[event_name] = callbacks[event_name] || [];
        callbacks[event_name].push(callback);
        return this; // chainable
      };

      this.bindMethod = function(method_name, okCallback, errorCallback) {
        this.bind(method_name + ".ok", okCallback);
        this.bind(method_name + ".error", errorCallback);
      };

      this.bindDefault = function(callback) {
        defaultCallback = callback;
      }

      this.send = function(event_name, event_data) {
        var payload = JSON.stringify({event:event_name, data: event_data});
        conn.send(payload); // <= send JSON data to socket server
        return this;
      };

      this.close = function() {
        conn.close();
      }

      this.inject = function (event_name, message) {
        console.log("Receiving injected message from socket on channel '" + event_name +"': ", message);
        dispatch(event_name, message);
      }

      // dispatch to the right handlers
      conn.onmessage = function(evt) {
        var json = JSON.parse(evt.data);

        // not an event, throw exception
        if (!jsschema.valid(schemas.event, json))
          throw new Error("received object that is not an event, ignoring: " + JSON.stringify(evt.data));

        var eventName = json.event;
        var eventData = json.data;

        // not a defined schema: warn but permit
        var eventSchema = schemas.events[eventName];
        if (eventSchema === undefined)
          console.error("Warning: received object without defined schema on event '" + eventName + "': ", eventData, " received JSON: ", json);
        else if (!jsschema.valid(eventSchema, eventData))
          console.error("Warning: received object ", eventData, " does not mach declared schema ", eventSchema, "for event '" + eventName + "'; received JSON: ", json);

        dispatch(eventName, eventData);
      };

      conn.onclose = function() {
        dispatch('close',null);
      };

      conn.onopen = function() {
        dispatch('open',null);
      };

      var dispatch = function(event_name, message) {
        var chain = callbacks[event_name];
        if (typeof chain == 'undefined') {
          if (typeof defaultCallback != 'undefined') {
            defaultCallback(event_name, message);
          }
          return; // no callbacks for this event
        }
        for(var i = 0; i < chain.length; i++) {
          chain[i](message);
        }
      }
    }

  }

});
<|endoftext|>


<commit_before>import React from 'react';
import { Component, PropTypes } from '../utils/';

function toArray(activeKey) {
  let currentActiveKey = activeKey;
  if (!Array.isArray(currentActiveKey)) {
    currentActiveKey = currentActiveKey ? [currentActiveKey] : [];
  }
  return currentActiveKey;
}

export default class Collapse extends Component {
  constructor(props) {
    super(props)
    this.state = {
      activeKey: toArray(props.activeKey)
    }
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.activeKey !== this.props.activeKey) {
      this.setState({ activeKey: toArray(nextProps.activeKey) })
    }
  }
  onItemClick(key) {
    let activeKey = this.state.activeKey;
    if (this.props.accordion) {
      activeKey = activeKey[0] === key ? [] : [key];
    } else {
      activeKey = [...activeKey];
      const index = activeKey.indexOf(key);
      const isActive = index > -1;
      if (isActive) {
        activeKey.splice(index, 1);
      } else {
        activeKey.push(key);
      }
    }
    this.setState({ activeKey });
  }
  render() {
    const { prefixCls, className, children, accordion, bordered, activeKey, showArrow, ...resetProps } = this.props;
    const cls = this.classNames(prefixCls, className, {
      'no-border': bordered
    })
    return (

        {React.Children.map(children, (child, index) => {
          // 如果没有密钥提供，请使用面板顺序作为默认密钥
          const key = child.key || String(index);
          const { disabled } = child.props;
          let activeKey = this.state.activeKey;
          let isActive = false;
          if (accordion) {// 手风琴模式下默认选择第一个
            isActive = activeKey[0] === key;
          } else {
            isActive = activeKey.indexOf(key) > -1;
          }
          let childProps = {
            prefixCls: prefixCls,
            isActive: isActive,
            disabled: disabled,
            showArrow: showArrow,
            onItemClick: disabled ? () => { } : () => this.onItemClick(key),
            ...child.props
          }
          return React.cloneElement(child, childProps)
        })}

    )
  }
}

Collapse.propTypes = {
  prefixCls: PropTypes.string,
  accordion: PropTypes.bool,
  showArrow: PropTypes.bool,
  activeKey: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.arrayOf(PropTypes.string),
  ]),
}

Collapse.defaultProps = {
  prefixCls: 'w-collapse',
  accordion: false,
  showArrow: true,
}
<commit_msg>Collapse component to add onChange event.<commit_after>import React from 'react';
import { Component, PropTypes } from '../utils/';

function toArray(activeKey) {
  let currentActiveKey = activeKey;
  if (!Array.isArray(currentActiveKey)) {
    currentActiveKey = currentActiveKey ? [currentActiveKey] : [];
  }
  return currentActiveKey;
}

export default class Collapse extends Component {
  constructor(props) {
    super(props)
    this.state = {
      activeKey: toArray(props.activeKey)
    }
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.activeKey !== this.props.activeKey) {
      this.setState({ activeKey: toArray(nextProps.activeKey) })
    }
  }
  onItemClick(key) {
    const { onChange } = this.props;
    let activeKey = this.state.activeKey;
    if (this.props.accordion) {
      activeKey = activeKey[0] === key ? [] : [key];
    } else {
      activeKey = [...activeKey];
      const index = activeKey.indexOf(key);
      const isActive = index > -1;
      if (isActive) {
        activeKey.splice(index, 1);
      } else {
        activeKey.push(key);
      }
    }
    this.setState({ activeKey }, () => {
      onChange && onChange(activeKey, this.props)
    });
  }
  render() {
    const { prefixCls, className, children, accordion, bordered, activeKey, showArrow, ...resetProps } = this.props;
    const cls = this.classNames(prefixCls, className, {
      'no-border': bordered
    })
    return (

        {React.Children.map(children, (child, index) => {
          // 如果没有密钥提供，请使用面板顺序作为默认密钥
          const key = child.key || String(index);
          const { disabled } = child.props;
          let activeKey = this.state.activeKey;
          let isActive = false;
          if (accordion) {// 手风琴模式下默认选择第一个
            isActive = activeKey[0] === key;
          } else {
            isActive = activeKey.indexOf(key) > -1;
          }
          let childProps = {
            prefixCls: prefixCls,
            isActive: isActive,
            disabled: disabled,
            showArrow: showArrow,
            onItemClick: disabled ? () => { } : () => this.onItemClick(key),
            ...child.props
          }
          return React.cloneElement(child, childProps)
        })}

    )
  }
}

Collapse.propTypes = {
  prefixCls: PropTypes.string,
  accordion: PropTypes.bool,
  showArrow: PropTypes.bool,
  onChange: PropTypes.func,
  activeKey: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.arrayOf(PropTypes.string),
  ]),
}

Collapse.defaultProps = {
  prefixCls: 'w-collapse',
  accordion: false,
  showArrow: true,
}
<|endoftext|>


<commit_before>configGetLanguage = function() {
	return i18n.getLanguage();
}

var us_example = "beautiful, love, blessed, kind, guilty, free";
var br_example = "feliz, amor, linda, lindo, culpada, culpado";
var lang_en_US = {
	projectDescription : {
		title : 'How are you feeling?',
		text : '\

 \
			Me Sinto visualizes people\'s feelings in real time, as they are \
			shared on Twitter. It is easy. \
			Just type in one or more feeling words and hit enter. You will see tweets \
			of people sharing similar feelings. \

',
		example : '\

 \
			 \
			Example: ' + us_example + '  \

',
		ex : us_example
	},
	language : "Mudar para Português",
	appName : "Me Sinto",
	headlineQuestion : "How are you feeling?",
	searchBarPlaceholder : "I Feel",
	about : "About",
	background : {
		title : "Background",
		text : '\

 \
				Me Sinto was based on the 2006 project We Feel Fine, by Jonathas Harris. Harris seizes the state of mind of people by searching the internet for feelings, specifically, blog posts with sentences starting with I feel and I\'m felling. We Feel Fine shows a number of carefully crafted infographics and beautiful image compositions. \
				We Feel Fine has also inspired other similar projects.\

 \

 \
				Me Sinto applies the same idea in the era of Twitter. The staggering number of users sharing their hearts on social media makes a project like this much faster to execute. Here we show what people feel in real-time. \

'
	},
	tutorial : {
		title : "What are those bars and circles?",
		text : '\

\
				To get started, you must type-in a word that the completes the sentence "I feel ...". We will show recent tweets of people describing similar feelings. Each circle is a tweet somebody recently tweeted. Click on them to see what they are about. The tweets fall into one of the bars and, from time to time, the circles are aggregated to the bar. When aggregation happens, the height of each bar changes. The higher the bar, the more tweets about that feeling. The shorter, less tweets. Each bar is associated with a word you typed-in. So if you type "Sad" and "Happy" you will see how many people feel happy and sad at that moment. You can also click on the twitter handle of a particular user to see their message on the Twitter website. \

'
	},
	developedBy : 'Developed by Tiago Etiene | tiago.etiene@gmail.com',
	builtWith : '\

\
			Built with Meteor | Visual Sedimentation | D3 | chom\

',
	close : "Close",
	loading : "Loading tweets...",
	clear : "Clear Selection",
};
var lang_pt_BR = {
	projectDescription : {
		title : 'Como você se sente?',
		text : '\

 \
			Me Sinto visualiza o sentimento que as pessoas expressam nas \
			redes sociais em tempo real. É bem simples. \
			Digite uma ou mais palavas que descrevem um sentimento e pressione enter. \
			Você verá tuítes de pessoas que compartilham sentimentos similares. \

',
		example : '\

 \
			 \
			Exemplo: ' + br_example + '  \

',
		ex : br_example
	},
	language : "Switch to english",
	appName : "Me Sinto",
	headlineQuestion : "Como você se sente?",
	searchBarPlaceholder : "Eu me sinto",
	about : "Sobre",
	background : {
		title : "História",
		text : '\

 \
				Me Sinto é inspirado no projeto We Feel Fine, por Jonathas Harris. Harris captura o sentimento das pessoas procurando por textos e sentenças na web que contém as palavras Eu me sinto and Eu estou sentindo. We Feel Fine mostra vários infográfico - cuidadosamente construídos - e belas composições com fotos escolhidas por usuários. \
				We Feel Fine serve como fonto de inspiração para vários outros projetos. \

 \

 \
				Me Sinto applica a mesma idéia na era do Twitter. Hoje em dia, um número incrível de pessoas compartilham seus sentimentos nas redes sociais. Isso permite que projetos como esse sejam colocados em prática muito mais rapidamente. Aqui mostramos o que as pessoas sentem em tempo real. \

'
	},
	tutorial : {
		title : 'O que são essas barras e círculos?',
		text : '\

\
				Para começar, você digita uma palavra que complete a sentença "Eu me sinto ...". Em seguir, mostramos tweets de outras pessoas que descrevem sentimentos similares aos seus. Cada círculo é um tweet que alguém em algum lugar tuítou. Clique neles para ver o que eles dizem. Os tweets caem em cima de barras e, de tempos em tempos, eles são agregados à barra. Quando isso acontece, a altura da barra muda. Quanto mais alta a barra, mais tweets a respeito daquele sentimento. Cada barra está associada com umas das palavras digitadas. Sendo assim, se você digitar "Triste" e "Feliz", você verá quantas pessoas se sentem felizes e tristes naquele mommento. Você também pode clicar no nome do usuário para ver o autor do tweet no site do Twitter. \

'
	},
	developedBy : 'Desenvolvido por Tiago Etiene | tiago.etiene@gmail.com',
	builtWith : 'Construído usando Meteor | Visual Sedimentation | D3 | chom',
	close : "Fechar",
	loading : "Carregando tuítes",
	clear : "Limpar busca",
};

var currentLanguage;
configInternationalization = function() {

	i18n.map('en-us', lang_en_US);
	i18n.map('en', lang_en_US);
	i18n.map('pt', lang_pt_BR);
	i18n.map('pt-br', lang_pt_BR);
	i18n.map('pt_br', lang_pt_BR);
	i18n.map('pt_BR', lang_pt_BR);

	currentLanguage = navigator.language.toLowerCase()
	i18n.setLanguage( currentLanguage );
	// i18n.setLanguage('pt-br');
	// i18n.setDefaultLanguage('en_US');
	i18n.showMissing('[no translation for "<%= label %>" in <%= language %>]');
}

switchLanguage = function() {
	if( _.isEqual( currentLanguage, "en" ) || _.isEqual( currentLanguage, "en-us" ) ) {
		currentLanguage = "pt";
		i18n.setLanguage( currentLanguage );
	} else {
		currentLanguage = "en";
		i18n.setLanguage( currentLanguage );
	}
}
<commit_msg>Fixed caps<commit_after>configGetLanguage = function() {
	return i18n.getLanguage();
}

var us_example = "beautiful, love, blessed, kind, guilty, free";
var br_example = "feliz, amor, linda, lindo, culpada, culpado";
var lang_en_US = {
	projectDescription : {
		title : 'How are you feeling?',
		text : '\

 \
			Me Sinto visualizes people\'s feelings in real time, as they are \
			shared on Twitter. It is easy. \
			Just type in one or more feeling words and hit enter. You will see tweets \
			of people sharing similar feelings. \

',
		example : '\

 \
			 \
			Example: ' + us_example + '  \

',
		ex : us_example
	},
	language : "Mudar para português",
	appName : "Me Sinto",
	headlineQuestion : "How are you feeling?",
	searchBarPlaceholder : "I Feel",
	about : "About",
	background : {
		title : "Background",
		text : '\

 \
				Me Sinto was based on the 2006 project We Feel Fine, by Jonathas Harris. Harris seizes the state of mind of people by searching the internet for feelings, specifically, blog posts with sentences starting with I feel and I\'m felling. We Feel Fine shows a number of carefully crafted infographics and beautiful image compositions. \
				We Feel Fine has also inspired other similar projects.\

 \

 \
				Me Sinto applies the same idea in the era of Twitter. The staggering number of users sharing their hearts on social media makes a project like this much faster to execute. Here we show what people feel in real-time. \

'
	},
	tutorial : {
		title : "What are those bars and circles?",
		text : '\

\
				To get started, you must type-in a word that the completes the sentence "I feel ...". We will show recent tweets of people describing similar feelings. Each circle is a tweet somebody recently tweeted. Click on them to see what they are about. The tweets fall into one of the bars and, from time to time, the circles are aggregated to the bar. When aggregation happens, the height of each bar changes. The higher the bar, the more tweets about that feeling. The shorter, less tweets. Each bar is associated with a word you typed-in. So if you type "Sad" and "Happy" you will see how many people feel happy and sad at that moment. You can also click on the twitter handle of a particular user to see their message on the Twitter website. \

'
	},
	developedBy : 'Developed by Tiago Etiene | tiago.etiene@gmail.com',
	builtWith : '\

\
			Built with Meteor | Visual Sedimentation | D3 | chom\

',
	close : "Close",
	loading : "Loading tweets...",
	clear : "Clear Selection",
};
var lang_pt_BR = {
	projectDescription : {
		title : 'Como você se sente?',
		text : '\

 \
			Me Sinto visualiza o sentimento que as pessoas expressam nas \
			redes sociais em tempo real. É bem simples. \
			Digite uma ou mais palavas que descrevem um sentimento e pressione enter. \
			Você verá tuítes de pessoas que compartilham sentimentos similares. \

',
		example : '\

 \
			 \
			Exemplo: ' + br_example + '  \

',
		ex : br_example
	},
	language : "Switch to english",
	appName : "Me Sinto",
	headlineQuestion : "Como você se sente?",
	searchBarPlaceholder : "Eu me sinto",
	about : "Sobre",
	background : {
		title : "História",
		text : '\

 \
				Me Sinto é inspirado no projeto We Feel Fine, por Jonathas Harris. Harris captura o sentimento das pessoas procurando por textos e sentenças na web que contém as palavras Eu me sinto and Eu estou sentindo. We Feel Fine mostra vários infográfico - cuidadosamente construídos - e belas composições com fotos escolhidas por usuários. \
				We Feel Fine serve como fonto de inspiração para vários outros projetos. \

 \

 \
				Me Sinto applica a mesma idéia na era do Twitter. Hoje em dia, um número incrível de pessoas compartilham seus sentimentos nas redes sociais. Isso permite que projetos como esse sejam colocados em prática muito mais rapidamente. Aqui mostramos o que as pessoas sentem em tempo real. \

'
	},
	tutorial : {
		title : 'O que são essas barras e círculos?',
		text : '\

\
				Para começar, você digita uma palavra que complete a sentença "Eu me sinto ...". Em seguir, mostramos tweets de outras pessoas que descrevem sentimentos similares aos seus. Cada círculo é um tweet que alguém em algum lugar tuítou. Clique neles para ver o que eles dizem. Os tweets caem em cima de barras e, de tempos em tempos, eles são agregados à barra. Quando isso acontece, a altura da barra muda. Quanto mais alta a barra, mais tweets a respeito daquele sentimento. Cada barra está associada com umas das palavras digitadas. Sendo assim, se você digitar "Triste" e "Feliz", você verá quantas pessoas se sentem felizes e tristes naquele mommento. Você também pode clicar no nome do usuário para ver o autor do tweet no site do Twitter. \

'
	},
	developedBy : 'Desenvolvido por Tiago Etiene | tiago.etiene@gmail.com',
	builtWith : 'Construído usando Meteor | Visual Sedimentation | D3 | chom',
	close : "Fechar",
	loading : "Carregando tuítes",
	clear : "Limpar busca",
};

var currentLanguage;
configInternationalization = function() {

	i18n.map('en-us', lang_en_US);
	i18n.map('en', lang_en_US);
	i18n.map('pt', lang_pt_BR);
	i18n.map('pt-br', lang_pt_BR);
	i18n.map('pt_br', lang_pt_BR);
	i18n.map('pt_BR', lang_pt_BR);

	currentLanguage = navigator.language.toLowerCase()
	i18n.setLanguage( currentLanguage );
	// i18n.setLanguage('pt-br');
	// i18n.setDefaultLanguage('en_US');
	i18n.showMissing('[no translation for "<%= label %>" in <%= language %>]');
}

switchLanguage = function() {
	if( _.isEqual( currentLanguage, "en" ) || _.isEqual( currentLanguage, "en-us" ) ) {
		currentLanguage = "pt";
		i18n.setLanguage( currentLanguage );
	} else {
		currentLanguage = "en";
		i18n.setLanguage( currentLanguage );
	}
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

// TODO: Add text for sudo block reason
require('sudo-block')()

const spawn = require('cross-spawn')
const path = require('path')
const chalk = require('chalk')
const fs = require('fs-extra')
const os = require('os')
const createDebug = require('debug')
const globalPrefix = require('global-prefix')
const { CONFIGURATION_PATH, CLI_PLUGIN_NAME, CWD, LOCAL_VERSION_PATH, PACKAGE_JSON_PATH } = require('../src/constants')

const RunPluginScriptCommand = require('../src/commands/runPluginScript')
const CreateProjectCommand = require('../src/commands/createProject')
const AddPluginsCommand = require('../src/commands/addPlugins')
const RemovePluginsCommand = require('../src/commands/removePlugins')
const UpdatePluginsCommand = require('../src/commands/updatePlugins')
const GenerateCommand = require('../src/commands/generate')
const CommitCommand = require('../src/commands/commit')
const AssembleCommand = require('../src/commands/assemble')
const CleanCacheCommand = require('../src/commands/cleanCache')
const ReleaseCommand = require('../src/commands/release')

const commands = [
  RunPluginScriptCommand,
  CreateProjectCommand,
  AddPluginsCommand,
  RemovePluginsCommand,
  UpdatePluginsCommand,
  GenerateCommand,
  CommitCommand,
  AssembleCommand,
  ReleaseCommand,
  CleanCacheCommand,
]

const logError = createDebug('rispa:error:cli')

const handleError = e => {
  logError(e)
  if (e.errors) {
    e.errors.forEach(error => logError(error))
  }
  if (e.context) {
    logError('Context:')
    logError(e.context)
  }
  process.exit(1)
}

const parseArgs = args => {
  const paramRegExp = /^--([^=]+)=(.*)/
  const argv = args.filter(arg => !paramRegExp.test(arg))

  const params = args.reduce((result, arg) => {
    const paramMatch = paramRegExp.exec(arg)
    if (paramMatch) {
      try {
        result[paramMatch[1]] = JSON.parse(paramMatch[2])
      } catch (e) {
        result[paramMatch[1]] = paramMatch[2]
      }
    }
    return result
  }, {})

  return [argv, params]
}

const runCommand = ([firstArg = '', ...args]) => {
  let Command = commands.find(command => command.commandName === firstArg)
  if (!Command) {
    Command = RunPluginScriptCommand
    args.unshift(firstArg)
  }

  const [argv, params] = parseArgs(args)

  const command = new Command(argv)
  command.init()
  command.run(Object.assign(params, {
    cwd: CWD,
  })).catch(handleError)
}

const getYarnPrefix = () => {
  // Source: https://github.com/yarnpkg/yarn/blob/3901ba4e17edf0a835fb17a42e4da15238d6cd58/src/constants.js#L60
  if (process.platform === 'win32' && process.env.LOCALAPPDATA) {
    return path.join(process.env.LOCALAPPDATA, 'Yarn', 'config', 'global')
  }

  return path.join(os.homedir(), 'config', 'yarn', 'global')
}

const inGlobalYarn = fullpath => fullpath.indexOf(getYarnPrefix()) === 0

const inGlobalNpm = fullpath => fullpath.indexOf(globalPrefix) === 0

const isGlobalRun = () => {
  const execPath = fs.realpathSync(process.argv[1])

  return inGlobalNpm(execPath) || inGlobalYarn(execPath)
}

const canRunLocalVersion = () => {
  const packageJsonPath = path.resolve(CWD, PACKAGE_JSON_PATH)

  if (!fs.existsSync(packageJsonPath)) {
    return false
  }

  const { dependencies = {}, devDependencies = {} } = fs.readJsonSync(packageJsonPath)

  const deps = Object.keys(dependencies).concat(Object.keys(devDependencies))
  if (deps.indexOf('@rispa/cli') !== -1) {
    if (fs.existsSync(LOCAL_VERSION_PATH)) {
      return true
    }

    console.log(chalk.red(`Can't find local version of CLI in ${chalk.cyan('node_modules')}`))
    process.exit(1)
  }

  return false
}

const readLocalPluginPath = () => {
  const rispaJsonPath = path.resolve(CWD, CONFIGURATION_PATH)
  const { pluginsPath } = fs.readJsonSync(rispaJsonPath)

  const pluginPackageJsonPath = path.resolve(CWD, pluginsPath, CLI_PLUGIN_NAME, PACKAGE_JSON_PATH)
  const { bin = {} } = fs.readJsonSync(pluginPackageJsonPath)

  return path.resolve(CWD, pluginsPath, CLI_PLUGIN_NAME, bin.ris)
}

const pluginBinExists = pluginPath => {
  const pluginPackageJsonPath = path.resolve(CWD, pluginPath, PACKAGE_JSON_PATH)

  if (!fs.existsSync(pluginPackageJsonPath)) {
    return false
  }

  const { bin = {} } = fs.readJsonSync(pluginPackageJsonPath)
  if (!bin.ris) {
    return false
  }

  return fs.existsSync(path.resolve(CWD, pluginPath, bin.ris))
}

const canRunPlugin = () => {
  const rispaJsonPath = path.resolve(CWD, CONFIGURATION_PATH)

  if (!fs.existsSync(rispaJsonPath)) {
    return false
  }

  const { plugins = [], pluginsPath } = fs.readJsonSync(rispaJsonPath)

  if (plugins.indexOf(CLI_PLUGIN_NAME) !== -1) {
    if (pluginBinExists(path.join(pluginsPath, CLI_PLUGIN_NAME))) {
      return true
    }

    console.log(chalk.red(`Can't find local version of CLI in ${chalk.cyan(pluginsPath)}`))
    process.exit(1)
  }

  return false
}

const runLocalVersion = (execPath, args) => {
  console.log(chalk.bold.green('Switch to use local version'))

  const result = spawn.sync(
    execPath,
    args,
    {
      cwd: process.cwd(),
      stdio: 'inherit',
    }
  ).status

  process.exit(result)
}

const args = process.argv.slice(2)

const globalRun = isGlobalRun()

if (globalRun && canRunLocalVersion()) {
  // Run local version from node_modules directly - on Windows it will be shell script, on other systems - js file with execute permission
  runLocalVersion(LOCAL_VERSION_PATH, args)
} else if (globalRun && canRunPlugin()) {
  // Run local version from plugin with node - on all systems it will be js file
  runLocalVersion('node', [readLocalPluginPath()].concat(args))
} else {
  runCommand(args)
}
<commit_msg>Fix path to yarn globals on non-Windows systems<commit_after>#!/usr/bin/env node

// TODO: Add text for sudo block reason
require('sudo-block')()

const spawn = require('cross-spawn')
const path = require('path')
const chalk = require('chalk')
const fs = require('fs-extra')
const os = require('os')
const createDebug = require('debug')
const globalPrefix = require('global-prefix')
const { CONFIGURATION_PATH, CLI_PLUGIN_NAME, CWD, LOCAL_VERSION_PATH, PACKAGE_JSON_PATH } = require('../src/constants')

const RunPluginScriptCommand = require('../src/commands/runPluginScript')
const CreateProjectCommand = require('../src/commands/createProject')
const AddPluginsCommand = require('../src/commands/addPlugins')
const RemovePluginsCommand = require('../src/commands/removePlugins')
const UpdatePluginsCommand = require('../src/commands/updatePlugins')
const GenerateCommand = require('../src/commands/generate')
const CommitCommand = require('../src/commands/commit')
const AssembleCommand = require('../src/commands/assemble')
const CleanCacheCommand = require('../src/commands/cleanCache')
const ReleaseCommand = require('../src/commands/release')

const commands = [
  RunPluginScriptCommand,
  CreateProjectCommand,
  AddPluginsCommand,
  RemovePluginsCommand,
  UpdatePluginsCommand,
  GenerateCommand,
  CommitCommand,
  AssembleCommand,
  ReleaseCommand,
  CleanCacheCommand,
]

const logError = createDebug('rispa:error:cli')

const handleError = e => {
  logError(e)
  if (e.errors) {
    e.errors.forEach(error => logError(error))
  }
  if (e.context) {
    logError('Context:')
    logError(e.context)
  }
  process.exit(1)
}

const parseArgs = args => {
  const paramRegExp = /^--([^=]+)=(.*)/
  const argv = args.filter(arg => !paramRegExp.test(arg))

  const params = args.reduce((result, arg) => {
    const paramMatch = paramRegExp.exec(arg)
    if (paramMatch) {
      try {
        result[paramMatch[1]] = JSON.parse(paramMatch[2])
      } catch (e) {
        result[paramMatch[1]] = paramMatch[2]
      }
    }
    return result
  }, {})

  return [argv, params]
}

const runCommand = ([firstArg = '', ...args]) => {
  let Command = commands.find(command => command.commandName === firstArg)
  if (!Command) {
    Command = RunPluginScriptCommand
    args.unshift(firstArg)
  }

  const [argv, params] = parseArgs(args)

  const command = new Command(argv)
  command.init()
  command.run(Object.assign(params, {
    cwd: CWD,
  })).catch(handleError)
}

const getYarnPrefix = () => {
  // Source: https://github.com/yarnpkg/yarn/blob/3901ba4e17edf0a835fb17a42e4da15238d6cd58/src/constants.js#L60
  if (process.platform === 'win32' && process.env.LOCALAPPDATA) {
    return path.join(process.env.LOCALAPPDATA, 'Yarn', 'config', 'global')
  }

  return path.join(os.homedir(), '.config', 'yarn', 'global')
}

const inGlobalYarn = fullpath => fullpath.indexOf(getYarnPrefix()) === 0

const inGlobalNpm = fullpath => fullpath.indexOf(globalPrefix) === 0

const isGlobalRun = () => {
  const execPath = fs.realpathSync(process.argv[1])

  return inGlobalNpm(execPath) || inGlobalYarn(execPath)
}

const canRunLocalVersion = () => {
  const packageJsonPath = path.resolve(CWD, PACKAGE_JSON_PATH)

  if (!fs.existsSync(packageJsonPath)) {
    return false
  }

  const { dependencies = {}, devDependencies = {} } = fs.readJsonSync(packageJsonPath)

  const deps = Object.keys(dependencies).concat(Object.keys(devDependencies))
  if (deps.indexOf('@rispa/cli') !== -1) {
    if (fs.existsSync(LOCAL_VERSION_PATH)) {
      return true
    }

    console.log(chalk.red(`Can't find local version of CLI in ${chalk.cyan('node_modules')}`))
    process.exit(1)
  }

  return false
}

const readLocalPluginPath = () => {
  const rispaJsonPath = path.resolve(CWD, CONFIGURATION_PATH)
  const { pluginsPath } = fs.readJsonSync(rispaJsonPath)

  const pluginPackageJsonPath = path.resolve(CWD, pluginsPath, CLI_PLUGIN_NAME, PACKAGE_JSON_PATH)
  const { bin = {} } = fs.readJsonSync(pluginPackageJsonPath)

  return path.resolve(CWD, pluginsPath, CLI_PLUGIN_NAME, bin.ris)
}

const pluginBinExists = pluginPath => {
  const pluginPackageJsonPath = path.resolve(CWD, pluginPath, PACKAGE_JSON_PATH)

  if (!fs.existsSync(pluginPackageJsonPath)) {
    return false
  }

  const { bin = {} } = fs.readJsonSync(pluginPackageJsonPath)
  if (!bin.ris) {
    return false
  }

  return fs.existsSync(path.resolve(CWD, pluginPath, bin.ris))
}

const canRunPlugin = () => {
  const rispaJsonPath = path.resolve(CWD, CONFIGURATION_PATH)

  if (!fs.existsSync(rispaJsonPath)) {
    return false
  }

  const { plugins = [], pluginsPath } = fs.readJsonSync(rispaJsonPath)

  if (plugins.indexOf(CLI_PLUGIN_NAME) !== -1) {
    if (pluginBinExists(path.join(pluginsPath, CLI_PLUGIN_NAME))) {
      return true
    }

    console.log(chalk.red(`Can't find local version of CLI in ${chalk.cyan(pluginsPath)}`))
    process.exit(1)
  }

  return false
}

const runLocalVersion = (execPath, args) => {
  console.log(chalk.bold.green('Switch to use local version'))

  const result = spawn.sync(
    execPath,
    args,
    {
      cwd: process.cwd(),
      stdio: 'inherit',
    }
  ).status

  process.exit(result)
}

const args = process.argv.slice(2)

const globalRun = isGlobalRun()

if (globalRun && canRunLocalVersion()) {
  // Run local version from node_modules directly - on Windows it will be shell script, on other systems - js file with execute permission
  runLocalVersion(LOCAL_VERSION_PATH, args)
} else if (globalRun && canRunPlugin()) {
  // Run local version from plugin with node - on all systems it will be js file
  runLocalVersion('node', [readLocalPluginPath()].concat(args))
} else {
  runCommand(args)
}
<|endoftext|>


<commit_before>module.exports = {
  config: {
    fontSize: 12,
    fontFamily: 'Menlo, DejaVu Sans Mono, Lucida Console, monospace',
    padding: '10px',
    cursorShape: 'BEAM',
    termCSS: `
      x-screen {
        -webkit-font-smoothing: subpixel-antialiased !important;
      }
    `,
  },
  plugins: [
    'hyper-one-light',
    'hypercwd',
    'hyper-blink',
  ],
};
<commit_msg>Enable copyOnSelect<commit_after>module.exports = {
  config: {
    fontSize: 12,
    fontFamily: 'Menlo, DejaVu Sans Mono, Lucida Console, monospace',
    padding: '10px',
    cursorShape: 'BEAM',
    termCSS: `
      x-screen {
        -webkit-font-smoothing: subpixel-antialiased !important;
      }
    `,
    copyOnSelect: true,
  },
  plugins: [
    'hyper-one-light',
    'hypercwd',
    'hyper-blink',
  ],
};
<|endoftext|>


<commit_before>
const core = require('./core'),
  nodeGetoptLong = require('node-getopt-long'),
  P = require('bluebird'),
  config = require('./config'),
  readline = require('readline'),
  logger = require('./logger')

const commands = {
  'list': list(),
  'create': create(),
  'run': run(),
  'ensure-no-development-scripts': ensureNoDevelopmentScripts()
}

P.try(async function () {
  const cmdLine = parseCommandLine()
  if (cmdLine.options.config) {
    config.setupConfig(require(cmdLine.options.config))
  } else {
    config.findAndLoadConfig()
  }
  await cmdLine.command.action(cmdLine.options)
}).catch(err => {
  if (!err.printed) {
    console.error(err.stack || err)
  }
  process.exit(1)
})

function parseCommandLine() {
  const command = process.argv[2]
  process.argv.splice(2, 1)
  let cmdImpl = commands[command]
  if (!cmdImpl) throw new Error('Invalid command: ' + command + '; available commands are ' + Object.keys(commands).join(', '))

  const defaultOptions = [[
    'config|conf|c=s', 'Configuration file'
  ]]

  const options = nodeGetoptLong.options((cmdImpl.options || []).concat(defaultOptions), {
    name: 'migsi'
  })

  return {
    command: cmdImpl,
    options
  }
}

function list() {
  return {
    options: [],
    action: async function (options) {
      const migrations = await core.loadAllMigrations()
      for (let migration of migrations) {
        logger.log(migration.migsiName, migration.inDevelopment ? 'dev ' : 'prod', migration.runDate || 'to-be-run')
      }
    }
  }
}

function create() {
  return {
    options: [
      ['friendlyName|name|n=s', 'Friendly name for migration script'],
      ['template|t=s', 'Template name']
    ],
    async action({friendlyName, template = 'default'}) {
      if (!friendlyName) {
        friendlyName = await query('Friendly name')
      }
      const filename = await core.createMigrationScript(friendlyName, template)
      logger.log('Migration script created: ' + filename)
    }
  }
}

function run() {
  return {
    options: [
      ['production|prod|p', 'Only run production scripts']
    ],
    action({production = false}) {
      return core.runMigrations({production, confirmation})
    }
  }
}

function ensureNoDevelopmentScripts() {
  return {
    async action() {
      const migrations = await core.loadAllMigrations()
      if (migrations.any(mig => mig.inDevelopment)) {
        throw new Error('There are migration scripts still in develoment.')
      }
    }
  }
}

async function query(prompt) {
  const readlineImpl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  })
  try {
    return await new Promise(resolve => readlineImpl.question(prompt + ': ', resolve))
  } finally {
    readlineImpl.close()
  }
}

async function confirmation() {
  if (require('tty').isatty(process.stdin)) return true
  if (process.argv.includes('--yes')) return true
  const response = await query('Do you want to run the migrations? [y/N]')
  return ['y', 'yes'].includes(response.toLowerCase())
}<commit_msg>Fix support for --yes for run in command line tool<commit_after>
const core = require('./core'),
  nodeGetoptLong = require('node-getopt-long'),
  P = require('bluebird'),
  config = require('./config'),
  readline = require('readline'),
  logger = require('./logger')

const commands = {
  'list': list(),
  'create': create(),
  'run': run(),
  'ensure-no-development-scripts': ensureNoDevelopmentScripts()
}

P.try(async function () {
  const cmdLine = parseCommandLine()
  if (cmdLine.options.config) {
    config.setupConfig(require(cmdLine.options.config))
  } else {
    config.findAndLoadConfig()
  }
  await cmdLine.command.action(cmdLine.options)
}).catch(err => {
  if (!err.printed) {
    console.error(err.stack || err)
  }
  process.exit(1)
})

function parseCommandLine() {
  const command = process.argv[2]
  process.argv.splice(2, 1)
  let cmdImpl = commands[command]
  if (!cmdImpl) throw new Error('Invalid command: ' + command + '; available commands are ' + Object.keys(commands).join(', '))

  const defaultOptions = [[
    'config|conf|c=s', 'Configuration file'
  ]]

  const options = nodeGetoptLong.options((cmdImpl.options || []).concat(defaultOptions), {
    name: 'migsi'
  })

  return {
    command: cmdImpl,
    options
  }
}

function list() {
  return {
    options: [],
    action: async function (options) {
      const migrations = await core.loadAllMigrations()
      for (let migration of migrations) {
        logger.log(migration.migsiName, migration.inDevelopment ? 'dev ' : 'prod', migration.runDate || 'to-be-run')
      }
    }
  }
}

function create() {
  return {
    options: [
      ['friendlyName|name|n=s', 'Friendly name for migration script'],
      ['template|t=s', 'Template name']
    ],
    async action({friendlyName, template = 'default'}) {
      if (!friendlyName) {
        friendlyName = await query('Friendly name')
      }
      const filename = await core.createMigrationScript(friendlyName, template)
      logger.log('Migration script created: ' + filename)
    }
  }
}

function run() {
  return {
    options: [
      ['production|prod|p', 'Only run production scripts'],
      ['yes', 'Automatically confirm deployment']
    ],
    action({production = false, yes: confirmed = false}) {
      return core.runMigrations({production, confirmation: confirmed ? undefined : confirmation})
    }
  }
}

function ensureNoDevelopmentScripts() {
  return {
    async action() {
      const migrations = await core.loadAllMigrations()
      if (migrations.any(mig => mig.inDevelopment)) {
        throw new Error('There are migration scripts still in develoment.')
      }
    }
  }
}

async function query(prompt) {
  const readlineImpl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  })
  try {
    return await new Promise(resolve => readlineImpl.question(prompt + ': ', resolve))
  } finally {
    readlineImpl.close()
  }
}

async function confirmation() {
  if (require('tty').isatty(process.stdin)) return true
  if (process.argv.includes('--yes')) return true
  const response = await query('Do you want to run the migrations? [y/N]')
  return ['y', 'yes'].includes(response.toLowerCase())
}<|endoftext|>


<commit_before>const { KubeConfig } = require('kubernetes-client')
const Client = require('kubernetes-client').Client
const Request = require('kubernetes-client/backends/request')
const parser = require('../../util/parser.js')
const kubeconfig = new KubeConfig()
const consoleLogger = require('../../util/logger.js')
const LRU = require('lru-cache')
const podCache = new LRU({
  max: 2000,
  maxAge: 1000 * 60 * 60
})

var client = null
const FALSE_REGEX = /false/i
const TRUE_REGEX = /true/i
const useLogsEnabledPodAnnotation = TRUE_REGEX.test(
  process.env.USE_LOGS_ENABLED_K8S_ANNOTATIONS || 'true'
)

// The run.sh sets both LOGSENE_ENABLED_DEFAULT and LOGS_ENABLED_DEFAULT to TRUE by default.
// Users should set either of these two to FALSE to disable logging by default for all containers.
// This means you need to use whitelisting to enable logging for certain containers.
// In the ENV for those containers set 'LOGS_ENABLED=true' or 'LOGSENE_ENABLED=true'.
// const LOGS_ENABLED_DEFAULT = TRUE_REGEX.test((process.env.LOGSENE_ENABLED_DEFAULT && process.env.LOGS_ENABLED_DEFAULT) || 'true')

const LOGSENE_ENABLED_DEFAULT = TRUE_REGEX.test(
  process.env.LOGSENE_ENABLED_DEFAULT
)
const LOGS_ENABLED_DEFAULT = TRUE_REGEX.test(process.env.LOGS_ENABLED_DEFAULT)
const FINAL_LOGS_ENABLED_DEFAULT =
  LOGSENE_ENABLED_DEFAULT && LOGS_ENABLED_DEFAULT

if (process.env.KUBERNETES_PORT_443_TCP !== undefined) {
  kubeconfig.loadFromCluster()
} else {
  kubeconfig.loadFromDefault()
}
client = new Client({ backend: new Request({ kubeconfig }) })
client.loadSpec().catch(error => {
  consoleLogger.error('Error in k8s client', error)
})

function kubernetesOutputFilter (
  context,
  config,
  eventEmitter,
  data,
  callback
) {
  // we use the config object to track state of each plugin instance
  if (!config.client) {
    initKubernetesClient(context, config, eventEmitter, data, callback)
  } else {
    enrichLogs(context, config, eventEmitter, data, callback)
  }
}

function initKubernetesClient (context, config, eventEmitter, data, callback) {
  // do we run in k8s cluster?
  config.client = client
  config.getPodSpec = function (namespace, podName, cb) {
    this.client.api.v1
      .namespaces(namespace)
      .pods(podName)
      .get(cb)
  }.bind(config)

  enrichLogs(context, config, eventEmitter, data, callback)
}

const getPodSpec = async (config, namespace, podName, cb) => {
  try {
    var spec = await config.client.api.v1
      .namespaces(namespace)
      .pods(podName)
      .get()
    cb(null, spec.body)
  } catch (error) {
    cb(new Error('Kubernetes API not ready'))
  }
}

function removeFields (pod, data) {
  if (pod && pod.stRemoveFields === false) {
    return
  }
  var annotations = pod.metadata.annotations
  if (!annotations) {
    pod.stRemoveFields = false
    return
  }
  var removeFields =
    annotations.REMOVE_FIELDS || annotations['sematext.com/logs-remove-fields']
  if (removeFields) {
    var fieldNames = removeFields.split(',')
    for (var i = 0; i < fieldNames.length; i++) {
      delete data[fieldNames[i]]
    }
  } else {
    pod.stRemoveFields = false
  }
}

function checkLogsEnabled (pod, data, context, config) {
  if (pod.stLogEnabled !== undefined) {
    data.stLogEnabled = pod.stLogEnabled

    if (config.debug === true) {
      consoleLogger.log(
        `sematext.com/logs-enabled = ${pod.stLogEnabled} for ${pod.metadata.name}`
      )
    }

    return
  }

  pod.stLogEnabled = FINAL_LOGS_ENABLED_DEFAULT

  if (config.debug === true) {
    consoleLogger.log(
      `sematext.com/logs-enabled = ${pod.stLogEnabled} for ${pod.metadata.name}`
    )
  }

  var annotations = pod.metadata.annotations
  if (annotations) {
    var logsEnabled = annotations['sematext.com/logs-enabled']
    if (logsEnabled !== undefined) {
      if (TRUE_REGEX.test(logsEnabled)) {
        pod.stLogEnabled = true
      } else if (FALSE_REGEX.test(logsEnabled)) {
        pod.stLogEnabled = false
      }
    }
    data.stLogEnabled = pod.stLogEnabled

    if (config.debug === true) {
      consoleLogger.log(
        `sematext.com/logs-enabled = ${pod.stLogEnabled} for ${pod.metadata.name}`
      )
    }
  }
}

function checkLogsReceiverUrl (pod, data, context) {
  var annotations = pod.metadata.annotations
  if (annotations && annotations['sematext.com/logs-receiver-urls']) {
    context.logsReceivers = parser.parseReceiverList(
      annotations['sematext.com/logs-receiver-urls']
    )
    return
  }

  context.logsReceiver =
    annotations && annotations['sematext.com/logs-receiver-url']
}

function addLogsIndex (pod, data) {
  if (pod.stLogsTokenSet === false) {
    return
  }
  if (pod.stLogsTokenSet === true) {
    data._index = pod.stToken
    return
  }
  if (!pod.metadata.annotations) {
    pod.stLogsTokenSet = false
    return
  }
  // get ST Logs Token from pod annotation
  pod.stToken = pod.metadata.annotations['sematext.com/logs-token']
  // get comma separated list of fields from pod annotation
  if (pod.stToken) {
    data._index = pod.stToken
    pod.stLogsTokenSet = true
  } else {
    pod.stLogsTokenSet = false
  }
}

function replaceDockerImageName (pod, data) {
  if (data.kubernetes && data.container && pod.stImageCache) {
    var containerName = data.kubernetes.pod.container.name
    var imageInfo = pod.stImageCache[data.kubernetes.pod.name + containerName]
    if (!imageInfo) {
      return
    }
    if (data.container.image.name === 'sha256') {
      console.log(`Container name:  ${data.container.image.name}`)
      console.log(`Container tag: ${data.container.image.tag}`)
      //data.container.image.digest = 'sha256:' + data.container.image.tag
    }
    data.container.image.name = imageInfo.name
    data.container.image.tag = imageInfo.tag
  }
}

function processAnnotations (
  data,
  context,
  config,
  pod,
  eventEmitter,
  callback
) {
  if (pod && pod.metadata) {
    if (useLogsEnabledPodAnnotation) {
      checkLogsEnabled(pod, data, context, config)
      // var logsEnabled = context.dockerInspect.LOGSENE_ENABLED
      if (data.stLogEnabled === false) {
        // allow input plugins to close the input stream, e.g. input/docker/docker.js
        eventEmitter.emit('dropLogsRequest', context, data)
        // logs will be droped, skip enrichment
        return callback()
      }
    }
    replaceDockerImageName(pod, data)
    removeFields(pod, data)
    addLogsIndex(pod, data)
    checkLogsReceiverUrl(pod, data, context)
    return callback(null, data)
  }

  // fallback to return data if no pod info found
  return callback(null, data)
}

function getPodCacheKey (data) {
  return `${data.kubernetes.namespace}/${data.kubernetes.pod.name}`
}

function enrichLogs (context, config, eventEmitter, data, callback) {
  if (!(data.kubernetes && data.kubernetes.pod)) {
    return callback(null, data)
  }
  const cachedPod = podCache.get(getPodCacheKey(data))
  if (cachedPod) {
    processAnnotations(data, context, config, cachedPod, eventEmitter, callback)
    if (data.stLogEnabled === false) {
      if (config.debug === true) {
        consoleLogger.log(
          'logs dropped ' +
            data.kubernetes.namespace +
            '/' +
            data.kubernetes.pod.name,
          data.message
        )
      }
    }
  } else {
    getPodSpec(
      config,
      data.kubernetes.namespace,
      data.kubernetes.pod.name,
      function (err, pod) {
        if (err) {
          consoleLogger.log(err.message)
          return callback(null, data)
        }
        podCache.set(getPodCacheKey(data), pod)
        // create hashtable with containerName -> imageInformation
        pod.stImageCache = {}
        if (pod.spec && pod.spec.containers) {
          var podContainers = pod.spec.containers
          for (var i = 0; i < podContainers.length; i++) {
            var container = podContainers[i]
            // split imageName:version
            var imageInfo = container.image.split(':')
            // split registry/imageName
            var imageRegistryInfo = container.image.split('/')
            var imageKey = pod.metadata.name + container.name
            pod.stImageCache[imageKey] = {
              image: container.image,
              name: imageInfo[0],
              registry: imageRegistryInfo[0]
            }
            if (imageInfo.length > 1) {
              pod.stImageCache[imageKey].tag = imageInfo[1]
            }
            if (imageRegistryInfo.length > 1) {
              pod.stImageCache[imageKey].plainImageName = imageRegistryInfo[1]
            }
          }
        }
        if (config.debug) {
          consoleLogger.log('pod spec: ' + JSON.stringify(pod))
        }
        processAnnotations(data, context, pod, eventEmitter, callback)
      }
    )
  }
}

module.exports = kubernetesOutputFilter
<commit_msg>Revert "SC-12473 Comment code of container image digest (sha256)"<commit_after>const { KubeConfig } = require('kubernetes-client')
const Client = require('kubernetes-client').Client
const Request = require('kubernetes-client/backends/request')
const parser = require('../../util/parser.js')
const kubeconfig = new KubeConfig()
const consoleLogger = require('../../util/logger.js')
const LRU = require('lru-cache')
const podCache = new LRU({
  max: 2000,
  maxAge: 1000 * 60 * 60
})

var client = null
const FALSE_REGEX = /false/i
const TRUE_REGEX = /true/i
const useLogsEnabledPodAnnotation = TRUE_REGEX.test(
  process.env.USE_LOGS_ENABLED_K8S_ANNOTATIONS || 'true'
)

// The run.sh sets both LOGSENE_ENABLED_DEFAULT and LOGS_ENABLED_DEFAULT to TRUE by default.
// Users should set either of these two to FALSE to disable logging by default for all containers.
// This means you need to use whitelisting to enable logging for certain containers.
// In the ENV for those containers set 'LOGS_ENABLED=true' or 'LOGSENE_ENABLED=true'.
// const LOGS_ENABLED_DEFAULT = TRUE_REGEX.test((process.env.LOGSENE_ENABLED_DEFAULT && process.env.LOGS_ENABLED_DEFAULT) || 'true')

const LOGSENE_ENABLED_DEFAULT = TRUE_REGEX.test(
  process.env.LOGSENE_ENABLED_DEFAULT
)
const LOGS_ENABLED_DEFAULT = TRUE_REGEX.test(process.env.LOGS_ENABLED_DEFAULT)
const FINAL_LOGS_ENABLED_DEFAULT =
  LOGSENE_ENABLED_DEFAULT && LOGS_ENABLED_DEFAULT

if (process.env.KUBERNETES_PORT_443_TCP !== undefined) {
  kubeconfig.loadFromCluster()
} else {
  kubeconfig.loadFromDefault()
}
client = new Client({ backend: new Request({ kubeconfig }) })
client.loadSpec().catch(error => {
  consoleLogger.error('Error in k8s client', error)
})

function kubernetesOutputFilter (
  context,
  config,
  eventEmitter,
  data,
  callback
) {
  // we use the config object to track state of each plugin instance
  if (!config.client) {
    initKubernetesClient(context, config, eventEmitter, data, callback)
  } else {
    enrichLogs(context, config, eventEmitter, data, callback)
  }
}

function initKubernetesClient (context, config, eventEmitter, data, callback) {
  // do we run in k8s cluster?
  config.client = client
  config.getPodSpec = function (namespace, podName, cb) {
    this.client.api.v1
      .namespaces(namespace)
      .pods(podName)
      .get(cb)
  }.bind(config)

  enrichLogs(context, config, eventEmitter, data, callback)
}

const getPodSpec = async (config, namespace, podName, cb) => {
  try {
    var spec = await config.client.api.v1
      .namespaces(namespace)
      .pods(podName)
      .get()
    cb(null, spec.body)
  } catch (error) {
    cb(new Error('Kubernetes API not ready'))
  }
}

function removeFields (pod, data) {
  if (pod && pod.stRemoveFields === false) {
    return
  }
  var annotations = pod.metadata.annotations
  if (!annotations) {
    pod.stRemoveFields = false
    return
  }
  var removeFields =
    annotations.REMOVE_FIELDS || annotations['sematext.com/logs-remove-fields']
  if (removeFields) {
    var fieldNames = removeFields.split(',')
    for (var i = 0; i < fieldNames.length; i++) {
      delete data[fieldNames[i]]
    }
  } else {
    pod.stRemoveFields = false
  }
}

function checkLogsEnabled (pod, data, context, config) {
  if (pod.stLogEnabled !== undefined) {
    data.stLogEnabled = pod.stLogEnabled

    if (config.debug === true) {
      consoleLogger.log(
        `sematext.com/logs-enabled = ${pod.stLogEnabled} for ${pod.metadata.name}`
      )
    }

    return
  }

  pod.stLogEnabled = FINAL_LOGS_ENABLED_DEFAULT

  if (config.debug === true) {
    consoleLogger.log(
      `sematext.com/logs-enabled = ${pod.stLogEnabled} for ${pod.metadata.name}`
    )
  }

  var annotations = pod.metadata.annotations
  if (annotations) {
    var logsEnabled = annotations['sematext.com/logs-enabled']
    if (logsEnabled !== undefined) {
      if (TRUE_REGEX.test(logsEnabled)) {
        pod.stLogEnabled = true
      } else if (FALSE_REGEX.test(logsEnabled)) {
        pod.stLogEnabled = false
      }
    }
    data.stLogEnabled = pod.stLogEnabled

    if (config.debug === true) {
      consoleLogger.log(
        `sematext.com/logs-enabled = ${pod.stLogEnabled} for ${pod.metadata.name}`
      )
    }
  }
}

function checkLogsReceiverUrl (pod, data, context) {
  var annotations = pod.metadata.annotations
  if (annotations && annotations['sematext.com/logs-receiver-urls']) {
    context.logsReceivers = parser.parseReceiverList(
      annotations['sematext.com/logs-receiver-urls']
    )
    return
  }

  context.logsReceiver =
    annotations && annotations['sematext.com/logs-receiver-url']
}

function addLogsIndex (pod, data) {
  if (pod.stLogsTokenSet === false) {
    return
  }
  if (pod.stLogsTokenSet === true) {
    data._index = pod.stToken
    return
  }
  if (!pod.metadata.annotations) {
    pod.stLogsTokenSet = false
    return
  }
  // get ST Logs Token from pod annotation
  pod.stToken = pod.metadata.annotations['sematext.com/logs-token']
  // get comma separated list of fields from pod annotation
  if (pod.stToken) {
    data._index = pod.stToken
    pod.stLogsTokenSet = true
  } else {
    pod.stLogsTokenSet = false
  }
}

function replaceDockerImageName (pod, data) {
  if (data.kubernetes && data.container && pod.stImageCache) {
    var containerName = data.kubernetes.pod.container.name
    var imageInfo = pod.stImageCache[data.kubernetes.pod.name + containerName]
    if (!imageInfo) {
      return
    }
    if (data.container.image.name === 'sha256') {
      data.container.image.digest = 'sha256:' + data.container.image.tag
    }
    data.container.image.name = imageInfo.name
    data.container.image.tag = imageInfo.tag
  }
}

function processAnnotations (
  data,
  context,
  config,
  pod,
  eventEmitter,
  callback
) {
  if (pod && pod.metadata) {
    if (useLogsEnabledPodAnnotation) {
      checkLogsEnabled(pod, data, context, config)
      // var logsEnabled = context.dockerInspect.LOGSENE_ENABLED
      if (data.stLogEnabled === false) {
        // allow input plugins to close the input stream, e.g. input/docker/docker.js
        eventEmitter.emit('dropLogsRequest', context, data)
        // logs will be droped, skip enrichment
        return callback()
      }
    }
    replaceDockerImageName(pod, data)
    removeFields(pod, data)
    addLogsIndex(pod, data)
    checkLogsReceiverUrl(pod, data, context)
    return callback(null, data)
  }

  // fallback to return data if no pod info found
  return callback(null, data)
}

function getPodCacheKey (data) {
  return `${data.kubernetes.namespace}/${data.kubernetes.pod.name}`
}

function enrichLogs (context, config, eventEmitter, data, callback) {
  if (!(data.kubernetes && data.kubernetes.pod)) {
    return callback(null, data)
  }
  const cachedPod = podCache.get(getPodCacheKey(data))
  if (cachedPod) {
    processAnnotations(data, context, config, cachedPod, eventEmitter, callback)
    if (data.stLogEnabled === false) {
      if (config.debug === true) {
        consoleLogger.log(
          'logs dropped ' +
            data.kubernetes.namespace +
            '/' +
            data.kubernetes.pod.name,
          data.message
        )
      }
    }
  } else {
    getPodSpec(
      config,
      data.kubernetes.namespace,
      data.kubernetes.pod.name,
      function (err, pod) {
        if (err) {
          consoleLogger.log(err.message)
          return callback(null, data)
        }
        podCache.set(getPodCacheKey(data), pod)
        // create hashtable with containerName -> imageInformation
        pod.stImageCache = {}
        if (pod.spec && pod.spec.containers) {
          var podContainers = pod.spec.containers
          for (var i = 0; i < podContainers.length; i++) {
            var container = podContainers[i]
            // split imageName:version
            var imageInfo = container.image.split(':')
            // split registry/imageName
            var imageRegistryInfo = container.image.split('/')
            var imageKey = pod.metadata.name + container.name
            pod.stImageCache[imageKey] = {
              image: container.image,
              name: imageInfo[0],
              registry: imageRegistryInfo[0]
            }
            if (imageInfo.length > 1) {
              pod.stImageCache[imageKey].tag = imageInfo[1]
            }
            if (imageRegistryInfo.length > 1) {
              pod.stImageCache[imageKey].plainImageName = imageRegistryInfo[1]
            }
          }
        }
        if (config.debug) {
          consoleLogger.log('pod spec: ' + JSON.stringify(pod))
        }
        processAnnotations(data, context, pod, eventEmitter, callback)
      }
    )
  }
}

module.exports = kubernetesOutputFilter
<|endoftext|>


<commit_before>var Player = function(ui) {
	var player = ui._context.createElement('video')
	player.dom.preload = "metadata"

	player.setAttribute('preload', 'auto')
	player.setAttribute('data-setup', '{}')
	player.setAttribute('class', 'video-js')

	this.element = player
	this.ui = ui
	this.setEventListeners()

	var uniqueId = 'videojs' + this.element._uniqueId
	player.setAttribute('id', uniqueId)

	if (ui.element)
		ui.element.remove()
	ui.element = player
	ui.parent.element.append(ui.element)

	this.videojs = window.videojs(uniqueId, { "textTrackSettings": false })

	this.videojs.width = 'auto'
	this.videojs.height = 'auto'
	// this.videojs.userActive(false)
	// this.videojs.controls(false)

	var errorDisplay = document.getElementsByClassName("vjs-error-display")
	if (errorDisplay && errorDisplay.length) {
		for (var index = 0; index < errorDisplay.length; ++index) {
			errorDisplay[index].style.display = 'none'
		}
	}

	var videojsSpinner = document.getElementsByClassName("vjs-loading-spinner")
	if (videojsSpinner && videojsSpinner.length) {
		for (var index = 0; index < videojsSpinner.length; ++index) {
			videojsSpinner[index].style.display = 'none'
		}
	}

	var videojsControllButton = document.getElementsByClassName("vjs-control-bar")
	if (videojsControllButton && videojsControllButton.length) {
		for (var index = 0; index < videojsControllButton.length; ++index) {
			videojsControllButton[index].style.display = 'none'
		}
	}

	var videojsBigPlayButton = document.getElementsByClassName("vjs-big-play-button")
	if (videojsBigPlayButton && videojsBigPlayButton.length) {
		for (var index = 0; index < videojsBigPlayButton.length; ++index) {
			videojsBigPlayButton[index].style.display = 'none'
		}
	}

	this.videojsContaner = document.getElementById(uniqueId)
	this.videojsContaner.style.zindex = -1
}

Player.prototype = Object.create(_globals.video.html5.backend.Player.prototype)

Player.prototype.dispose = function() {
	window.videojs(this.videojsContaner).dispose()
	this.videojs.dispose()
	this.videojs = null
	_globals.video.html5.backend.Player.prototype.dispose.apply(this)
}

Player.prototype.setSource = function(url) {
	var media = { 'src': url }
	log("SetSource", url)
	if (url) {
		var urlLower = url.toLowerCase()
		var querryIndex = url.indexOf("?")
		if (querryIndex >= 0)
			urlLower = urlLower.substring(0, querryIndex)
		var extIndex = urlLower.lastIndexOf(".")
		var extension = urlLower.substring(extIndex, urlLower.length)
		if (extension === ".m3u8" || extension === ".m3u")
			media.type = 'application/x-mpegURL'
		else if (extension === ".mpd")
			media.type = 'application/dash+xml'
	}
	this.videojs.src(media, { html5: { hls: { withCredentials: true } }, fluid: true, preload: 'none', techOrder: ["html5"] })
	if (this.ui.autoPlay)
		this.play()
}

Player.prototype.play = function() {
	var playPromise = this.element.dom.play()
	if (playPromise !== undefined) {
		playPromise.catch(function(e) {
			log('play error:', e)
			if (this.ui.autoPlay && e.code === DOMException.ABORT_ERR)
				this.element.dom.play()
		}.bind(this))
	}
}

Player.prototype.setRect = function(l, t, r, b) {
	this.videojsContaner.style.width = (r - l) + "px"
	this.videojsContaner.style.height = (b - t) + "px"
}

exports.createPlayer = function(ui) {
	return new Player(ui)
}

exports.probeUrl = function(url) {
	return window.videojs ? 60 : 0
}
<commit_msg>Code clean up<commit_after>var Player = function(ui) {
	var player = ui._context.createElement('video')
	player.dom.preload = "metadata"

	player.setAttribute('preload', 'auto')
	player.setAttribute('data-setup', '{}')
	player.setAttribute('class', 'video-js')

	this.element = player
	this.ui = ui
	this.setEventListeners()

	var uniqueId = 'videojs' + this.element._uniqueId
	player.setAttribute('id', uniqueId)

	if (ui.element)
		ui.element.remove()
	ui.element = player
	ui.parent.element.append(ui.element)

	this.videojs = window.videojs(uniqueId, { "textTrackSettings": false })

	this.videojs.width = 'auto'
	this.videojs.height = 'auto'

	var errorDisplay = document.getElementsByClassName("vjs-error-display")
	if (errorDisplay && errorDisplay.length) {
		for (var index = 0; index < errorDisplay.length; ++index) {
			errorDisplay[index].style.display = 'none'
		}
	}

	var videojsSpinner = document.getElementsByClassName("vjs-loading-spinner")
	if (videojsSpinner && videojsSpinner.length) {
		for (var index = 0; index < videojsSpinner.length; ++index) {
			videojsSpinner[index].style.display = 'none'
		}
	}

	var videojsControllButton = document.getElementsByClassName("vjs-control-bar")
	if (videojsControllButton && videojsControllButton.length) {
		for (var index = 0; index < videojsControllButton.length; ++index) {
			videojsControllButton[index].style.display = 'none'
		}
	}

	var videojsBigPlayButton = document.getElementsByClassName("vjs-big-play-button")
	if (videojsBigPlayButton && videojsBigPlayButton.length) {
		for (var index = 0; index < videojsBigPlayButton.length; ++index) {
			videojsBigPlayButton[index].style.display = 'none'
		}
	}

	this.videojsContaner = document.getElementById(uniqueId)
	this.videojsContaner.style.zindex = -1
}

Player.prototype = Object.create(_globals.video.html5.backend.Player.prototype)

Player.prototype.dispose = function() {
	window.videojs(this.videojsContaner).dispose()
	this.videojs.dispose()
	this.videojs = null
	_globals.video.html5.backend.Player.prototype.dispose.apply(this)
}

Player.prototype.setSource = function(url) {
	var media = { 'src': url }
	log("SetSource", url)
	if (url) {
		var urlLower = url.toLowerCase()
		var querryIndex = url.indexOf("?")
		if (querryIndex >= 0)
			urlLower = urlLower.substring(0, querryIndex)
		var extIndex = urlLower.lastIndexOf(".")
		var extension = urlLower.substring(extIndex, urlLower.length)
		if (extension === ".m3u8" || extension === ".m3u")
			media.type = 'application/x-mpegURL'
		else if (extension === ".mpd")
			media.type = 'application/dash+xml'
	}
	this.videojs.src(media, { html5: { hls: { withCredentials: true } }, fluid: true, preload: 'none', techOrder: ["html5"] })
	if (this.ui.autoPlay)
		this.play()
}

Player.prototype.play = function() {
	var playPromise = this.element.dom.play()
	if (playPromise !== undefined) {
		playPromise.catch(function(e) {
			log('play error:', e)
			if (this.ui.autoPlay && e.code === DOMException.ABORT_ERR)
				this.element.dom.play()
		}.bind(this))
	}
}

Player.prototype.setRect = function(l, t, r, b) {
	this.videojsContaner.style.width = (r - l) + "px"
	this.videojsContaner.style.height = (b - t) + "px"
}

exports.createPlayer = function(ui) {
	return new Player(ui)
}

exports.probeUrl = function(url) {
	return window.videojs ? 60 : 0
}
<|endoftext|>