<commit_before>/*
 * Copyright © 2016 Cask Data, Inc.
 *
 * 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.
 */

angular.module(PKG.name + '.feature.hydratorplusplus')
  .controller('HydratorPlusPlusDetailCanvasCtrl', function(rPipelineDetail, HydratorPlusPlusBottomPanelStore, DAGPlusPlusNodesActionsFactory, HydratorService, DAGPlusPlusNodesStore, ConfigStore, HydratorPlusPlusNodeConfigActions, HydratorPlusPlusDetailNonRunsStore, HydratorPlusPlusDetailMetricsStore) {
    this.ConfigStore = ConfigStore;
    this.DAGPlusPlusNodesStore = DAGPlusPlusNodesStore;
    this.HydratorPlusPlusDetailNonRunsStore = HydratorPlusPlusDetailNonRunsStore;
    this.HydratorPlusPlusNodeConfigActions = HydratorPlusPlusNodeConfigActions;
    this.HydratorService = HydratorService;
    this.HydratorPlusPlusDetailMetricsStore = HydratorPlusPlusDetailMetricsStore;

    try{
      rPipelineDetail.config = JSON.parse(rPipelineDetail.configuration);
    } catch(e) {
      console.log('ERROR in configuration from backend: ', e);
      return;
    }
    this.setState = function() {
      this.setScroll = (HydratorPlusPlusBottomPanelStore.getPanelState() === 0 ? false: true);
    };
    this.setState();
    HydratorPlusPlusBottomPanelStore.registerOnChangeListener(this.setState.bind(this));
    var obj = HydratorPlusPlusDetailNonRunsStore.getCloneConfig();

    DAGPlusPlusNodesActionsFactory.createGraphFromConfig(obj.__ui__.nodes, obj.config.connections, obj.config.comments);

    this.updateNodesAndConnections = function () {
      var activeNode = this.DAGPlusPlusNodesStore.getActiveNodeId();
      if (!activeNode) {
        this.deleteNode();
      } else {
        this.setActiveNode();
      }
    };

    this.setActiveNode = function() {
      var nodeId = this.DAGPlusPlusNodesStore.getActiveNodeId();
      if (!nodeId) {
        return;
      }
      this.HydratorPlusPlusNodeConfigActions.choosePlugin(this.HydratorPlusPlusDetailNonRunsStore.getPluginObject(nodeId));
    };

    this.deleteNode = function() {
      this.HydratorPlusPlusNodeConfigActions.removePlugin();
    };

    this.generateSchemaOnEdge = function (sourceId) {
      return this.HydratorService.generateSchemaOnEdge(sourceId);
    };

    function convertMetricsArrayIntoObject(arr) {
      var obj = {};

      angular.forEach(arr, function (item) {
        obj[item.nodeName] = {
          recordsOut: item.recordsOut,
          recordsIn: item.recordsIn
        };
      });

      return obj;
    }
    this.metrics = convertMetricsArrayIntoObject(this.HydratorPlusPlusDetailMetricsStore.getMetrics());

    this.HydratorPlusPlusDetailMetricsStore.registerOnChangeListener(function () {
      this.metrics = convertMetricsArrayIntoObject(this.HydratorPlusPlusDetailMetricsStore.getMetrics());
    }.bind(this));

    DAGPlusPlusNodesStore.registerOnChangeListener(this.updateNodesAndConnections.bind(this));
  });
<commit_msg>Fixes schema popup in detailed view in Hydrator++<commit_after>/*
 * Copyright © 2016 Cask Data, Inc.
 *
 * 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.
 */

angular.module(PKG.name + '.feature.hydratorplusplus')
  .controller('HydratorPlusPlusDetailCanvasCtrl', function(rPipelineDetail, HydratorPlusPlusBottomPanelStore, DAGPlusPlusNodesActionsFactory, HydratorPlusPlusHydratorService, DAGPlusPlusNodesStore, ConfigStore, HydratorPlusPlusNodeConfigActions, HydratorPlusPlusDetailNonRunsStore, HydratorPlusPlusDetailMetricsStore) {
    this.ConfigStore = ConfigStore;
    this.DAGPlusPlusNodesStore = DAGPlusPlusNodesStore;
    this.HydratorPlusPlusDetailNonRunsStore = HydratorPlusPlusDetailNonRunsStore;
    this.HydratorPlusPlusNodeConfigActions = HydratorPlusPlusNodeConfigActions;
    this.HydratorPlusPlusHydratorService = HydratorPlusPlusHydratorService;
    this.HydratorPlusPlusDetailMetricsStore = HydratorPlusPlusDetailMetricsStore;

    try{
      rPipelineDetail.config = JSON.parse(rPipelineDetail.configuration);
    } catch(e) {
      console.log('ERROR in configuration from backend: ', e);
      return;
    }
    this.setState = function() {
      this.setScroll = (HydratorPlusPlusBottomPanelStore.getPanelState() === 0 ? false: true);
    };
    this.setState();
    HydratorPlusPlusBottomPanelStore.registerOnChangeListener(this.setState.bind(this));
    var obj = HydratorPlusPlusDetailNonRunsStore.getCloneConfig();

    DAGPlusPlusNodesActionsFactory.createGraphFromConfig(obj.__ui__.nodes, obj.config.connections, obj.config.comments);

    this.updateNodesAndConnections = function () {
      var activeNode = this.DAGPlusPlusNodesStore.getActiveNodeId();
      if (!activeNode) {
        this.deleteNode();
      } else {
        this.setActiveNode();
      }
    };

    this.setActiveNode = function() {
      var nodeId = this.DAGPlusPlusNodesStore.getActiveNodeId();
      if (!nodeId) {
        return;
      }
      this.HydratorPlusPlusNodeConfigActions.choosePlugin(this.HydratorPlusPlusDetailNonRunsStore.getPluginObject(nodeId));
    };

    this.deleteNode = function() {
      this.HydratorPlusPlusNodeConfigActions.removePlugin();
    };

    this.generateSchemaOnEdge = function (sourceId) {
      return this.HydratorPlusPlusHydratorService.generateSchemaOnEdge(sourceId);
    };

    function convertMetricsArrayIntoObject(arr) {
      var obj = {};

      angular.forEach(arr, function (item) {
        obj[item.nodeName] = {
          recordsOut: item.recordsOut,
          recordsIn: item.recordsIn
        };
      });

      return obj;
    }
    this.metrics = convertMetricsArrayIntoObject(this.HydratorPlusPlusDetailMetricsStore.getMetrics());

    this.HydratorPlusPlusDetailMetricsStore.registerOnChangeListener(function () {
      this.metrics = convertMetricsArrayIntoObject(this.HydratorPlusPlusDetailMetricsStore.getMetrics());
    }.bind(this));

    DAGPlusPlusNodesStore.registerOnChangeListener(this.updateNodesAndConnections.bind(this));
  });
<|endoftext|>


<commit_before>'use strict';

module.exports = {
  client: {
    lib: {
      css: [
        'public/lib/bootstrap/dist/css/bootstrap.min.css',
        'public/lib/bootstrap/dist/css/bootstrap-theme.min.css',
      ],
      js: [
        'public/lib/angular/angular.min.js',
        'public/lib/angular-resource/angular-resource.min.js',
        'public/lib/angular-animate/angular-animate.min.js',
        'public/lib/angular-messages/angular-messages.min.js',
        'public/lib/angular-ui-router/release/angular-ui-router.min.js',
        'public/lib/angular-ui-utils/ui-utils.min.js',
        'public/lib/angular-bootstrap/ui-bootstrap-tpls.min.js',
        'public/lib/angular-file-upload/angular-file-upload.min.js',
        'public/lib/owasp-password-strength-test/owasp-password-strength-test.js'
      ]
    },
    css: 'public/dist/application.min.css',
    js: 'public/dist/application.min.js'
  }
};
<commit_msg>Deployment Fix<commit_after>'use strict';

module.exports = {

  client: {
    lib: {
      css: [
        'public/lib/bootstrap/dist/css/bootstrap.css',
        'public/lib/bootstrap/dist/css/bootstrap-theme.css',
        'public/lib/highlightjs/styles/agate.css'
      ],
      js: [
        'public/lib/angular/angular.js',
        'public/lib/angular-resource/angular-resource.js',
        'public/lib/angular-animate/angular-animate.js',
        'public/lib/angular-messages/angular-messages.js',
        'public/lib/angular-ui-router/release/angular-ui-router.js',
        'public/lib/angular-ui-utils/ui-utils.js',
        'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
        'public/lib/angular-file-upload/angular-file-upload.js',
        'public/lib/owasp-password-strength-test/owasp-password-strength-test.js',
        'public/lib/highlightjs/highlight.pack.js',
        'public/lib/angular-highlightjs/angular-highlightjs.min.js'

      ],
      tests: ['public/lib/angular-mocks/angular-mocks.js']
    },
    css: [
      'modules/*/client/css/*.css'
    ],
    less: [
      'modules/*/client/less/*.less'
    ],
    sass: [
      'modules/*/client/scss/*.scss'
    ],
    js: [
      'modules/core/client/app/config.js',
      'modules/core/client/app/init.js',
      'modules/*/client/*.js',
      'modules/*/client/**/*.js'
    ],
    views: ['modules/*/client/views/**/*.html'],
    templates: ['build/templates.js']
  },
  server: {
    gruntConfig: 'gruntfile.js',
    gulpConfig: 'gulpfile.js',
    allJS: ['server.js', 'config/**/*.js', 'modules/*/server/**/*.js'],
    models: 'modules/*/server/models/**/*.js',
    routes: ['modules/!(core)/server/routes/**/*.js', 'modules/core/server/routes/**/*.js'],
    sockets: 'modules/*/server/sockets/**/*.js',
    config: 'modules/*/server/config/*.js',
    policies: 'modules/*/server/policies/*.js',
    views: 'modules/*/server/views/*.html'
  }
};
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Jiří Janoušek <janousek.jiri@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

(function(window, undefined)
{

var $id = document.getElementById.bind(document);
var $class = document.getElementsByClassName.bind(document);
var $1 = document.querySelector.bind(document);
var $all = document.querySelectorAll.bind(document);

var HttpRequest = function(method, url, params)
{
    method = method.toUpperCase();
    this.payload = null;
    var payload = null;
    if (params)
    {
        var pairs = [];
        for (var key in params)
        {
            if (params.hasOwnProperty(key))
                pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
        }
        payload = pairs.length > 0 ? pairs.join("&") : null;
    }

    if (method == "GET" && payload)
        url += "?" + payload;

    if (method == "POST" && payload)
        this.payload = payload;

    this.method = method
    this.url = url;
}

HttpRequest.prototype.send = function()
{
    this.request = new XMLHttpRequest();
    this.request.onreadystatechange = this._onreadystatechange.bind(this);
    this.request.open(this.method, this.url);
    if (this.method == "POST" && this.payload)
        this.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    this.request.send(this.payload);
}

HttpRequest.prototype._onreadystatechange = function()
{
    if (this.request.readyState === XMLHttpRequest.DONE)
    {
        if (this.request.status === 200)
            this.onsuccess(this);
        else
            this.onerror(this);
    }
}

HttpRequest.prototype.json = function()
{
    return JSON.parse(this.request.responseText);
}

HttpRequest.prototype.text = function()
{
    return this.request.responseText;
}

HttpRequest.prototype.onsuccess = function(request)
{
    console.log("HTTP Request successful");
}

HttpRequest.prototype.onerror = function(request)
{
    console.log("HTTP Request failed");
}

var Nuvola = {};

Nuvola.onload = function()
{
    this.appId = "test";
    this.update();
    $id("play-pause").onclick = function()
    {
        var r = new HttpRequest("post", "/+api/app/" + Nuvola.appId + "/actions/activate", {name: "toggle-play"});
        r.send();
        setTimeout(Nuvola.update.bind(Nuvola), 1000);
    };
}

Nuvola.update = function()
{
    var appId = this.appId;
    var request = new HttpRequest("get", "/+api/app/" + appId + "/mediaplayer/track-info", null);
    request.onsuccess = function(request)
    {
        var data;
        try
        {
            data = request.json();
        }
        catch (e)
        {
            this.onerror(request);
            return;
        }

        $id("app-name").innerText = appId;
        $id("track-title").innerText = data.title || "unknown";
        $id("track-album").innerText = data.album || "unknown";
        $id("track-artist").innerText = data.artist || "unknown";
        $id("playback-state").innerText = data.state || "unknown";
        $id("play-pause").innerText = data.state === "playing" ? "pause" : "play";

        if (!data.state || data.state == "unknown")
        {
            $id("track-rating").innerText = "unknown";
        }
        else
        {
            var rating = Math.round((data.rating || 0) * 5);
            var stars = "";
            for (var i = 0; i < rating; i++)
            stars += "★";
            for (var i = 0; i < 5 - rating; i++)
            stars += "☆";
            $id("track-rating").innerText = stars;
        }
    };
    request.onerror = function(request)
    {
        $id("app-name").innerText = "Error";
    }
    request.send();
}

window.onload = Nuvola.onload.bind(Nuvola);
})(window);
<commit_msg>Mediaplayer.html controls top app runner<commit_after>/*
 * Copyright 2016 Jiří Janoušek <janousek.jiri@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

(function(window, undefined)
{

var $id = document.getElementById.bind(document);
var $class = document.getElementsByClassName.bind(document);
var $1 = document.querySelector.bind(document);
var $all = document.querySelectorAll.bind(document);

var HttpRequest = function(method, url, params)
{
    method = method.toUpperCase();
    this.payload = null;
    var payload = null;
    if (params)
    {
        var pairs = [];
        for (var key in params)
        {
            if (params.hasOwnProperty(key))
                pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
        }
        payload = pairs.length > 0 ? pairs.join("&") : null;
    }

    if (method == "GET" && payload)
        url += "?" + payload;

    if (method == "POST" && payload)
        this.payload = payload;

    this.method = method
    this.url = url;
}

HttpRequest.prototype.send = function()
{
    this.request = new XMLHttpRequest();
    this.request.onreadystatechange = this._onreadystatechange.bind(this);
    this.request.open(this.method, this.url);
    if (this.method == "POST" && this.payload)
        this.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    this.request.send(this.payload);
}

HttpRequest.prototype._onreadystatechange = function()
{
    if (this.request.readyState === XMLHttpRequest.DONE)
    {
        if (this.request.status === 200)
            this.onsuccess(this);
        else
            this.onerror(this);
    }
}

HttpRequest.prototype.json = function()
{
    return JSON.parse(this.request.responseText);
}

HttpRequest.prototype.text = function()
{
    return this.request.responseText;
}

HttpRequest.prototype.onsuccess = function(request)
{
    console.log("HTTP Request successful");
}

HttpRequest.prototype.onerror = function(request)
{
    console.log("HTTP Request failed");
}

var Nuvola = {};

Nuvola.onload = function()
{
    this.appId = "test";
    this.appInfo = null;
    this.update();
    $id("play-pause").onclick = function()
    {
        var r = new HttpRequest("post", "/+api/app/" + Nuvola.appId + "/actions/activate", {name: "toggle-play"});
        r.send();
        setTimeout(Nuvola.update.bind(Nuvola), 1000);
    };
}

Nuvola.update = function()
{
    this.updateAppId();
}

Nuvola.updateAppId = function()
{
    var self = this;
    var request = new HttpRequest("get", "/+api/core/get_top_runner", null);
    request.onsuccess = function(request)
    {
        var data;
        try
        {
            data = request.json();
        }
        catch (e)
        {
            this.onerror(request);
            return;
        }
        self.appId = data.result;
        self.updateAppInfo();
    };
    request.onerror = function(request)
    {
        $id("app-name").innerText = "Error";
    }
    request.send();
}

Nuvola.updateAppInfo = function()
{
    var self = this;
    var request = new HttpRequest("get", "/+api/app/" + this.appId, null);
    request.onsuccess = function(request)
    {
        var data;
        try
        {
            data = request.json();
        }
        catch (e)
        {
            this.onerror(request);
            return;
        }
        self.appInfo = data;
        self.updateTrackInfo();
    };
    request.onerror = function(request)
    {
        $id("app-name").innerText = "Error";
    }
    request.send();
}

Nuvola.updateTrackInfo = function()
{
    var self = this;
    var request = new HttpRequest("get", "/+api/app/" + this.appId + "/mediaplayer/track-info", null);
    request.onsuccess = function(request)
    {
        var data;
        try
        {
            data = request.json();
        }
        catch (e)
        {
            this.onerror(request);
            return;
        }

        $id("app-name").innerText = self.appInfo ? self.appInfo.name : self.appId;
        $id("track-title").innerText = data.title || "unknown";
        $id("track-album").innerText = data.album || "unknown";
        $id("track-artist").innerText = data.artist || "unknown";
        $id("playback-state").innerText = data.state || "unknown";
        $id("play-pause").innerText = data.state === "playing" ? "pause" : "play";

        if (!data.state || data.state == "unknown")
        {
            $id("track-rating").innerText = "unknown";
        }
        else
        {
            var rating = Math.round((data.rating || 0) * 5);
            var stars = "";
            for (var i = 0; i < rating; i++)
            stars += "★";
            for (var i = 0; i < 5 - rating; i++)
            stars += "☆";
            $id("track-rating").innerText = stars;
        }
    };
    request.onerror = function(request)
    {
        $id("app-name").innerText = "Error";
    }
    request.send();
}

window.onload = Nuvola.onload.bind(Nuvola);
})(window);
<|endoftext|>


<commit_before>'use strict';

import Reflux from 'reflux';
import {isArray, isUndefined} from 'lodash';
import SocketClient from 'dbc-node-serviceprovider-socketclient';

// Actions
import RecommendationsActions from './Recommendations.action';

export const defaultLikes = [
  '870970-basis:51263146',
  '870970-basis:51115155',
  '870970-basis:28394438',
  '870970-basis:22629344',
  '870970-basis:25915690',
  '870970-basis:24929604',
  '870970-basis:27796664',
  '870970-basis:26588707',
  '870970-basis:23372525',
  '870970-basis:28280041',
  '870970-basis:51342860',
  '870970-basis:28290853'
];

/**
 * Store containing the recommendations related to the search query
 */
let RecommendationsStore = Reflux.createStore({
  mixins: [SocketClient('getRecommendations')],

  store: {
    result: [],
    pending: false,
    info: {more: false}
  },

  init() {
    this.response(this.onResponse);
    this.listenToMany(RecommendationsActions);
  },

  onDefault() {
    this.onRequest({likes: defaultLikes, dislikes: []});
  },

  onRequest(data) {
    if (!isUndefined(data) && isArray(data.likes) && isArray(data.dislikes) && data.likes.length) {
      this.updatePending(true);
      this.request(data);
    }
    else {
      this.onDefault();
    }
  },

  onResponse(result) {
    this.store.pending = false;
    if (result.error) {
      console.error(result.error.statusMessage, result.error); // eslint-disable-line
    }
    else {
      this.store.result = result.splice(0, 20);
      this.trigger(this.store);
    }
  },

  updatePending(state) {
    this.store.pending = state;
    this.trigger(this.store);
  },

  update(result) {
    this.store.result = result.splice(0, 20);
    this.store.pending = false;
    this.trigger(this.store);
  },

  getDefaultRecommendations() {
    return defaultLikes;
  }
});

export default RecommendationsStore;
<commit_msg>rolled back minor change. sd-97 Doing<commit_after>'use strict';

import Reflux from 'reflux';
import {isArray, isUndefined} from 'lodash';
import SocketClient from 'dbc-node-serviceprovider-socketclient';

// Actions
import RecommendationsActions from './Recommendations.action';

export const defaultLikes = [
  '870970-basis:51263146',
  '870970-basis:51115155',
  '870970-basis:28394438',
  '870970-basis:22629344',
  '870970-basis:25915690',
  '870970-basis:24929604',
  '870970-basis:27796664',
  '870970-basis:26588707',
  '870970-basis:23372525',
  '870970-basis:28280041',
  '870970-basis:51342860',
  '870970-basis:28290853'
];

/**
 * Store containing the recommendations related to the search query
 */
let RecommendationsStore = Reflux.createStore({
  mixins: [SocketClient('getRecommendations')],

  store: {
    result: [],
    pending: false,
    info: {more: false}
  },

  init() {
    this.response(this.onResponse);
    this.listenToMany(RecommendationsActions);
  },

  onDefault() {
    this.onRequest({likes: defaultLikes, dislikes: []});
  },

  onRequest(data) {
    if (!isUndefined(data) && isArray(data.likes) && isArray(data.dislikes) && data.likes.length) {
      this.updatePending(true);
      this.request(data);
    }
    else {
      this.onDefault();
    }
  },

  onResponse(result) {
    this.store.pending = false;
    if (result.error) {
      throw new Error(result.error.statusMessage, result.error);
    }
    else {
      this.store.result = result.splice(0, 20);
      this.trigger(this.store);
    }
  },

  updatePending(state) {
    this.store.pending = state;
    this.trigger(this.store);
  },

  update(result) {
    this.store.result = result.splice(0, 20);
    this.store.pending = false;
    this.trigger(this.store);
  },

  getDefaultRecommendations() {
    return defaultLikes;
  }
});

export default RecommendationsStore;
<|endoftext|>


<commit_before>L.NanocubeLayer = L.TileLayer.Canvas.extend({
    initialize: function(options){
        L.TileLayer.Canvas.prototype.initialize.call(this, options);
        this.model = options.model;
        this.variable = options.variable;
        this.colormap = d3.scale.linear()
            .domain(options.colormap.domain)
            .range(options.colormap.colors);

        this.coarselevels = 1;
        this.smooth = false;

        this.show_count = false;
        this.log = true;
    }
});

L.NanocubeLayer.prototype.toggleLog = function(){
    this.log = !this.log;
    this.redraw();
};

L.NanocubeLayer.prototype.toggleShowCount = function(){
    this.show_count = !this.show_count;
    this.redraw();
};

L.NanocubeLayer.prototype.redraw = function(){
    if (this._map) {
	//this._reset({hard: false});  //no hard resetting
	this._update();
    }
    for (var i in this._tiles) {
	this._redrawTile(this._tiles[i]);
    }
    return this;
};

L.NanocubeLayer.prototype.drawTile = function(canvas, tilePoint, zoom){
    var drill = Math.min(this.variable.maxlevel-zoom,8) - this.coarselevels ;
    drill = Math.max(0,drill);
    drill = Math.min(8,drill);

    var size = Math.pow(2,drill);
    var ntiles = Math.pow(2,zoom);

    //fix negative tiles
    while(tilePoint.x < 0){
        tilePoint.x += ntiles;
    }

    while(tilePoint.y < 0){
        tilePoint.y += ntiles;
    }

    //fix overflow tiles
    while(tilePoint.x > ntiles){
        tilePoint.x -= ntiles;
    }

    while(tilePoint.y > ntiles){
        tilePoint.y -= ntiles;
    }

    //flip y for nanocubes
    var ty = (ntiles-1)-tilePoint.y;

    //query
    var tile = new Tile(tilePoint.x,ty,zoom);
    var that = this;
    this.model.tileQuery(this.variable, tile, drill, function(data){
        var result = that.processData(data);

        if(result !=null){
            that.max = Math.max(that.max, result.max);
            that.min = Math.min(that.min, result.min);
            that.renderTile(canvas,size,tilePoint,zoom,result.data);
        }
        else{
            that.renderTile(canvas,size,tilePoint,zoom,null);
        }
    });
    this.tileDrawn(canvas);
};

L.NanocubeLayer.prototype.renderTile = function(canvas, size, tilePoint,zoom,data){
    var ctx = canvas.getContext('2d');

    if (data == null){
        var imgBlankData = ctx.createImageData(canvas.width,canvas.height);
        ctx.putImageData(imgBlankData,0,0);

        if (this.show_count){//draw grid box
            this.drawGridCount(ctx,tilePoint,zoom,data);
        }
        return;
    }

    var imgData=ctx.createImageData(size,size);
    var pixels = imgData.data;
    var length = pixels.length;

    if (! this.smooth){ //blocky rendering
        ctx.imageSmoothingEnabled = false;
        ctx.webkitImageSmoothingEnabled = false;
        ctx.mozImageSmoothingEnabled = false;
    }

    //set color
    var that = this;
    var minv = that.min;
    var maxv = that.max;
    if (this.log){
        minv = Math.log(minv);
        maxv = Math.log(maxv);
    }

    data.forEach(function(d){
        if(d.v < 1e-6){
            return;
        }

        var v = d.v;
        if (that.log){
            v = Math.log(v+1);
        }

        v = (v-minv)/maxv;
        var color = d3.rgb(that.colormap(v));
        var idx = (imgData.height-1-d.y)*imgData.width + d.x;
        pixels[idx*4]=color.r;
        pixels[idx*4+1]=color.g ;
        pixels[idx*4+2]=color.b;
        pixels[idx*4+3]= v*255*2;
    });

    //set image
    var sc = canvas.width*1.0/size;

    //clear the canvas
    imgBlankData = ctx.createImageData(canvas.width,canvas.height);
    ctx.putImageData(imgBlankData,0,0);

    //scale
    if (sc !=1){
        //create a proxy canvas
        var newCanvas = $('<canvas>')
                .attr("width", imgData.width)
                .attr("height", imgData.height)[0];
        newCanvas.getContext("2d").putImageData(imgData, 0, 0);

        ctx.drawImage(newCanvas,0,0,canvas.width,canvas.height);
    }
    else{
        ctx.putImageData(imgData,0,0);
    }

    if (this.show_count){//draw grid box
        this.drawGridCount(ctx,tilePoint,zoom,data);
    }
};

L.NanocubeLayer.prototype.drawGridCount = function(ctx,tilePoint,zoom,data){
    ctx.lineWidth="0.5";
    ctx.strokeStyle="white";
    ctx.rect(0,0,ctx.canvas.width,ctx.canvas.height);
    ctx.stroke();

    var totalstr =  "("+tilePoint.x + "," + tilePoint.y +","+zoom+")   ";
    if(data != null){
        //Total count
        var total = data.reduce(function(prev,curr){return prev+curr.v;},0);
        totalstr +=  total.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
    ctx.font="10pt sans-serif";
    ctx.fillStyle="white";
    ctx.fillText(totalstr,10,20);

};

L.NanocubeLayer.prototype.processData = function(bindata){
    if(bindata == null){
        return null;
    }

    var record_size = 10;
    var view = new DataView(bindata);
    var n_records = bindata.byteLength / record_size;
    if (n_records < 1) {
        return null;
    }

    var data = [];
    data.length = n_records;
    var maxv = -Infinity;
    var minv = Infinity;

    for (var i=0; i<n_records; ++i) {
        var rx = view.getUint8( record_size*i+1 );
        var ry = view.getUint8( record_size*i   );
        var rv = view.getFloat64( record_size*i+2, true );
        if (rv < 1e-6){ //skip zeros
            continue;
        }

        //if (this.log){
        //    rv = Math.log(rv+1);
        //}

        data[i] = {x:rx, y:ry, v: rv};
        maxv = Math.max(maxv,rv);
        minv = Math.min(minv,rv);
    }

    if (maxv == -Infinity && minv == Infinity){ //zeros only
        return null;
    }

    return {min:minv,max:maxv,data:data};
};

L.NanocubeLayer.prototype._addTilesFromCenterOut = function (bounds){
    this.max = -Infinity;
    this.min = Infinity;
    L.TileLayer.Canvas.prototype._addTilesFromCenterOut.call(this, bounds);
};
<commit_msg>in the middle of promise fix<commit_after>L.NanocubeLayer = L.TileLayer.Canvas.extend({
    initialize: function(options){
        L.TileLayer.Canvas.prototype.initialize.call(this, options);
        this.model = options.model;
        this.variable = options.variable;
        this.colormap = d3.scale.linear()
            .domain(options.colormap.domain)
            .range(options.colormap.colors);

        this.coarselevels = 1;
        this.smooth = false;

        this.show_count = false;
        this.log = true;
    }
});

L.NanocubeLayer.prototype.toggleLog = function(){
    this.log = !this.log;
    this.redraw();
};

L.NanocubeLayer.prototype.toggleShowCount = function(){
    this.show_count = !this.show_count;
    this.redraw();
};

L.NanocubeLayer.prototype.redraw = function(){
    if (this._map) {
	//this._reset({hard: false});  //no hard resetting
	this._update();
    }
    for (var i in this._tiles) {
	this._redrawTile(this._tiles[i]);
    }
    return this;
};

L.NanocubeLayer.prototype.drawTile = function(canvas, tilePoint, zoom){
    var drill = Math.min(this.variable.maxlevel-zoom,8) - this.coarselevels ;
    drill = Math.max(0,drill);
    drill = Math.min(8,drill);

    var size = Math.pow(2,drill);
    var ntiles = Math.pow(2,zoom);

    //fix negative tiles
    while(tilePoint.x < 0){
        tilePoint.x += ntiles;
    }

    while(tilePoint.y < 0){
        tilePoint.y += ntiles;
    }

    //fix overflow tiles
    while(tilePoint.x > ntiles){
        tilePoint.x -= ntiles;
    }

    while(tilePoint.y > ntiles){
        tilePoint.y -= ntiles;
    }

    //flip y for nanocubes
    var ty = (ntiles-1)-tilePoint.y;

    var tile = new Tile(tilePoint.x,ty,zoom);
    tile.canvas = canvas;
    tile.drill = drill;
    this.tilelist.push(tile);

    /**
    //query
    var tile = new Tile(tilePoint.x,ty,zoom);
    var that = this;
    this.model.tileQuery(this.variable, tile, drill, function(data){
        var result = that.processData(data);

        if(result !=null){
            that.max = Math.max(that.max, result.max);
            that.min = Math.min(that.min, result.min);
            that.renderTile(canvas,size,tilePoint,zoom,result.data);
        }
        else{
            that.renderTile(canvas,size,tilePoint,zoom,null);
        }
    });
    this.tileDrawn(canvas);
     **/
};

L.NanocubeLayer.prototype.renderTile = function(canvas, size,
                                                tilePoint,zoom,data){
    var ctx = canvas.getContext('2d');

    if (data == null){
        var imgBlankData = ctx.createImageData(canvas.width,canvas.height);
        ctx.putImageData(imgBlankData,0,0);

        if (this.show_count){//draw grid box
            this.drawGridCount(ctx,tilePoint,zoom,data);
        }
        return;
    }

    var imgData=ctx.createImageData(size,size);
    var pixels = imgData.data;
    var length = pixels.length;

    if (! this.smooth){ //blocky rendering
        ctx.imageSmoothingEnabled = false;
        ctx.webkitImageSmoothingEnabled = false;
        ctx.mozImageSmoothingEnabled = false;
    }

    //set color
    var that = this;
    var minv = that.min;
    var maxv = that.max;
    if (this.log){
        minv = Math.log(minv+1);
        maxv = Math.log(maxv);
    }

    data.forEach(function(d){
        if(d.v < 1e-6){
            return;
        }

        var v = d.v;
        if (that.log){
            v = Math.log(v+1);
        }

        v = (v-minv)/maxv;
        var color = d3.rgb(that.colormap(v));
        var idx = (imgData.height-1-d.y)*imgData.width + d.x;
        pixels[idx*4]=color.r;
        pixels[idx*4+1]=color.g ;
        pixels[idx*4+2]=color.b;
        pixels[idx*4+3]= v*255*2;
    });

    //set image
    var sc = canvas.width*1.0/size;

    //clear the canvas
    imgBlankData = ctx.createImageData(canvas.width,canvas.height);
    ctx.putImageData(imgBlankData,0,0);

    //scale
    if (sc !=1){
        //create a proxy canvas
        var newCanvas = $('<canvas>')
                .attr("width", imgData.width)
                .attr("height", imgData.height)[0];
        newCanvas.getContext("2d").putImageData(imgData, 0, 0);

        ctx.drawImage(newCanvas,0,0,canvas.width,canvas.height);
    }
    else{
        ctx.putImageData(imgData,0,0);
    }

    if (this.show_count){//draw grid box
        this.drawGridCount(ctx,tilePoint,zoom,data);
    }
};

L.NanocubeLayer.prototype.drawGridCount = function(ctx,tilePoint,zoom,data){
    ctx.lineWidth="0.5";
    ctx.strokeStyle="white";
    ctx.rect(0,0,ctx.canvas.width,ctx.canvas.height);
    ctx.stroke();

    var totalstr =  "("+tilePoint.x + "," + tilePoint.y +","+zoom+")   ";
    if(data != null){
        //Total count
        var total = data.reduce(function(prev,curr){return prev+curr.v;},0);
        totalstr +=  total.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }
    ctx.font="10pt sans-serif";
    ctx.fillStyle="white";
    ctx.fillText(totalstr,10,20);

};

L.NanocubeLayer.prototype.processData = function(bindata){
    if(bindata == null){
        return null;
    }

    var record_size = 10;
    var view = new DataView(bindata);
    var n_records = bindata.byteLength / record_size;
    if (n_records < 1) {
        return null;
    }

    var data = [];
    data.length = n_records;
    var maxv = -Infinity;
    var minv = Infinity;

    for (var i=0; i<n_records; ++i) {
        var rx = view.getUint8( record_size*i+1 );
        var ry = view.getUint8( record_size*i   );
        var rv = view.getFloat64( record_size*i+2, true );
        if (rv < 1e-6){ //skip zeros
            continue;
        }

        data[i] = {x:rx, y:ry, v: rv};
        maxv = Math.max(maxv,rv);
        minv = Math.min(minv,rv);
    }

    if (maxv == -Infinity && minv == Infinity){ //zeros only
        return null;
    }

    return {min:minv,max:maxv,data:data};
};

L.NanocubeLayer.prototype._addTilesFromCenterOut = function(bounds){
    this.tilelist = [];
    L.TileLayer.Canvas.prototype._addTilesFromCenterOut.call(this, bounds);
    var that = this;
    var promises = this.tilelist.map(function(t){
        return that.queryTile(t);
    });
    console.log('prom',promises);
    if promises.length

    var comb = $.when(promises[0],promises[1]);
    comb.done(function(){ console.log("done");});

};

L.NanocubeLayer.prototype.queryTile = function(tile){
    var that = this;
    return $.Deferred(function(dfd){
        that.model.tileQuery(that.variable,tile,tile.drill, function(data){
            var result = that.processData(data);
            if(result !=null){
                that.max = Math.max(that.max,result.max);
                that.min = Math.min(that.min,result.min);
            }
            dfd.resolve();
        });
    }).promise();
};
<|endoftext|>


<commit_before>(function (window, $) {
	$(function() {
		$('.posts .post').addClass('ripple').data('ripple-color', '#bdbdbd');
		$('.ripple').on('mousedown', function (event) {
			event.preventDefault();

			$('.ripple .ripple-effect').remove();

			var $div = $('<div/>'),
				btnOffset = $(this).offset(),
				xPos = event.pageX - btnOffset.left,
				yPos = event.pageY - btnOffset.top;

			$div.addClass('ripple-effect');
			var $ripple = $('.ripple-effect');

			$ripple.css('height', $(this).height());
			$ripple.css('width', $(this).height());
			$div.css({
				top: yPos - ($ripple.height()/2),
				left: xPos - ($ripple.width()/2),
				background: $(this).data('ripple-color')
			}).prependTo($(this));
		});
		$('.ripple').on('mouseup mouseout', function (event) {
			var $ripples = $('.ripple .ripple-effect');
			$ripples.addClass('out');
			window.setTimeout(function()
			{
				$ripples.remove();
			}, 300);
		});
		$('.ripple').on('mouseup', function (event) {
			// Fix hyperlink issue in Firefox
			var href = $(this).children('a').attr('href');
			if(href != "")
			{
				window.setTimeout(function()
				{
					window.location = href
				}, 100);
			}
		});
	});
})(window, jQuery);
<commit_msg>Format ripple.js<commit_after>$(document).on('ready', function() {
	$('.posts .post').addClass('ripple').data('ripple-color', '#bdbdbd');
	$('.ripple').on('mousedown', function (event) {
		event.preventDefault();

		$('.ripple .ripple-effect').remove();

		var $div = $('<div/>'),
			btnOffset = $(this).offset(),
			xPos = event.pageX - btnOffset.left,
			yPos = event.pageY - btnOffset.top;

		$div.addClass('ripple-effect');
		var $ripple = $('.ripple-effect');

		$ripple.css('height', $(this).height());
		$ripple.css('width', $(this).height());
		$div.css({
			top: yPos - ($ripple.height()/2),
			left: xPos - ($ripple.width()/2),
			background: $(this).data('ripple-color')
		}).prependTo($(this));
	});
	$('.ripple').on('mouseup mouseout', function (event) {
		var $ripples = $('.ripple .ripple-effect');
		$ripples.addClass('out');
		window.setTimeout(function()
		{
			$ripples.remove();
		}, 300);
	});
	$('.ripple').on('mouseup', function (event) {
		// Fix hyperlink issue in Firefox
		var href = $(this).children('a').attr('href');
		if(href != "")
		{
			window.setTimeout(function()
			{
				window.location = href
			}, 100);
		}
	});
});
<|endoftext|>


<commit_before>$(document).ready(function () {
  var timeData = [],
    temperatureData = [],
    humidityData = [],
  pm2Data = [],
  pm10Data = [];
 //---------yanji start 1/2------------

  //20170913
  var pm10Data = [],
      pm25Data = [],
      busp2Data = [],
      busp1Data = [];
  var result;
 // android 20170912 23:29
  var humilength = humidityData.length;
  // 20170913
  var templength = temperatureData.length;
  var pm10length = pm10Data.length;
  var pm25length = pm25Data.length;
  var rpmData = [];
  var rpm2Data = [];
   var tempimsi = 0;
   var aaaa = 50;
  //---------yanji end 1/2------------
  document.getElementById("pm2").innerHTML = "50";
  document.getElementById("pm10").innerHTML = "30";
  document.getElementById("temp").innerHTML = "10";
  document.getElementById("humi").innerHTML = "80";
  document.getElementById("rpm").innerHTML = "0";
  document.getElementById("rpm2").innerHTML = "0";
  var data = {
    labels: timeData,
    datasets: [
      {
        fill: false,
        label: 'Temp',
        yAxisID: 'Temp',
        borderColor: "rgba(255, 204, 0, 1)",
        pointBoarderColor: "rgba(255, 204, 0, 1)",
        backgroundColor: "rgba(255, 204, 0, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 204, 0, 1)",
        pointHoverBorderColor: "rgba(255, 204, 0, 1)",
        data: temperatureData
      },
      {
        fill: false,
        label: 'pm2.5',
        yAxisID: 'pm2.5',
        borderColor: "rgba(255, 131, 131, 1)",
        pointBoarderColor: "rgba(255, 131, 131, 1)",
        backgroundColor: "rgba(255, 131, 131, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 131, 131, 1)",
        pointHoverBorderColor: "rgba(255, 131, 131, 1)",
        data: pm2Data
      }
    ]
  }

  var basicOption = {
    title: {
      display: true,
      text: 'Temperature & pm2.5 Real-time Data',
      fontSize: 15
    },
    scales: {
      yAxes: [{
        id: 'Temp',
        type: 'linear',
        scaleLabel: {
          labelString: 'Temp(C)',
          display: true
        },
        position: 'left',
      }, {
          id: 'pm2.5',
          type: 'linear',
          scaleLabel: {
            labelString: 'pm2.5(ug/m3)',
            display: true
          },
          position: 'right'
        }]
    }
  }

  ///////////////////////////////////////////////////////////////////////////////////////////////////

  var data2 = {
    labels: timeData,
    datasets: [
      {
        fill: false,
        label: 'Motor1',
        yAxisID: 'Motor1',
        borderColor: "rgba(0, 84, 255, 1)",
        pointBoarderColor: "rgba(0, 84, 255, 1)",
        backgroundColor: "rgba(0, 84, 255, 0.4)",
        pointHoverBackgroundColor: "rgba(0, 84, 255, 1)",
        pointHoverBorderColor: "rgba(0, 84, 255, 1)",
        data: rpmData
      },
      {
        fill: false,
        label: 'Motor2',
        yAxisID: 'Motor2',
        borderColor: "rgba(29, 219, 22, 1)",
        pointBoarderColor: "rgba(29, 219, 22, 1)",
        backgroundColor: "rgba(29, 219, 22, 0.4)",
        pointHoverBackgroundColor: "rgba(29, 219, 22, 1)",
        pointHoverBorderColor: "rgba(29, 219, 22, 1)",
        data: rpm2Data
      }
    ]
  }

  var basicOption2 = {
    title: {
      display: true,
      text: 'Mortor1 & Mortor2 Real-time Data',
      fontSize: 15
    },
    scales: {
      yAxes: [{
        id: 'Motor1',
        type: 'linear',
        scaleLabel: {
          labelString: 'rpm(r/min)',
          display: true
        },
        position: 'left',
      }, {
          id: 'Motor2',
          type: 'linear',
          scaleLabel: {
            labelString: 'rpm(r/min)',
            display: true
          },
          position: 'right'
        }]
    }
  }

  //////////////////////////////////////////////////////////////////////////////////////////////////////////////

  //Get the context of the canvas element we want to select
  var ctx = document.getElementById("myChart").getContext("2d");
  var optionsNoAnimation = { animation: false }
  var myLineChart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: basicOption
  });
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  var ctx2 = document.getElementById("myChart2").getContext("2d");
  var optionsNoAnimation2 = { animation: false }
  var myLineChart2 = new Chart(ctx2, {
    type: 'line',
    data: data2,
    options: basicOption2
  });
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  var ws = new WebSocket('wss://' + location.host);
  ws.onopen = function () {
    console.log('Successfully connect WebSocket');
  }
  ws.onmessage = function (message) {
    console.log('receive message' + message.data);
    try {
      var obj = JSON.parse(message.data);
      if(!obj.time || !obj.params.pm10) {
        return;
      }
      document.getElementById("pm2").innerHTML = obj.params.pm2;
  	  document.getElementById("pm10").innerHTML = obj.params.pm10;
	  document.getElementById("temp").innerHTML = obj.params.Temperature;
	  document.getElementById("humi").innerHTML = obj.params.Humidity;
	  document.getElementById("rpm").innerHTML = obj.params.rpm;
	  document.getElementById("rpm2").innerHTML = obj.params.rpm2;
	  var time = obj.time;
	  var subS = time.substring(13,19);
	  var hourS = time.substring(11,13);
	  var vv = parseInt(hourS);
	  var timeS = "";
	  vv = vv - 3;
	  if(vv<0)
		{
		  vv = vv + 24;
		}

		if(vv<10)
		{
			timeS = "0" + vv.toString() + subS;
		}
		else
		{
			timeS = vv.toString() + subS;
		}
	if(obj.params.Temperature)
	{
	  timeData.push(timeS);
      temperatureData.push(obj.params.Temperature);
	  tempimsi = obj.params.Temperature;
	}
	else
	{
		timeData.push(timeS);
		var xxx = Math.floor((Math.random() * 3));
		var xxxx = Math.floor((Math.random() * 2)+1);
		if(xxxx == 1)
		{
			temperatureData.push(tempimsi+xxx);
			document.getElementById("temp").innerHTML = tempimsi+xxx;
		}
		else
		{
			temperatureData.push(tempimsi-xxx);
			document.getElementById("temp").innerHTML = tempimsi-xxx;
		}

	}

      // only keep no more than 50 points in the line chart
      const maxLen = 10;
      var len = timeData.length;
      if (len > maxLen) {
        timeData.shift();
        temperatureData.shift();
      }

      if (obj.params.Humidity) {
        humidityData.push(obj.params.Humidity);
      }
      if (humidityData.length > maxLen) {
        humidityData.shift();
      }
	  if (obj.params.pm2) {
		  pm2Data.push(obj.params.pm2);
		  rpmData.push(obj.params.rpm);
		  rpm2Data.push(obj.params.rpm2);
	  }
	  if (pm2Data.length > maxLen)
	  {
		  pm2Data.shift();
	  }

	  if (rpmData.length > maxLen)
	  {
		  rpmData.shift();
	  }
	  if (rpm2Data.length > maxLen)
	  {
		  rpm2Data.shift();
	  }

// yangji, update data Start-------------------------------------------------------

if(obj.params.pm2>100){
  document.getElementById("pm25dis").innerHTML = "아주나쁨";
}else if(obj.params.pm2>50){
  document.getElementById("pm25dis").innerHTML = "나쁨";
}else if(obj.params.pm2>15){
  document.getElementById("pm25dis").innerHTML = "보통";
}else if(obj.params.pm2>0){
  document.getElementById("pm25dis").innerHTML = "좋음";
}
if(obj.params.pm10>150){
  document.getElementById("pm10dis").innerHTML = "아주나쁨";
}else if(obj.params.pm2>80){
  document.getElementById("pm10dis").innerHTML = "나쁨";
}else if(obj.params.pm2>30){
  document.getElementById("pm10dis").innerHTML = "보통";
}else if(obj.params.pm2>0){
  document.getElementById("pm10dis").innerHTML = "좋음";
}

// yangji, update data End-------------------------------------------------------

//graph tag start------------------------------------------------------------------
// if(obj.params.pm2>80){
// 	document.getElementById("pm25dis").innerHTML = "아주나쁨";
// }else if(obj.params.pm2>60){
// 	document.getElementById("pm25dis").innerHTML = "나쁨";
// }else if(obj.params.pm2>40){
// 	document.getElementById("pm25dis").innerHTML = "보통";
// }else if(obj.params.pm2>20){
// 	document.getElementById("pm25dis").innerHTML = "좋음";
// }else if(obj.params.pm2>0){
// 	document.getElementById("pm25dis").innerHTML = "아주좋음";
// }
// 	    if(obj.params.pm10>80){
// 	document.getElementById("pm10dis").innerHTML = "아주나쁨";
// }else if(obj.params.pm2>60){
// 	document.getElementById("pm10dis").innerHTML = "나쁨";
// }else if(obj.params.pm2>40){
// 	document.getElementById("pm10dis").innerHTML = "보통";
// }else if(obj.params.pm2>20){
// 	document.getElementById("pm10dis").innerHTML = "좋음";
// }else if(obj.params.pm2>0){
// 	document.getElementById("pm10dis").innerHTML = "아주좋음";
// }
if(obj.params.Temperature>30){
	document.getElementById("tempdis").innerHTML = "높음";
}else if(obj.params.Temperature>20){
	document.getElementById("tempdis").innerHTML = "쾌적";
}else if(obj.params.Temperature>0){
	document.getElementById("tempdis").innerHTML = "낮음";
}
	    if(obj.params.humi>70){
	document.getElementById("humidis").innerHTML = "습함";
}else if(obj.params.pm2>50){
	document.getElementById("humidis").innerHTML = "쾌적";
}else if(obj.params.pm2>0){
	document.getElementById("humidis").innerHTML = "건조";
}
	    if(obj.params.rpm  >1300){
	document.getElementById("rpm1dis").innerHTML = "강하게";
}else if(obj.params.rpm>1100){
	document.getElementById("rpm1dis").innerHTML = "중간";
}else if(obj.params.rpm>900){
	document.getElementById("rpm1dis").innerHTML = "약하게";
}else if(obj.params.rpm>=0){
	document.getElementById("rpm1dis").innerHTML = "정지";
}
	    	    if(obj.params.rpm2>1300){
	document.getElementById("rpm2dis").innerHTML = "";
}else if(obj.params.rpm2>1100){
	document.getElementById("rpm2dis").innerHTML = "중간";
}else if(obj.params.rpm2>900){
	document.getElementById("rpm2dis").innerHTML = "약하게";
}else if(obj.params.rpm2>=0){
	document.getElementById("rpm2dis").innerHTML = "정지";
}
//graph tag end-------------------------------------------------------------------
 myLineChart2.update();

      myLineChart.update();

 //---------yanji start 2/2------------
 //20170913 pm Data push
      pm10Data.push(obj.params.pm10);
      pm25Data.push(obj.params.pm2);

      //android 20170912 23:29
//       if(humilength==0 || templength == 0 || pm10length ==0 || pm25length ==0){

//            }
//           }else{
//             humilength = humidityData.length;
//             templength = temperatureData.length;
//             pm10length = pm10Data.length;
//             pm25length = pm25Data.length;
//            insertDatas(pm25Data[pm25length],humidityData[humilength],temperatureData[templength],humidityData[humilength]);
//         }
      //20170913
     if((pm25length<pm25Data.length || pm25length == pm25Data.length)&&(pm10length<pm10Data.length || pm10length == pm10Data.length)){
          pm25length = pm25Data.length;
          pm10length = pm10Data.length;
          insertDatas(pm25Data[pm25length-1],pm10Data[pm10length-1]);

          }

      //android 20170912 23:29
      function insertDatas(p2,p1){
         var p2State;
         if(p2<16){
           p2State = "좋음";
         }else if(p2<51){
           p2State = "보통";
         }else if(p2<101){
           p2State = "나쁨";
         }else{
           p2State = "매우나쁨";
         }
         A2.showResult2(p2,p1,p2State);
      }

//---------yanji end 2/2------------

    } catch (err) {
      console.error(err);
    }
  }
});
<commit_msg>Update index.js<commit_after>$(document).ready(function () {
  var timeData = [],
    temperatureData = [],
    humidityData = [],
  pm2Data = [],
  pm10Data = [];
 //---------yanji start 1/2------------

  //20170913
  var pm10Data = [],
      pm25Data = [],
      busp2Data = [],
      busp1Data = [];
  var result;
 // android 20170912 23:29
  var humilength = humidityData.length;
  // 20170913
  var templength = temperatureData.length;
  var pm10length = pm10Data.length;
  var pm25length = pm25Data.length;
  var rpmData = [];
  var rpm2Data = [];
   var tempimsi = 0;
   var humiimsi = 0;
   var aaaa = 50;
  //---------yanji end 1/2------------
  document.getElementById("pm2").innerHTML = "50";
  document.getElementById("pm10").innerHTML = "30";
  document.getElementById("temp").innerHTML = "10";
  document.getElementById("humi").innerHTML = "80";
  document.getElementById("rpm").innerHTML = "0";
  document.getElementById("rpm2").innerHTML = "0";
  var data = {
    labels: timeData,
    datasets: [
      {
        fill: false,
        label: 'Temp',
        yAxisID: 'Temp',
        borderColor: "rgba(255, 204, 0, 1)",
        pointBoarderColor: "rgba(255, 204, 0, 1)",
        backgroundColor: "rgba(255, 204, 0, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 204, 0, 1)",
        pointHoverBorderColor: "rgba(255, 204, 0, 1)",
        data: temperatureData
      },
      {
        fill: false,
        label: 'pm2.5',
        yAxisID: 'pm2.5',
        borderColor: "rgba(255, 131, 131, 1)",
        pointBoarderColor: "rgba(255, 131, 131, 1)",
        backgroundColor: "rgba(255, 131, 131, 0.4)",
        pointHoverBackgroundColor: "rgba(255, 131, 131, 1)",
        pointHoverBorderColor: "rgba(255, 131, 131, 1)",
        data: pm2Data
      }
    ]
  }

  var basicOption = {
    title: {
      display: true,
      text: 'Temperature & pm2.5 Real-time Data',
      fontSize: 15
    },
    scales: {
      yAxes: [{
        id: 'Temp',
        type: 'linear',
        scaleLabel: {
          labelString: 'Temp(C)',
          display: true
        },
        position: 'left',
      }, {
          id: 'pm2.5',
          type: 'linear',
          scaleLabel: {
            labelString: 'pm2.5(ug/m3)',
            display: true
          },
          position: 'right'
        }]
    }
  }

  ///////////////////////////////////////////////////////////////////////////////////////////////////

  var data2 = {
    labels: timeData,
    datasets: [
      {
        fill: false,
        label: 'Motor1',
        yAxisID: 'Motor1',
        borderColor: "rgba(0, 84, 255, 1)",
        pointBoarderColor: "rgba(0, 84, 255, 1)",
        backgroundColor: "rgba(0, 84, 255, 0.4)",
        pointHoverBackgroundColor: "rgba(0, 84, 255, 1)",
        pointHoverBorderColor: "rgba(0, 84, 255, 1)",
        data: rpmData
      },
      {
        fill: false,
        label: 'Motor2',
        yAxisID: 'Motor2',
        borderColor: "rgba(29, 219, 22, 1)",
        pointBoarderColor: "rgba(29, 219, 22, 1)",
        backgroundColor: "rgba(29, 219, 22, 0.4)",
        pointHoverBackgroundColor: "rgba(29, 219, 22, 1)",
        pointHoverBorderColor: "rgba(29, 219, 22, 1)",
        data: rpm2Data
      }
    ]
  }

  var basicOption2 = {
    title: {
      display: true,
      text: 'Mortor1 & Mortor2 Real-time Data',
      fontSize: 15
    },
    scales: {
      yAxes: [{
        id: 'Motor1',
        type: 'linear',
        scaleLabel: {
          labelString: 'rpm(r/min)',
          display: true
        },
        position: 'left',
      }, {
          id: 'Motor2',
          type: 'linear',
          scaleLabel: {
            labelString: 'rpm(r/min)',
            display: true
          },
          position: 'right'
        }]
    }
  }

  //////////////////////////////////////////////////////////////////////////////////////////////////////////////

  //Get the context of the canvas element we want to select
  var ctx = document.getElementById("myChart").getContext("2d");
  var optionsNoAnimation = { animation: false }
  var myLineChart = new Chart(ctx, {
    type: 'line',
    data: data,
    options: basicOption
  });
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  var ctx2 = document.getElementById("myChart2").getContext("2d");
  var optionsNoAnimation2 = { animation: false }
  var myLineChart2 = new Chart(ctx2, {
    type: 'line',
    data: data2,
    options: basicOption2
  });
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  var ws = new WebSocket('wss://' + location.host);
  ws.onopen = function () {
    console.log('Successfully connect WebSocket');
  }
  ws.onmessage = function (message) {
    console.log('receive message' + message.data);
    try {
      var obj = JSON.parse(message.data);
      if(!obj.time || !obj.params.pm10) {
        return;
      }
      document.getElementById("pm2").innerHTML = obj.params.pm2;
  	  document.getElementById("pm10").innerHTML = obj.params.pm10;
	  document.getElementById("temp").innerHTML = obj.params.Temperature;
	  document.getElementById("humi").innerHTML = obj.params.Humidity;
	  document.getElementById("rpm").innerHTML = obj.params.rpm;
	  document.getElementById("rpm2").innerHTML = obj.params.rpm2;
	  var time = obj.time;
	  var subS = time.substring(13,19);
	  var hourS = time.substring(11,13);
	  var vv = parseInt(hourS);
	  var timeS = "";
	  vv = vv - 3;
	  if(vv<0)
		{
		  vv = vv + 24;
		}

		if(vv<10)
		{
			timeS = "0" + vv.toString() + subS;
		}
		else
		{
			timeS = vv.toString() + subS;
		}
	if(obj.params.Temperature)
	{
	  timeData.push(timeS);
      temperatureData.push(obj.params.Temperature);
	  tempimsi = obj.params.Temperature;
	  humiimsi = obj.params.Humidity;
	}
	else
	{
		timeData.push(timeS);
		document.getElementById("humi").innerHTML = humiimsi;
		var xxx = Math.floor((Math.random() * 3));
		var xxxx = Math.floor((Math.random() * 2) + 1);
		if(xxxx == 1)
		{
			temperatureData.push(tempimsi+xxx);
			document.getElementById("temp").innerHTML = tempimsi+xxx;
		}
		else
		{
			temperatureData.push(tempimsi-xxx);
			document.getElementById("temp").innerHTML = tempimsi-xxx;
		}

	}

      // only keep no more than 50 points in the line chart
      const maxLen = 10;
      var len = timeData.length;
      if (len > maxLen) {
        timeData.shift();
        temperatureData.shift();
      }

      if (obj.params.Humidity) {
        humidityData.push(obj.params.Humidity);
      }
      if (humidityData.length > maxLen) {
        humidityData.shift();
      }
	  if (obj.params.pm2) {
		  pm2Data.push(obj.params.pm2);
		  rpmData.push(obj.params.rpm);
		  rpm2Data.push(obj.params.rpm2);
	  }
	  if (pm2Data.length > maxLen)
	  {
		  pm2Data.shift();
	  }

	  if (rpmData.length > maxLen)
	  {
		  rpmData.shift();
	  }
	  if (rpm2Data.length > maxLen)
	  {
		  rpm2Data.shift();
	  }

// yangji, update data Start-------------------------------------------------------

if(obj.params.pm2>100){
  document.getElementById("pm25dis").innerHTML = "아주나쁨";
}else if(obj.params.pm2>50){
  document.getElementById("pm25dis").innerHTML = "나쁨";
}else if(obj.params.pm2>15){
  document.getElementById("pm25dis").innerHTML = "보통";
}else if(obj.params.pm2>0){
  document.getElementById("pm25dis").innerHTML = "좋음";
}
if(obj.params.pm10>150){
  document.getElementById("pm10dis").innerHTML = "아주나쁨";
}else if(obj.params.pm2>80){
  document.getElementById("pm10dis").innerHTML = "나쁨";
}else if(obj.params.pm2>30){
  document.getElementById("pm10dis").innerHTML = "보통";
}else if(obj.params.pm2>0){
  document.getElementById("pm10dis").innerHTML = "좋음";
}

// yangji, update data End-------------------------------------------------------

//graph tag start------------------------------------------------------------------
// if(obj.params.pm2>80){
// 	document.getElementById("pm25dis").innerHTML = "아주나쁨";
// }else if(obj.params.pm2>60){
// 	document.getElementById("pm25dis").innerHTML = "나쁨";
// }else if(obj.params.pm2>40){
// 	document.getElementById("pm25dis").innerHTML = "보통";
// }else if(obj.params.pm2>20){
// 	document.getElementById("pm25dis").innerHTML = "좋음";
// }else if(obj.params.pm2>0){
// 	document.getElementById("pm25dis").innerHTML = "아주좋음";
// }
// 	    if(obj.params.pm10>80){
// 	document.getElementById("pm10dis").innerHTML = "아주나쁨";
// }else if(obj.params.pm2>60){
// 	document.getElementById("pm10dis").innerHTML = "나쁨";
// }else if(obj.params.pm2>40){
// 	document.getElementById("pm10dis").innerHTML = "보통";
// }else if(obj.params.pm2>20){
// 	document.getElementById("pm10dis").innerHTML = "좋음";
// }else if(obj.params.pm2>0){
// 	document.getElementById("pm10dis").innerHTML = "아주좋음";
// }
if(obj.params.Temperature>30){
	document.getElementById("tempdis").innerHTML = "높음";
}else if(obj.params.Temperature>20){
	document.getElementById("tempdis").innerHTML = "쾌적";
}else if(obj.params.Temperature>0){
	document.getElementById("tempdis").innerHTML = "낮음";
}
	    if(obj.params.humi>70){
	document.getElementById("humidis").innerHTML = "습함";
}else if(obj.params.pm2>50){
	document.getElementById("humidis").innerHTML = "쾌적";
}else if(obj.params.pm2>0){
	document.getElementById("humidis").innerHTML = "건조";
}
	    if(obj.params.rpm  >1300){
	document.getElementById("rpm1dis").innerHTML = "강하게";
}else if(obj.params.rpm>1100){
	document.getElementById("rpm1dis").innerHTML = "중간";
}else if(obj.params.rpm>900){
	document.getElementById("rpm1dis").innerHTML = "약하게";
}else if(obj.params.rpm>=0){
	document.getElementById("rpm1dis").innerHTML = "정지";
}
	    	    if(obj.params.rpm2>1300){
	document.getElementById("rpm2dis").innerHTML = "";
}else if(obj.params.rpm2>1100){
	document.getElementById("rpm2dis").innerHTML = "중간";
}else if(obj.params.rpm2>900){
	document.getElementById("rpm2dis").innerHTML = "약하게";
}else if(obj.params.rpm2>=0){
	document.getElementById("rpm2dis").innerHTML = "정지";
}
//graph tag end-------------------------------------------------------------------
 myLineChart2.update();

      myLineChart.update();

 //---------yanji start 2/2------------
 //20170913 pm Data push
      pm10Data.push(obj.params.pm10);
      pm25Data.push(obj.params.pm2);

      //android 20170912 23:29
//       if(humilength==0 || templength == 0 || pm10length ==0 || pm25length ==0){

//            }
//           }else{
//             humilength = humidityData.length;
//             templength = temperatureData.length;
//             pm10length = pm10Data.length;
//             pm25length = pm25Data.length;
//            insertDatas(pm25Data[pm25length],humidityData[humilength],temperatureData[templength],humidityData[humilength]);
//         }
      //20170913
     if((pm25length<pm25Data.length || pm25length == pm25Data.length)&&(pm10length<pm10Data.length || pm10length == pm10Data.length)){
          pm25length = pm25Data.length;
          pm10length = pm10Data.length;
          insertDatas(pm25Data[pm25length-1],pm10Data[pm10length-1]);

          }

      //android 20170912 23:29
      function insertDatas(p2,p1){
         var p2State;
         if(p2<16){
           p2State = "좋음";
         }else if(p2<51){
           p2State = "보통";
         }else if(p2<101){
           p2State = "나쁨";
         }else{
           p2State = "매우나쁨";
         }
         A2.showResult2(p2,p1,p2State);
      }

//---------yanji end 2/2------------

    } catch (err) {
      console.error(err);
    }
  }
});
<|endoftext|>


<commit_before>longestPalindromeSubstring.js
<commit_msg>add desc<commit_after>// Given a string S, find the longest palindromic substring in S.
// You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

<|endoftext|>


<commit_before>var createMap = function() {
  return L.map("map", {
    center: [47, 7],
    zoom: 4,
    zoomControl: false
  }).addControl(L.control.zoom({
    position: "topright"
  })).addLayer(L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
    attribution: 'OpenStreetMap'
  }));
};

var createMarkers = function(sites, { onClick: onClickCallback }) {
  var group = L.markerClusterGroup({
    showCoverageOnHover: false,
    //chunkedLoading: true, // FIXME bug if map.setView() is called at the same time
  });

  // Add markers on map
  var markers = sites.map(function(site) {
    var marker = L.marker([site.latdd, site.londd], {
      icon: L.divIcon({
        iconSize: [16, 16],
        iconAnchor: [8, 8]
      })
    });

    if (onClickCallback) {
      marker.on("click", function(e) {
        onClickCallback(site);
      });
    }

    return marker;
  });

  group.addLayers(markers);

  return group;
};

var fetchSamples = function({ sigle, types, limit }, callback) {
  var querySite = sigle.toLowerCase();
  var queryTypes = types.join(",").toLowerCase();
  var path = "/sites/" + querySite + "/samples?types=" + queryTypes;

  Vue.http.get(path).then(response => {
    return response.json();
  }).then(json => {
    var counts = json.reduce(function(acc, row) {
      acc[row.varname] = (acc[row.varname] || 0) + row.count;
      return acc;
    }, {});

    // Keep only the n taxons with the most pollen count
    var datum = Object.keys(counts).map(function(varname, i) {
      return {
        key: varname,
        values: json.filter(function(row) { return row.varname == varname; }),
        _count: counts[varname]
      };
    }).sort(function(a, b) {
      return b._count - a._count;
    }).slice(0, limit).map(function(row, i) {
      row.color = "hsl(" + i * 360 / limit + ", 50%, 60%)";
      row.values = row.values.map(function(value) {
        return { x: value.agebp, y: value.count };
      });
      return row;
    });
    callback(null, datum);
  });
};

/*
 * var datum = [
 *   {
 *     key: "Quercus", // Taxon name
 *     color: "hsl(0, 50%, 60%),
 *     values: [
 *       { x: 1000, y: 42 }, // `x` is 'Year cal BP'; `y` is 'Pollen Count'
 *       { x: 2000, y: 25 },
 *       ...
 *     ]
 *   },
 *   ...
 * ]
 *
 */
var createChart = function(datum) {
  nv.addGraph(function() {
    var chart = nv.models.lineChart().options({
      duration: 300,
      useInteractiveGuideline: true
    });

    chart.interpolate("monotone");

    // FIXME: only work for xAxis and not yAxis
    //chart.padData(true);
    //chart.padDataOuter(1);

    chart.margin({ "top": 10, "right": 10 });

    chart.xAxis
      .axisLabel('Year cal BP')
      .showMaxMin(false)
      .tickPadding(5)
      .tickFormat(d3.format(',r'));

    chart.yAxis
      .axisLabel('Pollen Count')
      .showMaxMin(false)
      .tickPadding(5)
      .tickFormat(d3.format(',r'));

    // Add new chart
    d3.select('#nvd3-container').append('svg')
      .datum(datum)
      .call(chart);

    //Update the chart when window resizes.
    nv.utils.windowResize(function() {
      chart.update();
    });

    return chart;
  });
};

var destroyChart = function() {
  d3.select("#nvd3-container svg").remove();
  d3.select(".nvtooltip").remove();
};

Vue.component("site-info", function (resolve, reject) {
  Vue.http.get("/partials/sites/info.hbs").then(response => {
    return response.text();
  }).then(text => {
    resolve({
      template: text,
      props: ["site"]
    });
  });
});

var router = new VueRouter({
  mode: "history",
  routes: [
    {
      name: "sites",
      path: "/sites"
    },
    {
      name: "site",
      path: "/sites/:sigle"
    }
  ]
});

var vue = new Vue({
  el: "#app",
  router: router,
  data: {
    selectSite: "",
    selectTypes: ["TRSH"],
    selectLimit: 3,
    sites: [],
    site: undefined
  },
  mounted: function() { // Leaflet requires `mounted` instead of `created`
    this.map = createMap(); // TODO: Create map later to avoid `setView()`

    this.$http.get("/sites").then(response => {
      return response.json();
    }).then(json => {
      this.sites = json;

      var vm = this;
      var markers = createMarkers(json, {
        onClick: function(site) {
          vm.selectSite = site.sigle;
        }
      });

      this.map.addLayer(markers);
      if (this.$route.name == "site") {
        this.selectSite = this.$route.params.sigle.toUpperCase();
      } // TODO: Create map in else case and below in place of setView
    });
  },
  watch: {
    selectSite: function(newSite) {
      var path = "/sites/" + newSite.toLowerCase();
      this.$http.get(path).then(response => {
        return response.json();
      }).then(json => {
        router.push(path);
        this.site = json;

        // FIXME: This bug when chunkedLoading of markers is true
        this.map.setView([json.latdd, json.londd], 9);

        this.updateChart();
      });
    },
    selectTypes: function(newTypes) {
      if (this.site) {
        this.updateChart();
      }
    },
    selectLimit: function(newLimit) {
      if (this.site) {
        this.updateChart();
      }
    }
  },
  methods: {
    updateChart() {
      destroyChart();
      var params = {
        sigle: this.selectSite,
        types: this.selectTypes,
        limit: this.selectLimit
      };
      fetchSamples(params, function(err, samples) {
        createChart(samples);
      });
    }
  }
});
<commit_msg>Don't set view if clicked on map<commit_after>var createMap = function() {
  return L.map("map", {
    center: [47, 7],
    zoom: 4,
    zoomControl: false
  }).addControl(L.control.zoom({
    position: "topright"
  })).addLayer(L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
    attribution: 'OpenStreetMap'
  }));
};

var createMarkers = function(sites, { onClick: onClickCallback }) {
  var group = L.markerClusterGroup({
    showCoverageOnHover: false,
    //chunkedLoading: true, // FIXME bug if map.setView() is called at the same time
  });

  // Add markers on map
  var markers = sites.map(function(site) {
    var marker = L.marker([site.latdd, site.londd], {
      icon: L.divIcon({
        iconSize: [16, 16],
        iconAnchor: [8, 8]
      })
    });

    if (onClickCallback) {
      marker.on("click", function(e) {
        onClickCallback(site);
      });
    }

    return marker;
  });

  group.addLayers(markers);

  return group;
};

var fetchSamples = function({ sigle, types, limit }, callback) {
  var querySite = sigle.toLowerCase();
  var queryTypes = types.join(",").toLowerCase();
  var path = "/sites/" + querySite + "/samples?types=" + queryTypes;

  Vue.http.get(path).then(response => {
    return response.json();
  }).then(json => {
    var counts = json.reduce(function(acc, row) {
      acc[row.varname] = (acc[row.varname] || 0) + row.count;
      return acc;
    }, {});

    // Keep only the n taxons with the most pollen count
    var datum = Object.keys(counts).map(function(varname, i) {
      return {
        key: varname,
        values: json.filter(function(row) { return row.varname == varname; }),
        _count: counts[varname]
      };
    }).sort(function(a, b) {
      return b._count - a._count;
    }).slice(0, limit).map(function(row, i) {
      row.color = "hsl(" + i * 360 / limit + ", 50%, 60%)";
      row.values = row.values.map(function(value) {
        return { x: value.agebp, y: value.count };
      });
      return row;
    });
    callback(null, datum);
  });
};

/*
 * var datum = [
 *   {
 *     key: "Quercus", // Taxon name
 *     color: "hsl(0, 50%, 60%),
 *     values: [
 *       { x: 1000, y: 42 }, // `x` is 'Year cal BP'; `y` is 'Pollen Count'
 *       { x: 2000, y: 25 },
 *       ...
 *     ]
 *   },
 *   ...
 * ]
 *
 */
var createChart = function(datum) {
  nv.addGraph(function() {
    var chart = nv.models.lineChart().options({
      duration: 300,
      useInteractiveGuideline: true
    });

    chart.interpolate("monotone");

    // FIXME: only work for xAxis and not yAxis
    //chart.padData(true);
    //chart.padDataOuter(1);

    chart.margin({ "top": 10, "right": 10 });

    chart.xAxis
      .axisLabel('Year cal BP')
      .showMaxMin(false)
      .tickPadding(5)
      .tickFormat(d3.format(',r'));

    chart.yAxis
      .axisLabel('Pollen Count')
      .showMaxMin(false)
      .tickPadding(5)
      .tickFormat(d3.format(',r'));

    // Add new chart
    d3.select('#nvd3-container').append('svg')
      .datum(datum)
      .call(chart);

    //Update the chart when window resizes.
    nv.utils.windowResize(function() {
      chart.update();
    });

    return chart;
  });
};

var destroyChart = function() {
  d3.select("#nvd3-container svg").remove();
  d3.select(".nvtooltip").remove();
};

Vue.component("site-info", function (resolve, reject) {
  Vue.http.get("/partials/sites/info.hbs").then(response => {
    return response.text();
  }).then(text => {
    resolve({
      template: text,
      props: ["site"]
    });
  });
});

var router = new VueRouter({
  mode: "history",
  routes: [
    {
      name: "sites",
      path: "/sites"
    },
    {
      name: "site",
      path: "/sites/:sigle"
    }
  ]
});

var vue = new Vue({
  el: "#app",
  router: router,
  data: {
    clickedMarker: false,
    selectSite: "",
    selectTypes: ["TRSH"],
    selectLimit: 3,
    sites: [],
    site: undefined
  },
  mounted: function() { // Leaflet requires `mounted` instead of `created`
    this.map = createMap(); // TODO: Create map later to avoid `setView()`

    this.$http.get("/sites").then(response => {
      return response.json();
    }).then(json => {
      this.sites = json;

      var vm = this;
      var markers = createMarkers(json, {
        onClick: function(site) {
          vm.selectSite = site.sigle;
          vm.clickedMarker = true;
        }
      });

      this.map.addLayer(markers);
      if (this.$route.name == "site") {
        this.selectSite = this.$route.params.sigle.toUpperCase();
      } // TODO: Create map in else case and below in place of setView
    });
  },
  watch: {
    selectSite: function(newSite) {
      var path = "/sites/" + newSite.toLowerCase();
      this.$http.get(path).then(response => {
        return response.json();
      }).then(json => {
        router.push(path);
        this.site = json;

        if (!this.clickedMarker) {
          // FIXME: setView() will cause a bug when chunkedLoading of markers is true
          this.map.setView([json.latdd, json.londd], 9);
        }
        this.clickedMarker = false;

        this.updateChart();
      });
    },
    selectTypes: function(newTypes) {
      if (this.site) {
        this.updateChart();
      }
    },
    selectLimit: function(newLimit) {
      if (this.site) {
        this.updateChart();
      }
    }
  },
  methods: {
    updateChart() {
      destroyChart();
      var params = {
        sigle: this.selectSite,
        types: this.selectTypes,
        limit: this.selectLimit
      };
      fetchSamples(params, function(err, samples) {
        createChart(samples);
      });
    }
  }
});
<|endoftext|>


<commit_before>require('babel-register');
const os = require('os');

const dotenv = require('dotenv');

dotenv.config();
dotenv.config({path: '.env.default'});

// eslint-disable-next-line prefer-destructuring
const argv = require('yargs').argv;

const uuid = require('uuid');

const {inject} = require('./scripts/tests/openh264');
const beforeSuite = require('./scripts/tests/beforeSuite');

const browser = process.env.BROWSER || 'chrome';
const platform = process.env.PLATFORM || 'mac 10.12';
const tunnelId = uuid.v4();
const port = process.env.PORT || 4567;
const {suite} = argv || 'integration';
const screenResolutionMac = '1920x1440';
const screenResolutionWin = '1920x1080';
const screenResolution = platform.toLowerCase().includes('os x') || platform === 'darwin' || platform.includes('mac') ? screenResolutionMac : screenResolutionWin;

const chromeCapabilities = {
  browserName: 'chrome',
  name: `react-widget-${suite}`,
  chromeOptions: {
    args: [
      '--use-fake-device-for-media-stream',
      '--use-fake-ui-for-media-stream',
      '--disable-infobars'
    ],
    prefs: {
      'profile.default_content_setting_values.notifications': 2
    }
  },
  idleTimeout: 300,
  commandTimeout: 600,
  maxDuration: 3600,
  seleniumVersion: '3.4.0',
  screenResolution,
  platform
};
const firefoxCapabilities = {
  browserName: 'firefox',
  name: `react-widget-${suite}`,
  idleTimeout: 300,
  maxDuration: 3600,
  seleniumVersion: '3.4.0',
  screenResolution,
  platform
};
let mochaTimeout = 60000;

if (process.env.DEBUG_JOURNEYS) {
  mochaTimeout = 99999999;
}
if (process.env.SAUCE) {
  mochaTimeout = 120000;
}
const services = [];
services.push('firefox-profile');
if (process.env.SAUCE) {
  services.push('sauce');
}
else {
  services.push('selenium-standalone');
}
if (!process.env.TAP) {
  services.push('static-server');
}

exports.config = {
  seleniumInstallArgs: {version: '3.4.0'},
  seleniumArgs: {version: '3.4.0'},
  //
  // ==================
  // Specify Test Files
  // ==================
  // Define which test specs should run. The pattern is relative to the directory
  // from which `wdio` was called. Notice that, if you are calling `wdio` from an
  // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
  // directory is where your package.json resides, so `wdio` will be called from there.
  //
  specs: ['./test/journeys/specs/**/*.js'],
  suites: {
    tap: [
      './test/journeys/specs/tap/**/*.js'
    ],
    oneOnOne: [
      './test/journeys/specs/oneOnOne/dataApi/basic.js',
      './test/journeys/specs/oneOnOne/dataApi/features.js',
      './test/journeys/specs/oneOnOne/dataApi/meet.js',
      './test/journeys/specs/oneOnOne/dataApi/messaging.js',
      './test/journeys/specs/oneOnOne/dataApi/startup-settings.js',
      './test/journeys/specs/oneOnOne/global/basic.js',
      './test/journeys/specs/oneOnOne/global/features.js',
      './test/journeys/specs/oneOnOne/global/meet.js',
      './test/journeys/specs/oneOnOne/global/messaging.js'
    ],
    space: [
      './test/journeys/specs/space/dataApi/basic.js',
      './test/journeys/specs/space/dataApi/meet.js',
      './test/journeys/specs/space/dataApi/messaging.js',
      './test/journeys/specs/space/dataApi/startup-settings.js',
      './test/journeys/specs/space/global/basic.js',
      './test/journeys/specs/space/global/meet.js',
      './test/journeys/specs/space/global/messaging.js',
      './test/journeys/specs/space/featureFlags.js'
    ],
    recents: [
      './test/journeys/specs/recents/dataApi/basic.js',
      './test/journeys/specs/recents/global/basic.js'
    ],
    multiple: [
      './test/journeys/specs/multiple/index.js'
    ],
    integration: [
      './test/journeys/specs/multiple/index.js',
      './test/journeys/specs/oneOnOne/dataApi/basic.js',
      './test/journeys/specs/oneOnOne/dataApi/features.js',
      './test/journeys/specs/oneOnOne/dataApi/meet.js',
      './test/journeys/specs/oneOnOne/dataApi/messaging.js',
      './test/journeys/specs/oneOnOne/dataApi/startup-settings.js',
      './test/journeys/specs/oneOnOne/global/basic.js',
      './test/journeys/specs/oneOnOne/global/features.js',
      './test/journeys/specs/oneOnOne/global/meet.js',
      './test/journeys/specs/oneOnOne/global/messaging.js',
      './test/journeys/specs/recents/dataApi/basic.js',
      './test/journeys/specs/recents/global/basic.js',
      './test/journeys/specs/space/dataApi/basic.js',
      './test/journeys/specs/space/dataApi/meet.js',
      './test/journeys/specs/space/dataApi/messaging.js',
      './test/journeys/specs/space/dataApi/startup-settings.js',
      './test/journeys/specs/space/global/basic.js',
      './test/journeys/specs/space/global/meet.js',
      './test/journeys/specs/space/global/messaging.js',
      './test/journeys/specs/space/featureFlags.js'
    ]
  },
  // Patterns to exclude.
  exclude: [],
  //
  // ============
  // Capabilities
  // ============
  // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
  // time. Depending on the number of capabilities, WebdriverIO launches several test
  // sessions. Within your capabilities you can overwrite the spec and exclude options in
  // order to group specific specs to a specific capability.
  //
  // First, you can define how many instances should be started at the same time. Let's
  // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
  // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
  // files and you set maxInstances to 10, all spec files will get tested at the same time
  // and 30 processes will get spawned. The property handles how many capabilities
  // from the same test should run tests.
  //
  //
  // If you have trouble getting all important capabilities together, check out the
  // Sauce Labs platform configurator - a great tool to configure your capabilities:
  // https://docs.saucelabs.com/reference/platforms-configurator
  //
  capabilities: browser === 'chrome' ? {
    browserLocal: {
      desiredCapabilities: chromeCapabilities
    },
    browserRemote: {
      desiredCapabilities: chromeCapabilities
    }
  } : {
    browserLocal: {
      desiredCapabilities: firefoxCapabilities
    },
    browserRemote: {
      desiredCapabilities: firefoxCapabilities
    }
  },
  //
  // ===================
  // Test Configurations
  // ===================
  // Define all options that are relevant for the WebdriverIO instance here
  //
  // By default WebdriverIO commands are executed in a synchronous way using
  // the wdio-sync package. If you still want to run your tests in an async way
  // e.g. using promises you can set the sync option to false.
  sync: true,
  //
  // Level of logging verbosity: silent | verbose | command | data | result | error
  logLevel: 'silent',
  //
  // Enables colors for log output.
  coloredLogs: true,
  //
  // If you only want to run your tests until a specific amount of tests have failed use
  // bail (default is 0 - don't bail, run all tests).
  bail: 1,
  //
  // Saves a screenshot to a given path if a command fails.
  // screenshotPath: './errorShots/',
  //
  // Set a base URL in order to shorten url command calls. If your url parameter starts
  // with "/", then the base url gets prepended.
  baseUrl: process.env.TAP ? 'https://code.s4d.io' : `http://localhost:${port}`,
  //
  // Default timeout for all waitFor* commands.
  waitforTimeout: 120000,
  //
  // Default timeout in milliseconds for request
  // if Selenium Grid doesn't send response
  connectionRetryTimeout: 90000,
  //
  // Default request retries count
  connectionRetryCount: 3,
  //
  // Initialize the browser instance with a WebdriverIO plugin. The object should have the
  // plugin name as key and the desired plugin options as properties. Make sure you have
  // the plugin installed before running any tests. The following plugins are currently
  // available:
  // WebdriverCSS: https://github.com/webdriverio/webdrivercss
  // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
  // Browserevent: https://github.com/webdriverio/browserevent
  // plugins: {
  //   webdrivercss: {
  //     screenshotRoot: 'my-shots',
  //     failedComparisonsRoot: 'diffs',
  //     misMatchTolerance: 0.05,
  //     screenWidth: [320,480,640,1024]
  //   },
  //   webdriverrtc: {},
  //   browserevent: {}
  // },
  //
  // Test runner services
  // Services take over a specific job you don't want to take care of. They enhance
  // your test setup with almost no effort. Unlike plugins, they don't add new
  // commands. Instead, they hook themselves up into the test process.
  services,
  //
  // Framework you want to run your specs with.
  // The following are supported: Mocha, Jasmine, and Cucumber
  // see also: http://webdriver.io/guide/testrunner/frameworks.html
  //
  // Make sure you have the wdio adapter package for the specific framework installed
  // before running any tests.
  framework: 'mocha',
  //
  // Test reporter for stdout.
  // The only one supported by default is 'dot'
  // see also: http://webdriver.io/guide/testrunner/reporters.html
  // NOTE: Omitting `xunit` for now. We can revisit that on another pass
  reporters: ['spec', 'junit'],
  reporterOptions: {
    junit: {
      outputDir: './reports/junit/wdio/',
      outputFileFormat() {
        return `results-${suite}-${browser}-${platform}.xml`;
      },
      packageName: `${suite}-${browser}-${platform}`
    }
  },

  //
  // Options to be passed to Mocha.
  // See the full list at http://mochajs.org/
  mochaOpts: {
    ui: 'bdd',
    timeout: mochaTimeout,
    bail: 1
  },

  // =====
  // Hooks
  // =====
  beforeSuite,

  // Static Server setup
  staticServerFolders: [
    {mount: '/dist-space', path: './packages/node_modules/@ciscospark/widget-space/dist'},
    {mount: '/dist-recents', path: './packages/node_modules/@ciscospark/widget-recents/dist'},
    {mount: '/', path: './test/journeys/server/'},
    {mount: '/axe-core', path: './node_modules/axe-core/'}
  ],
  staticServerPort: port,
  onPrepare(config, capabilities) {
    const defs = [
      capabilities.browserRemote.desiredCapabilities,
      capabilities.browserLocal.desiredCapabilities
    ];

    const build = process.env.BUILD_NUMBER || `local-${process.env.USER}-wdio-${Date.now()}`;
    /* eslint-disable no-param-reassign */
    defs.forEach((d) => {
      if (process.env.SAUCE) {
        d.build = build;
        // Set the base to SauceLabs so that inject() does its thing.
        d.base = 'SauceLabs';

        d.version = d.version || 'latest';
        d.platform = d.platform || 'OS X 10.12';
      }
      else {
        // Copy the base over so that inject() does its thing.
        d.base = d.browserName;
        d.platform = os.platform();
      }
    });
    /* eslint-enable no-param-reassign */

    return inject(defs)
      .then(() => {
        // Remove the base because it's not actually a selenium property
        defs.forEach((d) => Reflect.deleteProperty(d, 'base'));
      });
  }
};

if (process.env.SAUCE) {
  exports.config = Object.assign(exports.config, {
    deprecationWarnings: false, // Deprecation warnings on sauce just make the logs noisy
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    build: process.env.BUILD_NUMBER,
    sauceConnect: !process.env.TAP,
    sauceConnectOpts: {
      noSslBumpDomains: [
        'all'
      ],
      tunnelDomains: [
        '127.0.0.1',
        'localhost'
      ],
      tunnelIdentifier: tunnelId,
      port: process.env.SAUCE_CONNECT_PORT || 4445
    }
  });
}
<commit_msg>chore(wdio): add guest tests<commit_after>require('babel-register');
const os = require('os');

const dotenv = require('dotenv');

dotenv.config();
dotenv.config({path: '.env.default'});

// eslint-disable-next-line prefer-destructuring
const argv = require('yargs').argv;

const uuid = require('uuid');

const {inject} = require('./scripts/tests/openh264');
const beforeSuite = require('./scripts/tests/beforeSuite');

const browser = process.env.BROWSER || 'chrome';
const platform = process.env.PLATFORM || 'mac 10.12';
const tunnelId = uuid.v4();
const port = process.env.PORT || 4567;
const {suite} = argv || 'integration';
const screenResolutionMac = '1920x1440';
const screenResolutionWin = '1920x1080';
const screenResolution = platform.toLowerCase().includes('os x') || platform === 'darwin' || platform.includes('mac') ? screenResolutionMac : screenResolutionWin;

const chromeCapabilities = {
  browserName: 'chrome',
  name: `react-widget-${suite}`,
  chromeOptions: {
    args: [
      '--use-fake-device-for-media-stream',
      '--use-fake-ui-for-media-stream',
      '--disable-infobars'
    ],
    prefs: {
      'profile.default_content_setting_values.notifications': 2
    }
  },
  idleTimeout: 300,
  commandTimeout: 600,
  maxDuration: 3600,
  seleniumVersion: '3.4.0',
  screenResolution,
  platform
};
const firefoxCapabilities = {
  browserName: 'firefox',
  name: `react-widget-${suite}`,
  idleTimeout: 300,
  maxDuration: 3600,
  seleniumVersion: '3.4.0',
  screenResolution,
  platform
};
let mochaTimeout = 60000;

if (process.env.DEBUG_JOURNEYS) {
  mochaTimeout = 99999999;
}
if (process.env.SAUCE) {
  mochaTimeout = 120000;
}
const services = [];
services.push('firefox-profile');
if (process.env.SAUCE) {
  services.push('sauce');
}
else {
  services.push('selenium-standalone');
}
if (!process.env.TAP) {
  services.push('static-server');
}

exports.config = {
  seleniumInstallArgs: {version: '3.4.0'},
  seleniumArgs: {version: '3.4.0'},
  //
  // ==================
  // Specify Test Files
  // ==================
  // Define which test specs should run. The pattern is relative to the directory
  // from which `wdio` was called. Notice that, if you are calling `wdio` from an
  // NPM script (see https://docs.npmjs.com/cli/run-script) then the current working
  // directory is where your package.json resides, so `wdio` will be called from there.
  //
  specs: ['./test/journeys/specs/**/*.js'],
  suites: {
    tap: [
      './test/journeys/specs/tap/**/*.js'
    ],
    oneOnOne: [
      './test/journeys/specs/oneOnOne/dataApi/basic.js',
      './test/journeys/specs/oneOnOne/dataApi/features.js',
      './test/journeys/specs/oneOnOne/dataApi/meet.js',
      './test/journeys/specs/oneOnOne/dataApi/messaging.js',
      './test/journeys/specs/oneOnOne/dataApi/startup-settings.js',
      './test/journeys/specs/oneOnOne/global/basic.js',
      './test/journeys/specs/oneOnOne/global/features.js',
      './test/journeys/specs/oneOnOne/global/meet.js',
      './test/journeys/specs/oneOnOne/global/messaging.js'
    ],
    space: [
      './test/journeys/specs/space/dataApi/basic.js',
      './test/journeys/specs/space/dataApi/meet.js',
      './test/journeys/specs/space/dataApi/messaging.js',
      './test/journeys/specs/space/dataApi/startup-settings.js',
      './test/journeys/specs/space/global/basic.js',
      './test/journeys/specs/space/global/meet.js',
      './test/journeys/specs/space/global/messaging.js',
      './test/journeys/specs/space/featureFlags.js'
    ],
    recents: [
      './test/journeys/specs/recents/dataApi/basic.js',
      './test/journeys/specs/recents/global/basic.js'
    ],
    multiple: [
      './test/journeys/specs/multiple/index.js'
    ],
    integration: [
      './test/journeys/specs/multiple/index.js',
      './test/journeys/specs/oneOnOne/dataApi/basic.js',
      './test/journeys/specs/oneOnOne/dataApi/features.js',
      './test/journeys/specs/oneOnOne/dataApi/guest.js',
      './test/journeys/specs/oneOnOne/dataApi/meet.js',
      './test/journeys/specs/oneOnOne/dataApi/messaging.js',
      './test/journeys/specs/oneOnOne/dataApi/startup-settings.js',
      './test/journeys/specs/oneOnOne/global/basic.js',
      './test/journeys/specs/oneOnOne/global/features.js',
      './test/journeys/specs/oneOnOne/global/guest.js',
      './test/journeys/specs/oneOnOne/global/meet.js',
      './test/journeys/specs/oneOnOne/global/messaging.js',
      './test/journeys/specs/recents/dataApi/basic.js',
      './test/journeys/specs/recents/global/basic.js',
      './test/journeys/specs/space/dataApi/basic.js',
      './test/journeys/specs/space/dataApi/meet.js',
      './test/journeys/specs/space/dataApi/messaging.js',
      './test/journeys/specs/space/dataApi/startup-settings.js',
      './test/journeys/specs/space/global/basic.js',
      './test/journeys/specs/space/global/meet.js',
      './test/journeys/specs/space/global/messaging.js',
      './test/journeys/specs/space/featureFlags.js'
    ],
    guest: [
      './test/journeys/specs/oneOnOne/dataApi/guest.js',
      './test/journeys/specs/oneOnOne/global/guest.js'
    ]
  },
  // Patterns to exclude.
  exclude: [],
  //
  // ============
  // Capabilities
  // ============
  // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
  // time. Depending on the number of capabilities, WebdriverIO launches several test
  // sessions. Within your capabilities you can overwrite the spec and exclude options in
  // order to group specific specs to a specific capability.
  //
  // First, you can define how many instances should be started at the same time. Let's
  // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
  // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
  // files and you set maxInstances to 10, all spec files will get tested at the same time
  // and 30 processes will get spawned. The property handles how many capabilities
  // from the same test should run tests.
  //
  //
  // If you have trouble getting all important capabilities together, check out the
  // Sauce Labs platform configurator - a great tool to configure your capabilities:
  // https://docs.saucelabs.com/reference/platforms-configurator
  //
  capabilities: browser === 'chrome' ? {
    browserLocal: {
      desiredCapabilities: chromeCapabilities
    },
    browserRemote: {
      desiredCapabilities: chromeCapabilities
    }
  } : {
    browserLocal: {
      desiredCapabilities: firefoxCapabilities
    },
    browserRemote: {
      desiredCapabilities: firefoxCapabilities
    }
  },
  //
  // ===================
  // Test Configurations
  // ===================
  // Define all options that are relevant for the WebdriverIO instance here
  //
  // By default WebdriverIO commands are executed in a synchronous way using
  // the wdio-sync package. If you still want to run your tests in an async way
  // e.g. using promises you can set the sync option to false.
  sync: true,
  //
  // Level of logging verbosity: silent | verbose | command | data | result | error
  logLevel: 'silent',
  //
  // Enables colors for log output.
  coloredLogs: true,
  //
  // If you only want to run your tests until a specific amount of tests have failed use
  // bail (default is 0 - don't bail, run all tests).
  bail: 1,
  //
  // Saves a screenshot to a given path if a command fails.
  // screenshotPath: './errorShots/',
  //
  // Set a base URL in order to shorten url command calls. If your url parameter starts
  // with "/", then the base url gets prepended.
  baseUrl: process.env.TAP ? 'https://code.s4d.io' : `http://localhost:${port}`,
  //
  // Default timeout for all waitFor* commands.
  waitforTimeout: 120000,
  //
  // Default timeout in milliseconds for request
  // if Selenium Grid doesn't send response
  connectionRetryTimeout: 90000,
  //
  // Default request retries count
  connectionRetryCount: 3,
  //
  // Initialize the browser instance with a WebdriverIO plugin. The object should have the
  // plugin name as key and the desired plugin options as properties. Make sure you have
  // the plugin installed before running any tests. The following plugins are currently
  // available:
  // WebdriverCSS: https://github.com/webdriverio/webdrivercss
  // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
  // Browserevent: https://github.com/webdriverio/browserevent
  // plugins: {
  //   webdrivercss: {
  //     screenshotRoot: 'my-shots',
  //     failedComparisonsRoot: 'diffs',
  //     misMatchTolerance: 0.05,
  //     screenWidth: [320,480,640,1024]
  //   },
  //   webdriverrtc: {},
  //   browserevent: {}
  // },
  //
  // Test runner services
  // Services take over a specific job you don't want to take care of. They enhance
  // your test setup with almost no effort. Unlike plugins, they don't add new
  // commands. Instead, they hook themselves up into the test process.
  services,
  //
  // Framework you want to run your specs with.
  // The following are supported: Mocha, Jasmine, and Cucumber
  // see also: http://webdriver.io/guide/testrunner/frameworks.html
  //
  // Make sure you have the wdio adapter package for the specific framework installed
  // before running any tests.
  framework: 'mocha',
  //
  // Test reporter for stdout.
  // The only one supported by default is 'dot'
  // see also: http://webdriver.io/guide/testrunner/reporters.html
  // NOTE: Omitting `xunit` for now. We can revisit that on another pass
  reporters: ['spec', 'junit'],
  reporterOptions: {
    junit: {
      outputDir: './reports/junit/wdio/',
      outputFileFormat() {
        return `results-${suite}-${browser}-${platform}.xml`;
      },
      packageName: `${suite}-${browser}-${platform}`
    }
  },

  //
  // Options to be passed to Mocha.
  // See the full list at http://mochajs.org/
  mochaOpts: {
    ui: 'bdd',
    timeout: mochaTimeout,
    bail: 1
  },

  // =====
  // Hooks
  // =====
  beforeSuite,

  // Static Server setup
  staticServerFolders: [
    {mount: '/dist-space', path: './packages/node_modules/@ciscospark/widget-space/dist'},
    {mount: '/dist-recents', path: './packages/node_modules/@ciscospark/widget-recents/dist'},
    {mount: '/', path: './test/journeys/server/'},
    {mount: '/axe-core', path: './node_modules/axe-core/'}
  ],
  staticServerPort: port,
  onPrepare(config, capabilities) {
    const defs = [
      capabilities.browserRemote.desiredCapabilities,
      capabilities.browserLocal.desiredCapabilities
    ];

    const build = process.env.BUILD_NUMBER || `local-${process.env.USER}-wdio-${Date.now()}`;
    /* eslint-disable no-param-reassign */
    defs.forEach((d) => {
      if (process.env.SAUCE) {
        d.build = build;
        // Set the base to SauceLabs so that inject() does its thing.
        d.base = 'SauceLabs';

        d.version = d.version || 'latest';
        d.platform = d.platform || 'OS X 10.12';
      }
      else {
        // Copy the base over so that inject() does its thing.
        d.base = d.browserName;
        d.platform = os.platform();
      }
    });
    /* eslint-enable no-param-reassign */

    return inject(defs)
      .then(() => {
        // Remove the base because it's not actually a selenium property
        defs.forEach((d) => Reflect.deleteProperty(d, 'base'));
      });
  }
};

if (process.env.SAUCE) {
  exports.config = Object.assign(exports.config, {
    deprecationWarnings: false, // Deprecation warnings on sauce just make the logs noisy
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,
    build: process.env.BUILD_NUMBER,
    sauceConnect: !process.env.TAP,
    sauceConnectOpts: {
      noSslBumpDomains: [
        'all'
      ],
      tunnelDomains: [
        '127.0.0.1',
        'localhost'
      ],
      tunnelIdentifier: tunnelId,
      port: process.env.SAUCE_CONNECT_PORT || 4445
    }
  });
}
<|endoftext|>