<commit_before>// Currently requires polyfills for
// Array#forEach
// Object.keys
// String#trim

(function(factory) {
  if (typeof define === 'function' && define.amd) {
    define(['q'], function(Q) {
      return factory(XMLHttpRequest, Q)
    })
  } else if (typeof exports === 'object' && typeof module === 'object') {
    // CommonJS, mainly for testing
    module.exports = factory
  } else {
    if (typeof Q !== 'undefined') {
      factory(XMLHttpRequest, Q)
    }
  }
})(function(XHR, Q) {
  // shallow extend with varargs
  function extend(dst) {
    Array.prototype.forEach.call(arguments, function(obj) {
      if (obj && obj !== dst) {
        Object.keys(obj).forEach(function(key) {
          dst[key] = obj[key]
        })
      }
    })

    return dst
  }

  function lowercase(str) {
    return (str || '').toLowerCase()
  }

  function parseHeaders(headers) {
    var parsed = {}, key, val, i

    if (!headers) return parsed

    headers.split('\n').forEach(function(line) {
      i = line.indexOf(':')
      key = lowercase(line.substr(0, i).trim())
      val = line.substr(i + 1).trim()

      if (key) {
        if (parsed[key]) {
          parsed[key] += ', ' + val
        } else {
          parsed[key] = val
        }
      }
    })

    return parsed
  }

  function headersGetter(headers) {
    var headersObj = typeof headers === 'object' ? headers : undefined;

    return function(name) {
      if (!headersObj) headersObj = parseHeaders(headers)

      if (name) {
        return headersObj[lowercase(name)]
      }

      return headersObj
    }
  }

  function transformData(data, headers, fns) {
    if (typeof fns === 'function') {
      return fns(data, headers)
    }

    fns.forEach(function(fn) {
      data = fn(data, headers)
    })

    return data
  }

  function isSuccess(status) {
    return 200 <= status && status < 300
  }

  function forEach(obj, iterator, context) {
    var keys = Object.keys(obj)
    keys.forEach(function(key) {
      iterator.call(context, obj[key], key)
    })
    return keys
  }

  function forEachSorted(obj, iterator, context) {
    var keys = Object.keys(obj).sort()
    keys.forEach(function(key) {
      iterator.call(context, obj[key], key)
    })
    return keys
  }

  function buildUrl(url, params) {
    if (!params) return url
    var parts = []
    forEachSorted(params, function(value, key) {
      if (value == null) return
      if (!Array.isArray(value)) value = [value]

      value.forEach(function(v) {
        if (typeof v === 'object') {
          v = JSON.stringify(v)
        }
        parts.push(encodeURIComponent(key) + '=' +
                   encodeURIComponent(v))
      })
    })
    return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&')
  }

  Q.xhr = function (requestConfig) {
    var defaults = Q.xhr.defaults,
    config = {
      transformRequest: defaults.transformRequest,
      transformResponse: defaults.transformResponse
    },
    mergeHeaders = function(config) {
      var defHeaders = defaults.headers,
          reqHeaders = extend({}, config.headers),
          defHeaderName, lowercaseDefHeaderName, reqHeaderName,

      execHeaders = function(headers) {
        forEach(headers, function(headerFn, header) {
          if (typeof headerFn === 'function') {
            var headerContent = headerFn()
            if (headerContent != null) {
              headers[header] = headerContent
            } else {
              delete headers[header]
            }
          }
        })
      }

      defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);

      // execute if header value is function
      execHeaders(defHeaders);
      execHeaders(reqHeaders);

      // using for-in instead of forEach to avoid unecessary iteration after header has been found
      defaultHeadersIteration:
      for (defHeaderName in defHeaders) {
        lowercaseDefHeaderName = lowercase(defHeaderName);

        for (reqHeaderName in reqHeaders) {
          if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {
            continue defaultHeadersIteration;
          }
        }

        reqHeaders[defHeaderName] = defHeaders[defHeaderName];
      }

      return reqHeaders;
    },
    headers = mergeHeaders(requestConfig)

    extend(config, requestConfig)
    config.headers = headers
    config.method = (config.method || 'GET').toUpperCase()

    var serverRequest = function(config) {
      headers = config.headers
      var reqData = transformData(config.data, headersGetter(headers), config.transformRequest)

      // strip content-type if data is undefined TODO does it really matter?
      if (config.data == null) {
        forEach(headers, function(value, header) {
          if (lowercase(header) === 'content-type') {
              delete headers[header]
          }
        })
      }

      if (config.withCredentials == null && defaults.withCredentials != null) {
        config.withCredentials = defaults.withCredentials
      }

      // send request
      return sendReq(config, reqData, headers).then(transformResponse, transformResponse)
    },

    transformResponse = function(response) {
      response.data = transformData(response.data, response.headers, config.transformResponse)
      return isSuccess(response.status) ? response : Q.reject(response)
    },

    promise = Q.when(config)

    // build a promise chain with request interceptors first, then the request, and response interceptors
    Q.xhr.interceptors.filter(function(interceptor) {
        return !!interceptor.request || !!interceptor.requestError
      }).map(function(interceptor) {
        return { success: interceptor.request, failure: interceptor.requestError }
      })
    .concat({ success: serverRequest })
    .concat(Q.xhr.interceptors.filter(function(interceptor) {
        return !!interceptor.response || !!interceptor.responseError
      }).map(function(interceptor) {
        return { success: interceptor.response, failure: interceptor.responseError }
      })
    ).forEach(function(then) {
      promise = promise.then(then.success, then.failure)
    })

    return promise
  }

  var contentTypeJson = { 'Content-Type': 'application/json;charset=utf-8' }

  Q.xhr.defaults = {
    transformResponse: [function(data, headers) {
      if (typeof data === 'string' && data.length && (headers('content-type') || '').indexOf('json') >= 0) {
          data = JSON.parse(data);
      }
      return data
    }],

    transformRequest: [function(data) {
      return !!data && typeof data === 'object' && data.toString() !== '[object File]' ?
        JSON.stringify(data) : data
    }],

    headers: {
      common: {
        'Accept': 'application/json, text/plain, */*'
      },
      post:   contentTypeJson,
      put:    contentTypeJson,
      patch:  contentTypeJson
    },
  }

  Q.xhr.interceptors = []
  Q.xhr.pendingRequests = []

  function sendReq(config, reqData, reqHeaders) {
    var deferred = Q.defer(),
        promise = deferred.promise,
        url = buildUrl(config.url, config.params),
        xhr = new XHR(),
        aborted = -1,
        status,
        timeoutId

    Q.xhr.pendingRequests.push(config)

    xhr.open(config.method, url, true)
    forEach(config.headers, function(value, key) {
      if (value) {
        xhr.setRequestHeader(key, value)
      }
    })

    xhr.onreadystatechange = function() {
      if (xhr.readyState == 4) {
        var response, responseHeaders
        if (status !== aborted) {
          responseHeaders = xhr.getAllResponseHeaders()
          // responseText is the old-school way of retrieving response (supported by IE8 & 9)
          // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
          response = xhr.responseType ? xhr.response : xhr.responseText
        }

        // cancel timeout and subsequent timeout promise resolution
        timeoutId && clearTimeout(timeoutId)
        status = status || xhr.status
        xhr = null

        // normalize status, including accounting for IE bug (http://bugs.jquery.com/ticket/1450)
        status = Math.max(status == 1223 ? 204 : status, 0)

        var idx = Q.xhr.pendingRequests.indexOf(config)
        if (idx !== -1) Q.xhr.pendingRequests.splice(idx, 1)

        ;(isSuccess(status) ? deferred.resolve : deferred.reject)({
          data: response,
          status: status,
          headers: headersGetter(responseHeaders),
          config: config
        })
      }
    }

    xhr.onprogress = function (progress) {
      deferred.notify(progress)
    }

    if (config.withCredentials) {
      xhr.withCredentials = true
    }

    if (config.responseType) {
      xhr.responseType = config.responseType;
    }

    xhr.send(reqData || null)

    if (config.timeout > 0) {
      timeoutId = setTimeout(function() {
        status = aborted;
        xhr && xhr.abort()
      }, config.timeout)
    }

    return promise
  }

  ['get', 'delete', 'head'].forEach(function(name) {
    Q.xhr[name] = function(url, config) {
      return Q.xhr(extend(config || {}, {
        method: name,
        url: url
      }))
    }
  });

  ['post', 'put', 'patch'].forEach(function(name) {
    Q.xhr[name] = function(url, data, config) {
      return Q.xhr(extend(config || {}, {
        method: name,
        url: url,
        data: data
      }))
    }
  })

  return Q
})
<commit_msg>remove extra space<commit_after>// Currently requires polyfills for
// Array#forEach
// Object.keys
// String#trim

(function(factory) {
  if (typeof define === 'function' && define.amd) {
    define(['q'], function(Q) {
      return factory(XMLHttpRequest, Q)
    })
  } else if (typeof exports === 'object' && typeof module === 'object') {
    // CommonJS, mainly for testing
    module.exports = factory
  } else {
    if (typeof Q !== 'undefined') {
      factory(XMLHttpRequest, Q)
    }
  }
})(function(XHR, Q) {
  // shallow extend with varargs
  function extend(dst) {
    Array.prototype.forEach.call(arguments, function(obj) {
      if (obj && obj !== dst) {
        Object.keys(obj).forEach(function(key) {
          dst[key] = obj[key]
        })
      }
    })

    return dst
  }

  function lowercase(str) {
    return (str || '').toLowerCase()
  }

  function parseHeaders(headers) {
    var parsed = {}, key, val, i

    if (!headers) return parsed

    headers.split('\n').forEach(function(line) {
      i = line.indexOf(':')
      key = lowercase(line.substr(0, i).trim())
      val = line.substr(i + 1).trim()

      if (key) {
        if (parsed[key]) {
          parsed[key] += ', ' + val
        } else {
          parsed[key] = val
        }
      }
    })

    return parsed
  }

  function headersGetter(headers) {
    var headersObj = typeof headers === 'object' ? headers : undefined;

    return function(name) {
      if (!headersObj) headersObj = parseHeaders(headers)

      if (name) {
        return headersObj[lowercase(name)]
      }

      return headersObj
    }
  }

  function transformData(data, headers, fns) {
    if (typeof fns === 'function') {
      return fns(data, headers)
    }

    fns.forEach(function(fn) {
      data = fn(data, headers)
    })

    return data
  }

  function isSuccess(status) {
    return 200 <= status && status < 300
  }

  function forEach(obj, iterator, context) {
    var keys = Object.keys(obj)
    keys.forEach(function(key) {
      iterator.call(context, obj[key], key)
    })
    return keys
  }

  function forEachSorted(obj, iterator, context) {
    var keys = Object.keys(obj).sort()
    keys.forEach(function(key) {
      iterator.call(context, obj[key], key)
    })
    return keys
  }

  function buildUrl(url, params) {
    if (!params) return url
    var parts = []
    forEachSorted(params, function(value, key) {
      if (value == null) return
      if (!Array.isArray(value)) value = [value]

      value.forEach(function(v) {
        if (typeof v === 'object') {
          v = JSON.stringify(v)
        }
        parts.push(encodeURIComponent(key) + '=' +
                   encodeURIComponent(v))
      })
    })
    return url + ((url.indexOf('?') == -1) ? '?' : '&') + parts.join('&')
  }

  Q.xhr = function (requestConfig) {
    var defaults = Q.xhr.defaults,
    config = {
      transformRequest: defaults.transformRequest,
      transformResponse: defaults.transformResponse
    },
    mergeHeaders = function(config) {
      var defHeaders = defaults.headers,
          reqHeaders = extend({}, config.headers),
          defHeaderName, lowercaseDefHeaderName, reqHeaderName,

      execHeaders = function(headers) {
        forEach(headers, function(headerFn, header) {
          if (typeof headerFn === 'function') {
            var headerContent = headerFn()
            if (headerContent != null) {
              headers[header] = headerContent
            } else {
              delete headers[header]
            }
          }
        })
      }

      defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]);

      // execute if header value is function
      execHeaders(defHeaders);
      execHeaders(reqHeaders);

      // using for-in instead of forEach to avoid unecessary iteration after header has been found
      defaultHeadersIteration:
      for (defHeaderName in defHeaders) {
        lowercaseDefHeaderName = lowercase(defHeaderName);

        for (reqHeaderName in reqHeaders) {
          if (lowercase(reqHeaderName) === lowercaseDefHeaderName) {
            continue defaultHeadersIteration;
          }
        }

        reqHeaders[defHeaderName] = defHeaders[defHeaderName];
      }

      return reqHeaders;
    },
    headers = mergeHeaders(requestConfig)

    extend(config, requestConfig)
    config.headers = headers
    config.method = (config.method || 'GET').toUpperCase()

    var serverRequest = function(config) {
      headers = config.headers
      var reqData = transformData(config.data, headersGetter(headers), config.transformRequest)

      // strip content-type if data is undefined TODO does it really matter?
      if (config.data == null) {
        forEach(headers, function(value, header) {
          if (lowercase(header) === 'content-type') {
              delete headers[header]
          }
        })
      }

      if (config.withCredentials == null && defaults.withCredentials != null) {
        config.withCredentials = defaults.withCredentials
      }

      // send request
      return sendReq(config, reqData, headers).then(transformResponse, transformResponse)
    },

    transformResponse = function(response) {
      response.data = transformData(response.data, response.headers, config.transformResponse)
      return isSuccess(response.status) ? response : Q.reject(response)
    },

    promise = Q.when(config)

    // build a promise chain with request interceptors first, then the request, and response interceptors
    Q.xhr.interceptors.filter(function(interceptor) {
        return !!interceptor.request || !!interceptor.requestError
      }).map(function(interceptor) {
        return { success: interceptor.request, failure: interceptor.requestError }
      })
    .concat({ success: serverRequest })
    .concat(Q.xhr.interceptors.filter(function(interceptor) {
        return !!interceptor.response || !!interceptor.responseError
      }).map(function(interceptor) {
        return { success: interceptor.response, failure: interceptor.responseError }
      })
    ).forEach(function(then) {
      promise = promise.then(then.success, then.failure)
    })

    return promise
  }

  var contentTypeJson = { 'Content-Type': 'application/json;charset=utf-8' }

  Q.xhr.defaults = {
    transformResponse: [function(data, headers) {
      if (typeof data === 'string' && data.length && (headers('content-type') || '').indexOf('json') >= 0) {
        data = JSON.parse(data);
      }
      return data
    }],

    transformRequest: [function(data) {
      return !!data && typeof data === 'object' && data.toString() !== '[object File]' ?
        JSON.stringify(data) : data
    }],

    headers: {
      common: {
        'Accept': 'application/json, text/plain, */*'
      },
      post:   contentTypeJson,
      put:    contentTypeJson,
      patch:  contentTypeJson
    },
  }

  Q.xhr.interceptors = []
  Q.xhr.pendingRequests = []

  function sendReq(config, reqData, reqHeaders) {
    var deferred = Q.defer(),
        promise = deferred.promise,
        url = buildUrl(config.url, config.params),
        xhr = new XHR(),
        aborted = -1,
        status,
        timeoutId

    Q.xhr.pendingRequests.push(config)

    xhr.open(config.method, url, true)
    forEach(config.headers, function(value, key) {
      if (value) {
        xhr.setRequestHeader(key, value)
      }
    })

    xhr.onreadystatechange = function() {
      if (xhr.readyState == 4) {
        var response, responseHeaders
        if (status !== aborted) {
          responseHeaders = xhr.getAllResponseHeaders()
          // responseText is the old-school way of retrieving response (supported by IE8 & 9)
          // response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
          response = xhr.responseType ? xhr.response : xhr.responseText
        }

        // cancel timeout and subsequent timeout promise resolution
        timeoutId && clearTimeout(timeoutId)
        status = status || xhr.status
        xhr = null

        // normalize status, including accounting for IE bug (http://bugs.jquery.com/ticket/1450)
        status = Math.max(status == 1223 ? 204 : status, 0)

        var idx = Q.xhr.pendingRequests.indexOf(config)
        if (idx !== -1) Q.xhr.pendingRequests.splice(idx, 1)

        ;(isSuccess(status) ? deferred.resolve : deferred.reject)({
          data: response,
          status: status,
          headers: headersGetter(responseHeaders),
          config: config
        })
      }
    }

    xhr.onprogress = function (progress) {
      deferred.notify(progress)
    }

    if (config.withCredentials) {
      xhr.withCredentials = true
    }

    if (config.responseType) {
      xhr.responseType = config.responseType;
    }

    xhr.send(reqData || null)

    if (config.timeout > 0) {
      timeoutId = setTimeout(function() {
        status = aborted;
        xhr && xhr.abort()
      }, config.timeout)
    }

    return promise
  }

  ['get', 'delete', 'head'].forEach(function(name) {
    Q.xhr[name] = function(url, config) {
      return Q.xhr(extend(config || {}, {
        method: name,
        url: url
      }))
    }
  });

  ['post', 'put', 'patch'].forEach(function(name) {
    Q.xhr[name] = function(url, data, config) {
      return Q.xhr(extend(config || {}, {
        method: name,
        url: url,
        data: data
      }))
    }
  })

  return Q
})
<|endoftext|>


<commit_before>/*
 * Copyright 2016, Lorenzo Mangani (lorenzo.mangani@gmail.com)
 * Copyright 2015, Rao Chenlin (rao.chenlin@gmail.com)
 *
 * This file is part of Sentinl (http://github.com/sirensolutions/sentinl)
 *
 * 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.
 */

import './alarm_spy.less';

const linkReqRespStats = function ($scope, config) {
  $scope.$bind('req', 'searchSource.history[searchSource.history.length - 1]');
  $scope.$watchMulti([
    'req',
    'req.started',
    'req.stopped',
    'searchSource'
  ], function () {
    if (!$scope.searchSource || !$scope.req) return;

    const req = $scope.req;
    const resp = $scope.req.resp;
    let indexPattern;
    $scope.indices = [];

    if (req.fetchParams && req.fetchParams.index) {
      const idx = req.fetchParams.index.toString();
      indexPattern = $scope.searchSource.get('index');
      if (indexPattern.hasTimeField()) {
        const tmp = idx.replace(/\*/g, '');
        $scope.indices.push(`<${tmp}{now/d}>`);
        $scope.indices.push(`<${tmp}{now/d-1d}>`);
      } else {
        $scope.indices.push(idx);
      }
    }

    $scope.intervals = [
      {name: '1m', value: 'every 1 minute'},
      {name: '5m', value: 'every 5 minutes'},
      {name: '10m', value: 'every 10 minutes'},
      {name: '1h', value: 'every 1 hour'},
      {name: '6h', value: 'every 6 hours'},
      {name: '12h', value: 'every 12 hours'},
      {name: '1d', value: 'every 1 day'}
    ];

    $scope.ranges = [
      {name: '1m', value: 'now-1m'},
      {name: '5m', value: 'now-5m'},
      {name: '10m', value: 'now-1h'},
      {name: '1h', value: 'now-1h'},
      {name: '6h', value: 'now-6h'},
      {name: '12h', value: 'now-12h'},
      {name: '1d', value: 'now-1d'}
    ];

    $scope.resKeys = [];
    $scope.iterateKeys = function (data) {
      var result = {};
      function recurse(cur, prop) {
        if (Object(cur) !== cur) {
          result[prop] = cur;
        } else if (Array.isArray(cur)) {
          for (var i = 0, l = cur.length; i < l; i++) {
            recurse(cur[i], prop + '[' + i + ']');
          }
          if (cur.length === 0) {
            result[prop] = [];
          }
        } else {
          var isEmpty = true;
          for (var p in cur) {
            if (p) {
              isEmpty = false;
              recurse(cur[p], prop ? prop + '.' + p : p);
            }
          }
          if (isEmpty && prop) {
            result[prop] = {};
          }
        }
      }
      recurse(data, '');
      $scope.resKeys = result;
    };

    if (resp) {
      $scope.iterateKeys({ payload: resp });
    }

    /* User can select different form - change here to change labels of the select*/
    $scope.watcher_choose = ['E-Mail', 'HTML E-Mail', 'Slack', 'Webhook'];
    $scope.selectedchoose = '';
    $scope.viewFlag = false;

    /* Enable-disable forms */
    $scope.activeform = {
      'email': false,
      'htmlemail': false,
      'slack': false,
      'webhook': false
    };

    /* Defaults */
    $scope.watcher_id = 'new_spy_watcher'  + Math.random().toString(36).substr(2, 9);
    $scope.watcher_title = 'new_title';
    $scope.watcher_script = 'payload.hits.total > 100';
    $scope.watcher_interval = $scope.intervals[0].value;
    $scope.watcher_range = $scope.ranges[1].value;

    /* fields for e-mail option */
    $scope.initEmail = function () {
      $scope.watcher_email_to = 'root@localhost';
      $scope.watcher_email_from = 'sentinl@localhost';
      $scope.watcher_email_subj = 'SENTINL ALARM {{payload._id}}';
      $scope.watcher_email_body = 'Series Alarm {{payload._id}}: {{payload.hits.total}}';
    };

    /*fields for html_e-mail option */
    $scope.initEmailHtml = function () {
      $scope.watcher_email_html_to = 'root@localhost';
      $scope.watcher_email_html_from = 'sentinl@localhost';
      $scope.watcher_email_html_subj = 'SENTINL ALARM {{payload._id}}';
      $scope.watcher_email_html_body = 'Series Alarm {{payload._id}}: {{payload.hits.total}}';
      $scope.watcher_email_html_html = '
Series Alarm {{payload._id}}: {{payload.hits.total}}
';
    };

    /* fields for slack webhook option */
    $scope.initSlack = function () {
      $scope.watcher_slack_channel = '#<channel>';
      $scope.watcher_slack_message = 'Series Alarm {{payload._id}}: {{payload.hits.total}}';
    };

    /* fields for generic webhook option */
    $scope.initWebhook = function () {
      $scope.watcher_webhook_method = 'POST';
      $scope.watcher_webhook_host = 'remote.server';
      $scope.watcher_webhook_port = 9200;
      $scope.watcher_webhook_path = '/{{payload.watcher_id}}';
      $scope.watcher_webhook_body = '{{payload.watcher_id}}:{{payload.hits.total}}';
    };

    $scope.initEmail();
    $scope.initEmailHtml();
    $scope.initSlack();
    $scope.initWebhook();

    $scope.savedWatcher = {};
    $scope.savedWatcher.actions = {};
    var alarm = {};

    $scope.watcherUpdate = function () {
      $scope.savedWatcher.interval = $scope.watcher_interval;
      $scope.savedWatcher.range = $scope.watcher_range;
      $scope.savedWatcher.id = $scope.watcher_id;
      $scope.savedWatcher.script = $scope.watcher_script;
      $scope.savedWatcher.keys = $scope.resKeys;
      config.savedWatcher = $scope.savedWatcher;
    };

    $scope.makeAlarm = function () {
      $scope.watcherUpdate();
      $scope.alarm = {
        _index: 'watcher',
        _type: 'watch',
        _id: $scope.watcher_id,
        _new: 'true',
        _source: {
          title: $scope.watcher_title,
          uuid: $scope.watcher_id,
          disable: false,
          trigger: {
            schedule: {
              later: $scope.watcher_interval ? $scope.watcher_interval : 'every 5 minutes'
            }
          },
          input: {
            search: {
              request: {}
            }
          },
          condition: {
            script: {
              script: $scope.savedWatcher.script
            }
          },
          transform: {},
          actions: {
            kibi_actions: $scope.savedWatcher.actions
          }
        }
      };

      if (req.fetchParams && req.fetchParams.body) {
        $scope.alarm._source.input.search.request.body = req.fetchParams.body;
      }
      // Patch Indices
      $scope.alarm._source.input.search.request.index = $scope.indices;
      // Patch Range
      if (indexPattern && indexPattern.hasTimeField()) {
        $scope.alarm._source.input.search.request.body.query.filtered.filter = {
          range: {
            [indexPattern.timeFieldName]: {
              from: $scope.watcher_range ? $scope.watcher_range : 'now-1h'
            }
          }
        };
      }
      // Store Watcher
      alarm = $scope.alarm;
      window.localStorage.setItem('sentinl_saved_query', JSON.stringify($scope.alarm));
    };

    $scope.manageForm = function () {
      if ($scope.selectedchoose === $scope.watcher_choose[0]) {
        $scope.viewFlag = Boolean($scope.savedWatcher.actions.email);
      } else if ($scope.selectedchoose === $scope.watcher_choose[1]) {
        $scope.viewFlag = Boolean($scope.savedWatcher.actions.email_html);
      } else if ($scope.selectedchoose === $scope.watcher_choose[2]) {
        $scope.viewFlag = Boolean($scope.savedWatcher.actions.slack);
      } else if ($scope.selectedchoose === $scope.watcher_choose[3]) {
        $scope.viewFlag = Boolean($scope.savedWatcher.actions.webhook);
      }
    };

    $scope.switchViewFlag = function (flag) {
      if (flag) {
        $scope.viewFlag = true;
        $scope.manageViewArray(true);
        $scope.updateAction();
      } else {
        var proceed = confirm('Are you sure to delete this action?');
        if (proceed) {
          $scope.viewFlag = false;
          $scope.manageViewArray(false);
          $scope.deleteAction();
        }
      }
    };

    $scope.manageViewArray = function (flag) {
      switch ($scope.selectedchoose) {
        case 'E-Mail':
          $scope.activeform.email = flag;
          break;
        case 'HTML E-Mail':
          $scope.activeform.htmlemail = flag;
          break;
        case 'Slack':
          $scope.activeform.slack = flag;
          break;
        case 'Webhook':
          $scope.activeform.webhook = flag;
          break;
      }
    };

    $scope.goToCompiledForm = function (nameForm) {
      $scope.selectedchoose = nameForm;
      $scope.viewFlag = true;
    };

    $scope.deleteAction = function () {
      if ($scope.selectedchoose === $scope.watcher_choose[0]) {
        if ($scope.savedWatcher.actions.email) {
          delete $scope.savedWatcher.actions.email;
          $scope.initEmail();
        }
      } else if ($scope.selectedchoose === $scope.watcher_choose[1]) {
        if ($scope.savedWatcher.actions.email_html) {
          delete $scope.savedWatcher.actions.email_html;
          $scope.initEmailHtml();
        }
      } else if ($scope.selectedchoose === $scope.watcher_choose[2]) {
        if ($scope.savedWatcher.actions.slack) {
          delete $scope.savedWatcher.actions.slack;
          $scope.initSlack();
        }
      } else if ($scope.selectedchoose === $scope.watcher_choose[3]) {
        if ($scope.savedWatcher.actions.webhook) {
          delete $scope.savedWatcher.actions.webhook;
          $scope.initWebhook();
        }
      }
      $scope.selectedchoose = '';
    };

    $scope.updateAction = function () {
      if ($scope.selectedchoose === $scope.watcher_choose[0]) {
        $scope.savedWatcher.actions.email = {
          to: $scope.watcher_email_to ? $scope.watcher_email_to : 'alarm@localhost',
          from: $scope.watcher_email_from ? $scope.watcher_email_from : 'sentinl@localhost',
          subject: $scope.watcher_email_subj ? $scope.watcher_email_subj : 'Sentinl Alarm',
          priority: 'high',
          body: $scope.watcher_email_body ? $scope.watcher_email_body : 'Found {{payload.hits.total}} Events'
        };
      } else if ($scope.selectedchoose === $scope.watcher_choose[1]) {
        $scope.savedWatcher.actions.email_html = {
          to: $scope.watcher_email_html_to ? $scope.watcher_email_html_to : 'alarm@localhost',
          from: $scope.watcher_email_html_from ? $scope.watcher_email_html_from : 'sentinl@localhost',
          subject: $scope.watcher_email_html_subj ? $scope.watcher_email_html_subj : 'Sentinl Alarm',
          priority: 'high',
          body: $scope.watcher_email_html_body ? $scope.watcher_email_html_body : 'Found {{payload.hits.total}} Events',
          html: $scope.watcher_email_html_html ? $scope.watcher_email_html_html :
          '
Series Alarm {{payload._id}}: {{payload.hits.total}}
'
        };
      } else if ($scope.selectedchoose === $scope.watcher_choose[2]) {
        $scope.savedWatcher.actions.slack = {
          channel: $scope.watcher_slack_channel ? $scope.watcher_slack_channel : '#<channel>',
          message: $scope.watcher_slack_message ? $scope.watcher_slack_message : 'Series Alarm {{payload._id}}: {{payload.hits.total}}'
        };
      } else if ($scope.selectedchoose === $scope.watcher_choose[3]) {
        $scope.savedWatcher.actions.webhook = {
          method: $scope.watcher_webhook_method ? $scope.watcher_webhook_method : 'POST',
          host: $scope.watcher_webhook_host ? $scope.watcher_webhook_host : 'remote.server',
          port: $scope.watcher_webhook_port ? $scope.watcher_webhook_port : 9200,
          path: $scope.watcher_webhook_path ? $scope.watcher_webhook_path : '/{{payload.watcher_id}}',
          body: $scope.watcher_webhook_body ? $scope.watcher_webhook_body : '{{payload.watcher_id}}:{{payload.hits.total}}'
        };
      }
    };
    $scope.makeAlarm();
    $scope.updateAction();

  });
};

// Spy Placement
require('ui/registry/spy_modes').register(function () {
  return {
    display: 'Set Watcher',
    name: 'setalarm',
    order: 1000,
    link: linkReqRespStats,
    template: require('plugins/sentinl/button/alarm_spy.html')
  };
});
<commit_msg>set query index before body in spy plugin<commit_after>/*
 * Copyright 2016, Lorenzo Mangani (lorenzo.mangani@gmail.com)
 * Copyright 2015, Rao Chenlin (rao.chenlin@gmail.com)
 *
 * This file is part of Sentinl (http://github.com/sirensolutions/sentinl)
 *
 * 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.
 */

import './alarm_spy.less';

const linkReqRespStats = function ($scope, config) {
  $scope.$bind('req', 'searchSource.history[searchSource.history.length - 1]');
  $scope.$watchMulti([
    'req',
    'req.started',
    'req.stopped',
    'searchSource'
  ], function () {
    if (!$scope.searchSource || !$scope.req) return;

    const req = $scope.req;
    const resp = $scope.req.resp;
    let indexPattern;
    $scope.indices = [];

    if (req.fetchParams && req.fetchParams.index) {
      const idx = req.fetchParams.index.toString();
      indexPattern = $scope.searchSource.get('index');
      if (indexPattern.hasTimeField()) {
        const tmp = idx.replace(/\*/g, '');
        $scope.indices.push(`<${tmp}{now/d}>`);
        $scope.indices.push(`<${tmp}{now/d-1d}>`);
      } else {
        $scope.indices.push(idx);
      }
    }

    $scope.intervals = [
      {name: '1m', value: 'every 1 minute'},
      {name: '5m', value: 'every 5 minutes'},
      {name: '10m', value: 'every 10 minutes'},
      {name: '1h', value: 'every 1 hour'},
      {name: '6h', value: 'every 6 hours'},
      {name: '12h', value: 'every 12 hours'},
      {name: '1d', value: 'every 1 day'}
    ];

    $scope.ranges = [
      {name: '1m', value: 'now-1m'},
      {name: '5m', value: 'now-5m'},
      {name: '10m', value: 'now-1h'},
      {name: '1h', value: 'now-1h'},
      {name: '6h', value: 'now-6h'},
      {name: '12h', value: 'now-12h'},
      {name: '1d', value: 'now-1d'}
    ];

    $scope.resKeys = [];
    $scope.iterateKeys = function (data) {
      var result = {};
      function recurse(cur, prop) {
        if (Object(cur) !== cur) {
          result[prop] = cur;
        } else if (Array.isArray(cur)) {
          for (var i = 0, l = cur.length; i < l; i++) {
            recurse(cur[i], prop + '[' + i + ']');
          }
          if (cur.length === 0) {
            result[prop] = [];
          }
        } else {
          var isEmpty = true;
          for (var p in cur) {
            if (p) {
              isEmpty = false;
              recurse(cur[p], prop ? prop + '.' + p : p);
            }
          }
          if (isEmpty && prop) {
            result[prop] = {};
          }
        }
      }
      recurse(data, '');
      $scope.resKeys = result;
    };

    if (resp) {
      $scope.iterateKeys({ payload: resp });
    }

    /* User can select different form - change here to change labels of the select*/
    $scope.watcher_choose = ['E-Mail', 'HTML E-Mail', 'Slack', 'Webhook'];
    $scope.selectedchoose = '';
    $scope.viewFlag = false;

    /* Enable-disable forms */
    $scope.activeform = {
      'email': false,
      'htmlemail': false,
      'slack': false,
      'webhook': false
    };

    /* Defaults */
    $scope.watcher_id = 'new_spy_watcher'  + Math.random().toString(36).substr(2, 9);
    $scope.watcher_title = 'new_title';
    $scope.watcher_script = 'payload.hits.total > 100';
    $scope.watcher_interval = $scope.intervals[0].value;
    $scope.watcher_range = $scope.ranges[1].value;

    /* fields for e-mail option */
    $scope.initEmail = function () {
      $scope.watcher_email_to = 'root@localhost';
      $scope.watcher_email_from = 'sentinl@localhost';
      $scope.watcher_email_subj = 'SENTINL ALARM {{payload._id}}';
      $scope.watcher_email_body = 'Series Alarm {{payload._id}}: {{payload.hits.total}}';
    };

    /*fields for html_e-mail option */
    $scope.initEmailHtml = function () {
      $scope.watcher_email_html_to = 'root@localhost';
      $scope.watcher_email_html_from = 'sentinl@localhost';
      $scope.watcher_email_html_subj = 'SENTINL ALARM {{payload._id}}';
      $scope.watcher_email_html_body = 'Series Alarm {{payload._id}}: {{payload.hits.total}}';
      $scope.watcher_email_html_html = '
Series Alarm {{payload._id}}: {{payload.hits.total}}
';
    };

    /* fields for slack webhook option */
    $scope.initSlack = function () {
      $scope.watcher_slack_channel = '#<channel>';
      $scope.watcher_slack_message = 'Series Alarm {{payload._id}}: {{payload.hits.total}}';
    };

    /* fields for generic webhook option */
    $scope.initWebhook = function () {
      $scope.watcher_webhook_method = 'POST';
      $scope.watcher_webhook_host = 'remote.server';
      $scope.watcher_webhook_port = 9200;
      $scope.watcher_webhook_path = '/{{payload.watcher_id}}';
      $scope.watcher_webhook_body = '{{payload.watcher_id}}:{{payload.hits.total}}';
    };

    $scope.initEmail();
    $scope.initEmailHtml();
    $scope.initSlack();
    $scope.initWebhook();

    $scope.savedWatcher = {};
    $scope.savedWatcher.actions = {};
    var alarm = {};

    $scope.watcherUpdate = function () {
      $scope.savedWatcher.interval = $scope.watcher_interval;
      $scope.savedWatcher.range = $scope.watcher_range;
      $scope.savedWatcher.id = $scope.watcher_id;
      $scope.savedWatcher.script = $scope.watcher_script;
      $scope.savedWatcher.keys = $scope.resKeys;
      config.savedWatcher = $scope.savedWatcher;
    };

    $scope.makeAlarm = function () {
      $scope.watcherUpdate();
      $scope.alarm = {
        _index: 'watcher',
        _type: 'watch',
        _id: $scope.watcher_id,
        _new: 'true',
        _source: {
          title: $scope.watcher_title,
          uuid: $scope.watcher_id,
          disable: false,
          trigger: {
            schedule: {
              later: $scope.watcher_interval ? $scope.watcher_interval : 'every 5 minutes'
            }
          },
          input: {
            search: {
              request: {}
            }
          },
          condition: {
            script: {
              script: $scope.savedWatcher.script
            }
          },
          transform: {},
          actions: {
            kibi_actions: $scope.savedWatcher.actions
          }
        }
      };

      // Set Index
      $scope.alarm._source.input.search.request.index = $scope.indices;
      // Set Request Body
      if (req.fetchParams && req.fetchParams.body) {
        $scope.alarm._source.input.search.request.body = req.fetchParams.body;
      }
      // Patch Range
      if (indexPattern && indexPattern.hasTimeField()) {
        $scope.alarm._source.input.search.request.body.query.filtered.filter = {
          range: {
            [indexPattern.timeFieldName]: {
              from: $scope.watcher_range ? $scope.watcher_range : 'now-1h'
            }
          }
        };
      }
      // Store Watcher
      alarm = $scope.alarm;
      window.localStorage.setItem('sentinl_saved_query', JSON.stringify($scope.alarm));
    };

    $scope.manageForm = function () {
      if ($scope.selectedchoose === $scope.watcher_choose[0]) {
        $scope.viewFlag = Boolean($scope.savedWatcher.actions.email);
      } else if ($scope.selectedchoose === $scope.watcher_choose[1]) {
        $scope.viewFlag = Boolean($scope.savedWatcher.actions.email_html);
      } else if ($scope.selectedchoose === $scope.watcher_choose[2]) {
        $scope.viewFlag = Boolean($scope.savedWatcher.actions.slack);
      } else if ($scope.selectedchoose === $scope.watcher_choose[3]) {
        $scope.viewFlag = Boolean($scope.savedWatcher.actions.webhook);
      }
    };

    $scope.switchViewFlag = function (flag) {
      if (flag) {
        $scope.viewFlag = true;
        $scope.manageViewArray(true);
        $scope.updateAction();
      } else {
        var proceed = confirm('Are you sure to delete this action?');
        if (proceed) {
          $scope.viewFlag = false;
          $scope.manageViewArray(false);
          $scope.deleteAction();
        }
      }
    };

    $scope.manageViewArray = function (flag) {
      switch ($scope.selectedchoose) {
        case 'E-Mail':
          $scope.activeform.email = flag;
          break;
        case 'HTML E-Mail':
          $scope.activeform.htmlemail = flag;
          break;
        case 'Slack':
          $scope.activeform.slack = flag;
          break;
        case 'Webhook':
          $scope.activeform.webhook = flag;
          break;
      }
    };

    $scope.goToCompiledForm = function (nameForm) {
      $scope.selectedchoose = nameForm;
      $scope.viewFlag = true;
    };

    $scope.deleteAction = function () {
      if ($scope.selectedchoose === $scope.watcher_choose[0]) {
        if ($scope.savedWatcher.actions.email) {
          delete $scope.savedWatcher.actions.email;
          $scope.initEmail();
        }
      } else if ($scope.selectedchoose === $scope.watcher_choose[1]) {
        if ($scope.savedWatcher.actions.email_html) {
          delete $scope.savedWatcher.actions.email_html;
          $scope.initEmailHtml();
        }
      } else if ($scope.selectedchoose === $scope.watcher_choose[2]) {
        if ($scope.savedWatcher.actions.slack) {
          delete $scope.savedWatcher.actions.slack;
          $scope.initSlack();
        }
      } else if ($scope.selectedchoose === $scope.watcher_choose[3]) {
        if ($scope.savedWatcher.actions.webhook) {
          delete $scope.savedWatcher.actions.webhook;
          $scope.initWebhook();
        }
      }
      $scope.selectedchoose = '';
    };

    $scope.updateAction = function () {
      if ($scope.selectedchoose === $scope.watcher_choose[0]) {
        $scope.savedWatcher.actions.email = {
          to: $scope.watcher_email_to ? $scope.watcher_email_to : 'alarm@localhost',
          from: $scope.watcher_email_from ? $scope.watcher_email_from : 'sentinl@localhost',
          subject: $scope.watcher_email_subj ? $scope.watcher_email_subj : 'Sentinl Alarm',
          priority: 'high',
          body: $scope.watcher_email_body ? $scope.watcher_email_body : 'Found {{payload.hits.total}} Events'
        };
      } else if ($scope.selectedchoose === $scope.watcher_choose[1]) {
        $scope.savedWatcher.actions.email_html = {
          to: $scope.watcher_email_html_to ? $scope.watcher_email_html_to : 'alarm@localhost',
          from: $scope.watcher_email_html_from ? $scope.watcher_email_html_from : 'sentinl@localhost',
          subject: $scope.watcher_email_html_subj ? $scope.watcher_email_html_subj : 'Sentinl Alarm',
          priority: 'high',
          body: $scope.watcher_email_html_body ? $scope.watcher_email_html_body : 'Found {{payload.hits.total}} Events',
          html: $scope.watcher_email_html_html ? $scope.watcher_email_html_html :
          '
Series Alarm {{payload._id}}: {{payload.hits.total}}
'
        };
      } else if ($scope.selectedchoose === $scope.watcher_choose[2]) {
        $scope.savedWatcher.actions.slack = {
          channel: $scope.watcher_slack_channel ? $scope.watcher_slack_channel : '#<channel>',
          message: $scope.watcher_slack_message ? $scope.watcher_slack_message : 'Series Alarm {{payload._id}}: {{payload.hits.total}}'
        };
      } else if ($scope.selectedchoose === $scope.watcher_choose[3]) {
        $scope.savedWatcher.actions.webhook = {
          method: $scope.watcher_webhook_method ? $scope.watcher_webhook_method : 'POST',
          host: $scope.watcher_webhook_host ? $scope.watcher_webhook_host : 'remote.server',
          port: $scope.watcher_webhook_port ? $scope.watcher_webhook_port : 9200,
          path: $scope.watcher_webhook_path ? $scope.watcher_webhook_path : '/{{payload.watcher_id}}',
          body: $scope.watcher_webhook_body ? $scope.watcher_webhook_body : '{{payload.watcher_id}}:{{payload.hits.total}}'
        };
      }
    };
    $scope.makeAlarm();
    $scope.updateAction();

  });
};

// Spy Placement
require('ui/registry/spy_modes').register(function () {
  return {
    display: 'Set Watcher',
    name: 'setalarm',
    order: 1000,
    link: linkReqRespStats,
    template: require('plugins/sentinl/button/alarm_spy.html')
  };
});
<|endoftext|>


<commit_before>"use strict";
define(
	['underscore', 'jquery'],
	function (_, $) {

/**
 * @exports Userlist
 */

/**
 * Userlist manages a ul, adding to & removing users from the list.
 * @constructor
 * @param {HTMLEntity} ul
 */
function Userlist(ul) {
	/** @public */
	this.ul = $(ul);
	/** @private */
	this._db = [];
}

function _userNick(dbEntry) {
	return dbEntry.user.nick;
}

function _makeUserFilter(user) {
	return function (e) {
		return user.equalTo(e.user);
	};
}

function _updateLiWithEntry(dbEntry) {
	$(dbEntry.li).attr('title', dbEntry.count + ' connection' + (dbEntry.count > 1 ? 's' : ''));
}

/**
 * Add a user.
 * @param {User} user
 */
Userlist.prototype.add = function(user) {
	/** @todo this looks terribly inefficient… */
	// check if the user was already connected
	var dbEntry = _.find(this._db, _makeUserFilter(user));
	if (dbEntry) {
		dbEntry.count++;
		_updateLiWithEntry(dbEntry);
		return $(dbEntry.li);
	}
	// create dom element
	var li = $('<li>')
		.text(user.nick)
		.css('color', user.color);
	// add new user
	this._db.push({user: user, li: li[0], count: 1});
	// rebuild sorted user view
	var db = _.sortBy(this._db, _userNick);
	this.removeAll();
	this._db = db;
	// render
	var self = this;
	_.each(db, function (dbEntry) {
		self.ul.append(dbEntry.li);
		_updateLiWithEntry(dbEntry);
	});
	return li;
};

/**
 * Remove a user.
 * @param {User} user
 */
Userlist.prototype.remove = function(user) {
	var userFilter = _makeUserFilter(user);
	var dbEntry = _.find(this._db, userFilter);
	if (dbEntry && --dbEntry.count === 0) {
		$(dbEntry.li).remove();
		this._db = _.reject(this._db, userFilter);
	} else {
		_updateLiWithEntry(dbEntry);
	}
};

/**
 * Clear the ul & internal db.
 */
Userlist.prototype.removeAll = function() {
	this.ul.empty();
	this._db = [];
};

return Userlist;

});
<commit_msg>fixed check for dbEntry<commit_after>"use strict";
define(
	['underscore', 'jquery'],
	function (_, $) {

/**
 * @exports Userlist
 */

/**
 * Userlist manages a ul, adding to & removing users from the list.
 * @constructor
 * @param {HTMLEntity} ul
 */
function Userlist(ul) {
	/** @public */
	this.ul = $(ul);
	/** @private */
	this._db = [];
}

function _userNick(dbEntry) {
	return dbEntry.user.nick;
}

function _makeUserFilter(user) {
	return function (e) {
		return user.equalTo(e.user);
	};
}

function _updateLiWithEntry(dbEntry) {
	$(dbEntry.li).attr('title', dbEntry.count + ' connection' + (dbEntry.count > 1 ? 's' : ''));
}

/**
 * Add a user.
 * @param {User} user
 */
Userlist.prototype.add = function(user) {
	/** @todo this looks terribly inefficient… */
	// check if the user was already connected
	var dbEntry = _.find(this._db, _makeUserFilter(user));
	if (dbEntry) {
		dbEntry.count++;
		_updateLiWithEntry(dbEntry);
		return $(dbEntry.li);
	}
	// create dom element
	var li = $('<li>')
		.text(user.nick)
		.css('color', user.color);
	// add new user
	this._db.push({user: user, li: li[0], count: 1});
	// rebuild sorted user view
	var db = _.sortBy(this._db, _userNick);
	this.removeAll();
	this._db = db;
	// render
	var self = this;
	_.each(db, function (dbEntry) {
		self.ul.append(dbEntry.li);
		_updateLiWithEntry(dbEntry);
	});
	return li;
};

/**
 * Remove a user.
 * @param {User} user
 */
Userlist.prototype.remove = function(user) {
	var userFilter = _makeUserFilter(user);
	var dbEntry = _.find(this._db, userFilter);
	if (dbEntry) {
		if (--dbEntry.count === 0) {
			$(dbEntry.li).remove();
			this._db = _.reject(this._db, userFilter);
		} else {
			_updateLiWithEntry(dbEntry);
		}
	}
};

/**
 * Clear the ul & internal db.
 */
Userlist.prototype.removeAll = function() {
	this.ul.empty();
	this._db = [];
};

return Userlist;

});
<|endoftext|>


<commit_before>define(function(require){
  require('partials/vizualisation/vizualisation');

  angular.module('cw.controllers', ['cw.controller.vizualisation'])

  .controller('mainController', function($scope){

  });
});
<commit_msg>adding files<commit_after>define(function(require){
  require('partials/vizualisation/vizualisation');

  angular.module('cw.controllers', ['cws.controller.vizualisation'])

  .controller('mainController', function($scope){

  });
});
<|endoftext|>


<commit_before>let config = require('./config');
let fs = require('fs');

/**
 *  @param {string} capital_name The username with proper capitalization
 *  @param {Collection<Snowflake, GuildMember>} members  A Map of [user id : member object]
 *  @param {int} index The index in cmds where this @mention is found
 *  @param {string[]} cmds Strings containing an action and potential extra parameters
 *  @return {string[2]} The display name and username of that user in that order
 */
function matchMention(capital_name, members, index, cmds) {
  let user = cmds[index];
  let display_name = '';
  let username = '';

  if (cmds.length > index) {
    if (/<@\d+>/.test(user)) {
      let user_id = user.substring(2, user.length - 1);
      let member = members.get(user_id);
      display_name = member.display_name;
      username = member.user.username;
    } else {
      display_name = capital_name;
      username = display_name;
    }
  }

  return [display_name, username];
}

/**
 *  @param {channel} channel The channel from which the original message came from
 *  @param {string[][2]} quotes An array of string[2]s which contain [username, text]
 */
function selectRandomQuote(channel, quotes) {
  if (quotes.size <= 0) {
    console.log("No quotes found");
    channel.send("No quotes found")
     .catch( reason => { console.log("Rejected Quote NoQuote Promise for " + reason); });
    return;
  }

  let rand = Math.random() * quotes.length - 1;
  let count = 0;

  for (let quote of quotes) {
    if (count >= rand) {
      channel.send("\"" + quote[1] + "\" - " + quote[0])
       .catch( reason => { console.log("Rejected Quote Read Promise for " + reason); });
      break;
    }
    count += 1;
  }
}

/**
 *  @param {channel} channel The channel from which the original message came from
 *  @param {string} name The username
 *  @param {message} message The last message from that username
 */
function addQuote(channel, name, message) {
  if (message != null) {
    fs.appendFile('quotes.txt', name + ':::' + message.content + '\n', function (err) {
      if (err) {
        console.log("Could not append quote to file");
        return;
      }
      channel.send("Added quote from " + name)
        .catch( reason => { console.log("Rejected Quote Added Promise for " + reason); });
      console.log('Quote added: ' + name + " ::: " + message.content);
    });
  } else {
    channel.send("No quote from that user found in the last 100 messages")
      .catch( reason => { console.log("Rejected Quote NoFound Promise for " + reason); });
    console.log('No Quote found');
  }
}

function addUserQuote(message, cmds) {
  let user = cmds.slice(2).join(' ');
  let name = matchMention(message.author.username, message.guild.members, 2, cmds);

  let last_message;
  message.channel.fetchMessages({ limit: 100})
   .then( messages => {
     for (let [key, value] of messages.entries()) {
       if (value.author.username.toLowerCase() == name[1].toLowerCase() && /!quote( add)?.*/i.test(value.content) == false) {
         last_message = value;
         break;
       }
     }

     addQuote(message.channel, name[0], last_message);
   })
   .catch( reason => { console.log("Rejected Quote Fetch Promise for " + reason); });
}

function searchQuote(message, cmds) {
  fs.readFile("quotes.txt", function(err, text) {
    if (err) {
      console.log("Failed to read Quote file: " + err);
      message.channel.send("Failed to find a quote")
       .catch( reason => { console.log("Rejected Quote SearchRead Promise for " + reason); });
      return;
    }

    let entries = text.toString().replace(/[\r\n]+/ig, ":::").split(/:{3}/);
    let quotes = [];

    let name = matchMention(message.author.username, message.guild.members, 1, cmds);

    for (let i = 0; i < entries.length - 1; i += 2) {
      if (cmds.length < 2 || name[0] == entries[i].toLowerCase()) {
        let entry = [entries[i], entries[i+1]];
        quotes.push(entry);
      }
    }

    selectRandomQuote(message.channel, quotes);
  });
}

/**
 * @param {message} message  A message object as defined in discord.js
 * @param {PermissionResolvable} permission The permission level required
 * @return {boolean} Whether or not the user has the permission
 */
function checkPermission(message, permission) {
  let admins = [];
  for (let [id, role] of message.guild.roles.entries()) {
    if (role.hasPermission(permission)) {
      admins = role.members;
      break;
    }
  }

  for (let [id, member] of admins.entries()) {
    if (member.id == message.author.id) {
      return true;
    }
  }

  return false;
}

function listQuotes(message, cmds) {
  if (checkPermission(message, 'ADMINISTRATOR')) {
    fs.readFile("quotes.txt", function(err, text) {
      if (err) {
        console.log("Failed to read Quote file: " + err);
        message.channel.send("Failed to find a quote")
         .catch( reason => { console.log("Rejected Quote ListRead Promise for " + reason); });
        return;
      }

      let entries = text.toString().replace(/[\r\n]+/ig, ":::").split(/:{3}/);
      let list = '';
      for (let i = 0; i < entries.length - 1; i += 2) {
          list += i/2 + ". " +  entries[i] + '\t - \"' + entries[i+1] + "\"\n";
      }
      message.channel.send(list)
        .catch( reason => { console.log("Rejected Quote ListPrint Promise for " + reason); });
    });
  } else {
    message.channel.send("You don't have the permission to do this!")
      .catch( reason => { console.log("Rejected Quote ListFail Promise for " + reason); });
  }
}

function deleteQuote(message, cmds) {
  if (checkPermission(message, 'ADMINISTRATOR')) {
    let new_entries = '';

    fs.readFile("quotes.txt", function(err, text) {
      if (err) {
        console.log("Failed to read Quote file: " + err);
        message.channel.send("Failed to find a quote")
         .catch( reason => { console.log("Rejected Quote DeleteRead Promise for " + reason); });
        return;
      }

      let entries = text.toString().replace(/[\r\n]+/ig, ":::").split(/:{3}/);
      let quotes = [];
      for (let i = 0; i < entries.length - 1; i += 2) {
        if(i == 2*cmds[2]) {
          continue;
        }
        let entry = [entries[i], entries[i+1]];
        quotes.push(entry);
      }

      for (let [name, text] of quotes) {
        new_entries += name + ":::" + text + "\n"
      }
      new_entries = new_entries.substring(0, new_entries.length);

      fs.writeFile("quotes.txt", new_entries, function(err) {
        if (err) {
          console.log("Failed to write Quote file: " + err);
          message.channel.send("Failed to write to file")
            .catch( reason => { console.log("Rejected Quote DeleteWrite Promise for " + reason); });
        }
      });
    });

    message.channel.send("Quote #" + cmds[2] + " deleted")
      .catch( reason => { console.log("Rejected Quote DelSuccess Promise for " + reason); });
  } else {
    message.channel.send("You don't have the permission to do this!")
      .catch( reason => { console.log("Rejected Quote DelFail Promise for " + reason); });
  }
}

/**
 *  @param {message} message  A message object as defined in discord.js
 *  @param {string[]} cmds Strings containing an action and potential extra parameters
 */
function quote(message, cmds) {
  switch (cmds[1]) {
    case 'add':
      addUserQuote(message, cmds);
      break;
    case 'list':
      listQuotes(message, cmds);
      break;
    case 'del':
      deleteQuote(message, cmds);
      break;
    default: {
      searchQuote(message, cmds);
    }
  }
}

module.exports = {quote};
<commit_msg>Revert "Moved Quote() to it's own file and refactored it - also fixed capitalization"<commit_after>let config = require('./config');
let fs = require('fs');

/**
 *  @param {Collection<Snowflake, GuildMember>} members  A Map of [user id : member object]
 *  @param {int} index The index in cmds where this @mention is found
 *  @param {string[]} cmds Strings containing an action and potential extra parameters
 *  @return {string[2]} The display name and username of that user in that order
 */
function matchMention(members, index, cmds) {
  let user = cmds[index];
  let display_name = '';
  let username = '';

  if (cmds.length > index) {
    if (/<@\d+>/.test(user)) {
      let user_id = user.substring(2, user.length - 1);
      let member = members.get(user_id);
      display_name = member.display_name.toLowerCase();
      username = member.user.username;
    } else {
      display_name = cmds.slice(index).join(' ');
      username = display_name;
    }
  }

  if (!display_name) {
    for (let [id, obj] of members) {
      let d_name = obj.displayName.toLowerCase();
      let u_name = obj.user.username.toLowerCase();

      if (d_name == user || u_name == user) {
        name = [d_name, u_name];
      }
    }
  }

  return [display_name, username];
}

/**
 *  @param {channel} channel The channel from which the original message came from
 *  @param {string[][2]} quotes An array of string[2]s which contain [username, text]
 */
function selectRandomQuote(channel, quotes) {
  if (quotes.size <= 0) {
    console.log("No quotes found");
    channel.send("No quotes found")
     .catch( reason => { console.log("Rejected Quote NoQuote Promise for " + reason); });
    return;
  }

  let rand = Math.random() * quotes.length - 1;
  let count = 0;

  for (let quote of quotes) {
    if (count >= rand) {
      channel.send("\"" + quote[1] + "\" - " + quote[0])
       .catch( reason => { console.log("Rejected Quote Read Promise for " + reason); });
      break;
    }
    count += 1;
  }
}

/**
 *  @param {channel} channel The channel from which the original message came from
 *  @param {string} name The username
 *  @param {message} message The last message from that username
 */
function addQuote(channel, name, message) {
  if (message != null) {
    fs.appendFile('quotes.txt', name + ':::' + message.content + '\n', function (err) {
      if (err) {
        console.log("Could not append quote to file");
        return;
      }
      channel.send("Added quote from " + name)
        .catch( reason => { console.log("Rejected Quote Added Promise for " + reason); });
      console.log('Quote added: ' + name + " ::: " + message.content);
    });
  } else {
    channel.send("No quote from that user found in the last 100 messages")
      .catch( reason => { console.log("Rejected Quote NoFound Promise for " + reason); });
    console.log('No Quote found');
  }
}

/**
 *  @param {message} message  A message object as defined in discord.js
 *  @param {string[]} cmds Strings containing an action and potential extra parameters
 */
function quote(message, cmds) {
  if (cmds[1] == 'add') {
    let user = cmds.slice(2).join(' ');
    let name = matchMention(message.guild.members, 2, cmds);

    let last_message;
    message.channel.fetchMessages({ limit: 100})
     .then( messages => {
       for (let [key, value] of messages.entries()) {
         if (value.author.username == name[1] && /!quote( add)?.*/i.test(value.content) == false) {
           last_message = value;
           break;
         }
       }

       addQuote(message.channel, name[0], last_message);
     })
     .catch( reason => { console.log("Rejected Quote Fetch Promise for " + reason); });
  } else {
    fs.readFile("quotes.txt", function(err, text) {
      if (err) {
        console.log("Failed to read Quote file: " + err);
        message.channel.send("Failed to find a quote")
         .catch( reason => { console.log("Rejected Quote Read Promise for " + reason); });
        return;
      }

      let entries = text.toString().replace(/[\r\n]+/ig, ":::").split(/:{3}/);
      let quotes = [];

      let name = matchMention(message.guild.members, 1, cmds);

      for (let i = 0; i < entries.length - 1; i += 2) {
        if (cmds.length < 2 || name[0] == entries[i].toLowerCase()) {
          let entry = [entries[i], entries[i+1]];
          quotes.push(entry);
        }
      }

      selectRandomQuote(message.channel, quotes);
    });
  }
}

module.exports = {quote};
<|endoftext|>


<commit_before>$(document).ready(function() {
    var socket = io();
    var $chatWindow = $('.chatWindow');
    var $chatInput = $('.messageTextInput');
    var $uname = $('.login_username');
    var dragEvents = 'drag dragstart dragend dragover dragenter dragleave drop';
    var userColors = {};

    //socket.emit('userConnect');

    $('.errorMsg').hide();
    var $loginBox = $('#LoginBoxContent');

    // set the width and height of the mask to cover the whole screen
    var maskHeight = $(document).height();
    var maskWidth = $(window).width();
    var $mask = $('#mask');
    $mask.css({'width':maskWidth, 'height':maskHeight});
    $mask.fadeIn(500);
    $mask.fadeTo("slow",0.9);

    // gethe window width and height and set the popup to center in the window
    var windowHeight = $(window).height();
    var windowWidth = $(window).width();
    $loginBox.css('top', windowHeight/2 - $loginBox.height() / 2);
    $loginBox.css('left', windowWidth/2 - $loginBox.width() / 2);
    $loginBox.fadeIn(2000);
    $uname.focus();

    // once the button is clicked
    $('.loginButton').click(function () {
        var username = $('.login_username').val();
        var chatroom = $('.login_chatroom').val();
        socket.emit('userConnect', username, chatroom);
        socket.on('ERROR', function(errorMsg) {
            $('.errorMsg').show();
        });
        socket.on('SUCCESS', function() {
            userColors[username] = genHexColor();
            $(mask).hide();
            $('.window').hide();
            $chatInput.focus();
        });
    });

    function genHexColor(){
        return '#'+Math.random().toString(16).slice(2,8);
    }

    function getUserColor(username){
        var uc;
        if(!userColors[username]){
            userColors[username] = genHexColor();
            uc = userColors[username];
        }else{
            uc = userColors[username];
        }
        return uc;
    }

    socket.on('updateChat', function(username, message) {
        var chatMessage = "
" + username + ":" + message + "
";
        if (username === 'EMF_HOST') {
            chatMessage = '
' + chatMessage + '
';
        }
        $chatWindow.append(chatMessage);
        $chatWindow[0].scrollTop = $chatWindow[0].scrollHeight;
    });

    socket.on('updateRooms', function(rooms) {
        var $lobbyWindow = $('.lobby');
        $lobbyWindow.empty();
        Object.keys(rooms).forEach(function(roomname) {
            var $room = $(document.createElement('h4'));
            $room.append(document.createTextNode(roomname));
            $lobbyWindow.append($room);
            $room.addClass('room');
            var userList = document.createElement('ul');
            $room.click(function() {
                console.log('Switch to ' + $room.text());
                socket.emit('switchRoom', $room.text());
            });
            var users = rooms[roomname];
            users.forEach(function(user) {
                $(userList).append("
"+user+"
");
            });
            $lobbyWindow.append(userList);
        });
    });

    $('.sendButton').click(function() {
        if ($chatInput.val()) {
            socket.emit('sendMessage', $chatInput.val());
            $chatInput.val("");
        }
    });

    $('.createRoom').click(function() {
        if($('.roomName').val().length <= 10 && $('.roomName').val().length != 0){
            socket.emit('switchRoom', $('.roomName').val());
        }
    });

    $chatInput.keyup(function(event) {
        if (event.keyCode == 13) {
            $('.sendButton').click();
        }
    });

    $('.login_username').keyup(function(event) {
        if (event.keyCode == 13) {
            $('.loginButton').click();
        }
    });

    $('.login_chatroom').keyup(function(event) {
        if (event.keyCode == 13) {
            $('.loginButton').click();
        }
    });

    $('.browserChatView').on(dragEvents, function(e) {
        e.preventDefault();
        e.stopPropagation();
    })
    .on('dragover dragenter', function() {
        // add dragover class
    })
    .on('dragleave dragend drop', function() {
        // remove dragover class
    })
    .on('drop', function(e) {
        // handle drop
        file = e.originalEvent.dataTransfer.files[0];
        if (file.size > 1048576) {
            alert('Whoa dude, that\'s like... a really big file.  Try something under 1 meg.');
        } else {
            var stream = ss.createStream();
            ss(socket).emit('file', stream, {
                size: file.size,
                name: file.name
            });
            ss.createBlobReadStream(file).pipe(stream);
        }
    });
});
<commit_msg>spacing between username and message<commit_after>$(document).ready(function() {
    var socket = io();
    var $chatWindow = $('.chatWindow');
    var $chatInput = $('.messageTextInput');
    var $uname = $('.login_username');
    var dragEvents = 'drag dragstart dragend dragover dragenter dragleave drop';
    var userColors = {};

    //socket.emit('userConnect');

    $('.errorMsg').hide();
    var $loginBox = $('#LoginBoxContent');

    // set the width and height of the mask to cover the whole screen
    var maskHeight = $(document).height();
    var maskWidth = $(window).width();
    var $mask = $('#mask');
    $mask.css({'width':maskWidth, 'height':maskHeight});
    $mask.fadeIn(500);
    $mask.fadeTo("slow",0.9);

    // gethe window width and height and set the popup to center in the window
    var windowHeight = $(window).height();
    var windowWidth = $(window).width();
    $loginBox.css('top', windowHeight/2 - $loginBox.height() / 2);
    $loginBox.css('left', windowWidth/2 - $loginBox.width() / 2);
    $loginBox.fadeIn(2000);
    $uname.focus();

    // once the button is clicked
    $('.loginButton').click(function () {
        var username = $('.login_username').val();
        var chatroom = $('.login_chatroom').val();
        socket.emit('userConnect', username, chatroom);
        socket.on('ERROR', function(errorMsg) {
            $('.errorMsg').show();
        });
        socket.on('SUCCESS', function() {
            userColors[username] = genHexColor();
            $(mask).hide();
            $('.window').hide();
            $chatInput.focus();
        });
    });

    function genHexColor(){
        return '#'+Math.random().toString(16).slice(2,8);
    }

    function getUserColor(username){
        var uc;
        if(!userColors[username]){
            userColors[username] = genHexColor();
            uc = userColors[username];
        }else{
            uc = userColors[username];
        }
        return uc;
    }

    socket.on('updateChat', function(username, message) {
        var chatMessage = "
" + username + ": " + message + "
";
        if (username === 'EMF_HOST') {
            chatMessage = '
' + chatMessage + '
';
        }
        $chatWindow.append(chatMessage);
        $chatWindow[0].scrollTop = $chatWindow[0].scrollHeight;
    });

    socket.on('updateRooms', function(rooms) {
        var $lobbyWindow = $('.lobby');
        $lobbyWindow.empty();
        Object.keys(rooms).forEach(function(roomname) {
            var $room = $(document.createElement('h4'));
            $room.append(document.createTextNode(roomname));
            $lobbyWindow.append($room);
            $room.addClass('room');
            var userList = document.createElement('ul');
            $room.click(function() {
                console.log('Switch to ' + $room.text());
                socket.emit('switchRoom', $room.text());
            });
            var users = rooms[roomname];
            users.forEach(function(user) {
                $(userList).append("
"+user+"
");
            });
            $lobbyWindow.append(userList);
        });
    });

    $('.sendButton').click(function() {
        if ($chatInput.val()) {
            socket.emit('sendMessage', $chatInput.val());
            $chatInput.val("");
        }
    });

    $('.createRoom').click(function() {
        if($('.roomName').val().length <= 10 && $('.roomName').val().length != 0){
            socket.emit('switchRoom', $('.roomName').val());
        }
    });

    $chatInput.keyup(function(event) {
        if (event.keyCode == 13) {
            $('.sendButton').click();
        }
    });

    $('.login_username').keyup(function(event) {
        if (event.keyCode == 13) {
            $('.loginButton').click();
        }
    });

    $('.login_chatroom').keyup(function(event) {
        if (event.keyCode == 13) {
            $('.loginButton').click();
        }
    });

    $('.browserChatView').on(dragEvents, function(e) {
        e.preventDefault();
        e.stopPropagation();
    })
    .on('dragover dragenter', function() {
        // add dragover class
    })
    .on('dragleave dragend drop', function() {
        // remove dragover class
    })
    .on('drop', function(e) {
        // handle drop
        file = e.originalEvent.dataTransfer.files[0];
        if (file.size > 1048576) {
            alert('Whoa dude, that\'s like... a really big file.  Try something under 1 meg.');
        } else {
            var stream = ss.createStream();
            ss(socket).emit('file', stream, {
                size: file.size,
                name: file.name
            });
            ss.createBlobReadStream(file).pipe(stream);
        }
    });
});
<|endoftext|>


<commit_before>angular.module('cleaver.controllers', ['ngAutocomplete'])

.controller('MainController', function($scope, $state, Rec) {
  angular.extend($scope, Rec);
  $scope.stateIs = $state.is;
  $scope.inputOptions = {
    types: 'geocode',
    country: 'us',
    watchEnter: true
  };
  $scope.lastVeto = {};

  angular.element(document.body).css('background-image', 'url("../img/background_' +
    (Math.floor(Math.random() * 5) + 1) + '.jpg")');

  $scope.undoIt = function(){
    Rec.undo($scope.lastVeto);
    $scope.lastVeto = {};
    angular.element(document.querySelectorAll('#undoButton')).addClass('disabled');
  };

  $scope.vetoRestaurant = function(restaurantID){
    Rec.vetoRestaurant(restaurantID);
    $scope.lastVeto = {
      key: 'id',
      val: restaurantID
    };
  };

  $scope.vetoCategory = function(category){
    Rec.vetoCategory(category);
    $scope.lastVeto = {
      key: 'category',
      val: category
    };
  };

  // submits the user's location input
  $scope.enterLocation = function(keyEvent) {
    if ($scope.details && (keyEvent === undefined || keyEvent.which === 13)) {
      $scope.postLocation($scope.details.formatted_address.slice(0, -5));
      $scope.details = null;
      angular.element(document.querySelector('i')).toggleClass('search').toggleClass('spinner loading');
    }
  };

});
<commit_msg>added documentation<commit_after>angular.module('cleaver.controllers', ['ngAutocomplete'])

.controller('MainController', function($scope, $state, Rec) {
  angular.extend($scope, Rec);

  $scope.stateIs = $state.is;
  $scope.lastVeto = {};
  $scope.inputOptions = {
    types: 'geocode',
    country: 'us',
    watchEnter: true
  };

  angular.element(document.body).css('background-image', 'url("../img/background_' +
    (Math.floor(Math.random() * 5) + 1) + '.jpg")');

  // takes "enter" key event and submits the user's location input
  $scope.enterLocation = function(keyEvent) {
    if ($scope.details && (keyEvent === undefined || keyEvent.which === 13)) {
      $scope.postLocation($scope.details.formatted_address.slice(0, -5));
      $scope.details = null;
      angular.element(document.querySelector('i')).toggleClass('search').toggleClass('spinner loading');
    }
  };

  // adds vetoed restaurant to the veto array
  $scope.vetoRestaurant = function(restaurantID){
    Rec.vetoRestaurant(restaurantID);
    $scope.lastVeto = {
      key: 'id',
      val: restaurantID
    };
  };

  // adds the vetoed category to veto array
  $scope.vetoCategory = function(category){
    Rec.vetoCategory(category);
    $scope.lastVeto = {
      key: 'category',
      val: category
    };
  };

  // removes the last vetoed category or restaurant from the veto list
  $scope.undoIt = function(){
    Rec.undo($scope.lastVeto);
    $scope.lastVeto = {};
    angular.element(document.querySelectorAll('#undoButton')).addClass('disabled');
  };

});
<|endoftext|>


<commit_before>angular.module('cleaver.controllers', [])

.controller('MainController', function($scope, Rec) {
  angular.extend($scope, Rec);

  //TODO: clear input box on enter
  $scope.enter = function(keyEvent, location) {
    if (location && keyEvent.which === 13) {
      $scope.postLocation(location);
    }
  };

});
<commit_msg>added uiview on keypress<commit_after>angular.module('cleaver.controllers', [])

.controller('MainController', function($scope, $state, Rec) {
  angular.extend($scope, Rec);

  //TODO: clear input box on enter
  $scope.enter = function(keyEvent, location) {
    if (location && keyEvent.which === 13) {
      $scope.postLocation(location);
      $state.go('rec');
    }
  };

});
<|endoftext|>


<commit_before><script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-46121892-4', 'auto');
  ga('send', 'pageview');

</script>
<commit_msg>Fix GA<commit_after>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-46121892-4', 'auto');
ga('send', 'pageview');
<|endoftext|>


<commit_before>//Insert player code<commit_msg>Added player code, without collisions<commit_after>//Insert player code
var Player = function() {
	this.x = 20;
	this.y = 20;
	this.width = 20;
	this.height = 20;

	this.velX = 0;
	this.velY = 0;
	this.falling = true;
};

Player.prototype.draw = function() {
	c.fillStyle = "#000000"
	c.fillRect(this.x, this.y, this.width, this.height);
}

Player.prototype.update = function() {

	if (keys["ArrowLeft"]) {
		this.velX -= 0.5;
	}

	if (keys["ArrowRight"]) {
        this.velX+=0.5;
    }

	if (keys["ArrowUp"]) {
		this.velY-=8;
	}
	this.falling = true;

	this.velY+=0.3;

    this.x+=this.velX;
    this.collide(this.velX, 0);
    this.y+=this.velY;
    this.collide(0, this.velY);

	this.velX /= 1.1;

}

Player.prototype.collide = function(velX, velY) {
	//Insert code when block class is complete
}
<|endoftext|>


<commit_before>// Copyright 2021, University of Colorado Boulder

/**
 * Manages output of responses for the Voicing feature. First, see Voicing.js for a description of what that includes.
 * This singleton is responsible for controlling when responses of each category are spoken when speech is
 * requested for a Node composed with Voicing.
 *
 * // REVIEW: I'm unsure if this type really needs to be here. Does it belong in scenery? Does it need to be a singleton?
 * // Why can't it be combined in another location like webSpeaker or something else. I guess my feelings are that it
 * // doesn't do that much, but that may not be a good enough reason to try to change or refactor it. Thoughts? https://github.com/phetsims/scenery/issues/1223
 *
 * @author Jesse Greenberg (PhET Interactive Simulations)
 */

import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
import merge from '../../../../phet-core/js/merge.js';
import StringUtils from '../../../../phetcommon/js/util/StringUtils.js';
import scenery from '../../scenery.js';
import VoicingResponsePatterns from './VoicingResponsePatterns.js';

class VoicingManager {
  constructor() {

    // @public {BooleanProperty} - whether or not component names are read as input lands on various components
    this.nameResponsesEnabledProperty = new BooleanProperty( true );

    // @public {BooleanProperty} - whether or not "Object Responses" are read as interactive components change
    this.objectResponsesEnabledProperty = new BooleanProperty( true );

    // @public {BooleanProperty} - whether or not "Context Responses" are read as inputs receive interaction
    this.contextResponsesEnabledProperty = new BooleanProperty( true );

    // @public {BooleanProperty} - whether or not "Hints" are read to the user in response to certain input
    this.hintResponsesEnabledProperty = new BooleanProperty( false );

    // @public {BooleanProperty} - Controls whether Voicing is enabled in a "main window" area of the application.
    // This supports the ability to disable Voicing for the important screen content of your simulation while keeping
    // Voicing for surrounding UI components enabled. At the time of this writing, all "Reading Blocks" are disabled
    // when Voicing for the "main window" is disabled. See ReadingBlock.js for more information.
    this.mainWindowVoicingEnabledProperty = new BooleanProperty( true );
  }

  /**
   * Prepares final output with an object response, a context response, and a hint. Each response
   * will only be added to the final string if that response type is included by the user. Rather than using
   * unique utterances, we use string interpolation so that the highlight around the abject being spoken
   * about stays lit for the entire combination of responses.
   * @public
   *
   * @param {Object} [options]
   * @returns {string}
   */
  collectResponses( options ) {

    options = merge( {

      // {string|null} - spoken when name responses are enabled
      nameResponse: null,

      // {string|null} - spoken when object responses are enabled
      objectResponse: null,

      // {string|null} - spoken when context responses are enabled
      contextResponse: null,

      // {string|null} - spoken when interaction hints are enabled
      hintResponse: null,

      // {boolean} - if true, the nameResponse, objectResponse, contextResponse, and interactionHint will all be spoken
      // regardless of the values of the Properties of voicingManager
      ignoreProperties: false,

      // {Object} - The collection of string patterns to use when assembling responses based on which
      // responses are provided and which voicingManager Properties are true. See VoicingResponsePatterns
      // if you do not want to use the default.
      responsePatterns: VoicingResponsePatterns.DEFAULT_RESPONSE_PATTERNS
    }, options );

    VoicingResponsePatterns.validatePatternKeys( options.responsePatterns );

    const usesNames = options.nameResponse && ( this.nameResponsesEnabledProperty.get() || options.ignoreProperties );
    const usesObjectChanges = options.objectResponse && ( this.objectResponsesEnabledProperty.get() || options.ignoreProperties );
    const usesContextChanges = options.contextResponse && ( this.contextResponsesEnabledProperty.get() || options.ignoreProperties );
    const usesInteractionHints = options.hintResponse && ( this.hintResponsesEnabledProperty.get() || options.ignoreProperties );
    const responseKey = VoicingResponsePatterns.createPatternKey( usesNames, usesObjectChanges, usesContextChanges, usesInteractionHints );

    let finalResponse = '';
    if ( responseKey ) {

      // graceful if the responseKey is empty, but if we formed some key, it should
      // be defined in responsePatterns
      const patternString = options.responsePatterns[ responseKey ];
      assert && assert( patternString, `no pattern string found for key ${responseKey}` );

      finalResponse = StringUtils.fillIn( patternString, {
        NAME: options.nameResponse,
        OBJECT: options.objectResponse,
        CONTEXT: options.contextResponse,
        HINT: options.hintResponse
      } );
    }

    return finalResponse;
  }
}

const voicingManager = new VoicingManager();

scenery.register( 'voicingManager', voicingManager );
export default voicingManager;
<commit_msg>Promote review comment to issue, see https://github.com/phetsims/scenery/issues/1227 and https://github.com/phetsims/scenery/issues/1223<commit_after>// Copyright 2021, University of Colorado Boulder

/**
 * Manages output of responses for the Voicing feature. First, see Voicing.js for a description of what that includes.
 * This singleton is responsible for controlling when responses of each category are spoken when speech is
 * requested for a Node composed with Voicing.
 *
 * @author Jesse Greenberg (PhET Interactive Simulations)
 */

import BooleanProperty from '../../../../axon/js/BooleanProperty.js';
import merge from '../../../../phet-core/js/merge.js';
import StringUtils from '../../../../phetcommon/js/util/StringUtils.js';
import scenery from '../../scenery.js';
import VoicingResponsePatterns from './VoicingResponsePatterns.js';

class VoicingManager {
  constructor() {

    // @public {BooleanProperty} - whether or not component names are read as input lands on various components
    this.nameResponsesEnabledProperty = new BooleanProperty( true );

    // @public {BooleanProperty} - whether or not "Object Responses" are read as interactive components change
    this.objectResponsesEnabledProperty = new BooleanProperty( true );

    // @public {BooleanProperty} - whether or not "Context Responses" are read as inputs receive interaction
    this.contextResponsesEnabledProperty = new BooleanProperty( true );

    // @public {BooleanProperty} - whether or not "Hints" are read to the user in response to certain input
    this.hintResponsesEnabledProperty = new BooleanProperty( false );

    // @public {BooleanProperty} - Controls whether Voicing is enabled in a "main window" area of the application.
    // This supports the ability to disable Voicing for the important screen content of your simulation while keeping
    // Voicing for surrounding UI components enabled. At the time of this writing, all "Reading Blocks" are disabled
    // when Voicing for the "main window" is disabled. See ReadingBlock.js for more information.
    this.mainWindowVoicingEnabledProperty = new BooleanProperty( true );
  }

  /**
   * Prepares final output with an object response, a context response, and a hint. Each response
   * will only be added to the final string if that response type is included by the user. Rather than using
   * unique utterances, we use string interpolation so that the highlight around the abject being spoken
   * about stays lit for the entire combination of responses.
   * @public
   *
   * @param {Object} [options]
   * @returns {string}
   */
  collectResponses( options ) {

    options = merge( {

      // {string|null} - spoken when name responses are enabled
      nameResponse: null,

      // {string|null} - spoken when object responses are enabled
      objectResponse: null,

      // {string|null} - spoken when context responses are enabled
      contextResponse: null,

      // {string|null} - spoken when interaction hints are enabled
      hintResponse: null,

      // {boolean} - if true, the nameResponse, objectResponse, contextResponse, and interactionHint will all be spoken
      // regardless of the values of the Properties of voicingManager
      ignoreProperties: false,

      // {Object} - The collection of string patterns to use when assembling responses based on which
      // responses are provided and which voicingManager Properties are true. See VoicingResponsePatterns
      // if you do not want to use the default.
      responsePatterns: VoicingResponsePatterns.DEFAULT_RESPONSE_PATTERNS
    }, options );

    VoicingResponsePatterns.validatePatternKeys( options.responsePatterns );

    const usesNames = options.nameResponse && ( this.nameResponsesEnabledProperty.get() || options.ignoreProperties );
    const usesObjectChanges = options.objectResponse && ( this.objectResponsesEnabledProperty.get() || options.ignoreProperties );
    const usesContextChanges = options.contextResponse && ( this.contextResponsesEnabledProperty.get() || options.ignoreProperties );
    const usesInteractionHints = options.hintResponse && ( this.hintResponsesEnabledProperty.get() || options.ignoreProperties );
    const responseKey = VoicingResponsePatterns.createPatternKey( usesNames, usesObjectChanges, usesContextChanges, usesInteractionHints );

    let finalResponse = '';
    if ( responseKey ) {

      // graceful if the responseKey is empty, but if we formed some key, it should
      // be defined in responsePatterns
      const patternString = options.responsePatterns[ responseKey ];
      assert && assert( patternString, `no pattern string found for key ${responseKey}` );

      finalResponse = StringUtils.fillIn( patternString, {
        NAME: options.nameResponse,
        OBJECT: options.objectResponse,
        CONTEXT: options.contextResponse,
        HINT: options.hintResponse
      } );
    }

    return finalResponse;
  }
}

const voicingManager = new VoicingManager();

scenery.register( 'voicingManager', voicingManager );
export default voicingManager;
<|endoftext|>


<commit_before>'use strict';

const BaseEntity = require('./baseentity.js');

var itemDefinitionIndexMap = {
  1: 'Desert Eagle',
  2: 'Dual Berettas',
  3: 'Five-SeveN',
  4: 'Glock-18',
  7: 'AK-47',
  8: 'AUG',
  9: 'AWP',
  10: 'FAMAS',
  11: 'G3SG1',
  13: 'Galil AR', 14: 'M249',
  16: 'M4A4',
  17: 'MAC-10',
  19: 'P90',
  24: 'UMP-45',
  25: 'XM1014',
  26: 'PP-Bizon',
  27: 'MAG-7',
  28: 'Negev',
  29: 'Sawed-Off',
  30: 'Tec-9',
  31: 'Zeus x27',
  32: 'P2000',
  33: 'MP7',
  34: 'MP9',
  35: 'Nova',
  36: 'P250',
  38: 'SCAR-20',
  39: 'SG 553',
  40: 'SSG 08',
  42: 'Knife',
  43: 'Flashbang',
  44: 'High Explosive Grenade',
  45: 'Smoke Grenade',
  46: 'Molotov',
  47: 'Decoy Grenade',
  48: 'Incendiary Grenade',
  49: 'C4 Explosive',
  58: 'Music Kit',
  59: 'Knife',
  60: 'M4A1-S',
  61: 'USP-S',
  63: 'CZ75-Auto',
  64: 'R8 Revolver',
  500: 'Bayonet',
  505: 'Flip Knife',
  506: 'Gut Knife',
  507: 'Karambit',
  508: 'M9 Bayonet',
  509: 'Huntsman Knife',
  512: 'Falchion Knife',
  514: 'Bowie Knife',
  515: 'Butterfly Knife',
  516: 'Shadow Dag',
};

/**
 * Represents an in-game weapon (guns, grenades, knifes).
 */
class Weapon extends BaseEntity {
  /**
   * @returns {string} Name of the weapon
   */
  get name() {
    var weaponId = this.getProp('DT_ScriptCreatedItem', 'm_iItemDefinitionIndex');

    return itemDefinitionIndexMap[weaponId] != undefined ? itemDefinitionIndexMap[weaponId] : 'unknown';
  }

  /**
   * @returns {Player|null} Previous Owner
   */
  get prevOwner() {
    var userId = this.getProp('DT_WeaponCSBase', 'm_hPrevOwner'),
        user = null;

    if (user = this._demo.entities.getByUserId(userId)) {
      return user;
    }

    return null;
  }
}

module.exports = Weapon;
<commit_msg>Adding name property to Weapon entity<commit_after>'use strict';

const BaseEntity = require('./baseentity.js');

var itemDefinitionIndexMap = {
  1: {
    itemName: 'Desert Eagle',
    name: 'weapon_deagle',
  },
  2: {
    itemName: 'Dual Berettas',
    name: 'weapon_elite',
  },
  3: {
    itemName: 'Five-SeveN',
    name: 'weapon_fiveseven',
  },
  4: {
    itemName: 'Glock-18',
    name: 'weapon_glock',
  },
  7: {
    itemName: 'AK-47',
    name: 'weapon_ak47',
  },
  8: {
    itemName: 'AUG',
    name: 'weapon_aug',
  },
  9: {
    itemName: 'AWP',
    name: 'weapon_awp',
  },
  10: {
    itemName: 'FAMAS',
    name: 'weapon_famas',
  },
  11: {
    itemName: 'G3SG1',
    name: 'weapon_g3sg1',
  },
  13: {
    itemName: 'Galil AR',
    name: 'weapon_galilar',
  },
  14: {
    itemName: 'M249',
    name: 'weapon_m249',
  },
  16: {
    itemName: 'M4A4',
    name: 'weapon_m4a1',
  },
  17: {
    itemName: 'MAC-10',
    name: 'weapon_mac10',
  },
  19: {
    itemName: 'P90',
    name: 'weapon_p90',
  },
  24: {
    itemName: 'UMP-45',
    name: 'weapon_ump45',
  },
  25: {
    itemName: 'XM1014',
    name: 'weapon_xm1014',
  },
  26: {
    itemName: 'PP-Bizon',
    name: 'weapon_bizon',
  },
  27: {
    itemName: 'MAG-7',
    name: 'weapon_mag7',
  },
  28: {
    itemName: 'Negev',
    name: 'weapon_negev',
  },
  29: {
    itemName: 'Sawed-Off',
    name: 'weapon_sawedoff',
  },
  30: {
    itemName: 'Tec-9',
    name: 'weapon_tec9',
  },
  31: {
    itemName: 'Zeus x27',
    name: 'weapon_taser',
  },
  32: {
    itemName: 'P2000',
    name: 'weapon_hkp2000',
  },
  33: {
    itemName: 'MP7',
    name: 'weapon_mp7',
  },
  34: {
    itemName: 'MP9',
    name: 'weapon_mp9',
  },
  35: {
    itemName: 'Nova',
    name: 'weapon_nova',
  },
  36: {
    itemName: 'P250',
    name: 'weapon_p250',
  },
  38: {
    itemName: 'SCAR-20',
    name: 'weapon_scar20',
  },
  39: {
    itemName: 'SG 553',
    name: 'weapon_sg556',
  },
  40: {
    itemName: 'SSG 08',
    name: 'weapon_ssg08',
  },
  42: {
    itemName: 'Knife',
    name: 'weapon_knife',
  },
  43: {
    itemName: 'Flashbang',
    name: 'weapon_flashbang',
  },
  44: {
    itemName: 'High Explosive Grenade',
    name: 'weapon_hegrenade',
  },
  45: {
    itemName: 'Smoke Grenade',
    name: 'weapon_smokegrenade',
  },
  46: {
    itemName: 'Molotov',
    name: 'weapon_molotov',
  },
  47: {
    itemName: 'Decoy Grenade',
    name: 'weapon_decoy',
  },
  48: {
    itemName: 'Incendiary Grenade',
    name: 'weapon_incgrenade',
  },
  49: {
    itemName: 'C4 Explosive',
    name: 'weapon_c4',
  },
  59: {
    itemName: 'Knife',
    name: 'weapon_knife_t',
  },
  60: {
    itemName: 'M4A1-S',
    name: 'weapon_m4a1_silencer',
  },
  61: {
    itemName: 'USP-S',
    name: 'weapon_usp_silencer',
  },
  63: {
    itemName: 'CZ75-Auto',
    name: 'weapon_cz75a',
  },
  64: {
    itemName: 'R8 Revolver',
    name: 'weapon_revolver',
  },
  500: {
    itemName: 'Bayonet',
    name: 'weapon_bayonet',
  },
  505: {
    itemName: 'Flip Knife',
    name: 'weapon_knife_flip',
  },
  506: {
    itemName: 'Gut Knife',
    name: 'weapon_knife_gut',
  },
  507: {
    itemName: 'Karambit',
    name: 'weapon_knife_karambit',
  },
  508: {
    itemName: 'M9 Bayonet',
    name: 'weapon_knife_m9_bayonet',
  },
  509: {
    itemName: 'Huntsman Knife',
    name: 'weapon_knife_tactical',
  },
  512: {
    itemName: 'Falchion Knife',
    name: 'weapon_knife_falchion',
  },
  514: {
    itemName: 'Bowie Knife',
    name: 'weapon_knife_survival_bowie',
  },
  515: {
    itemName: 'Butterfly Knife',
    name: 'weapon_knife_butterfly',
  },
  516: {
    itemName: 'Shadow Dag',
    name: 'weapon_knife_push',
  },
};

/**
 * Represents an in-game weapon (guns, grenades, knifes).
 */
class Weapon extends BaseEntity {
  /**
   * @returns {integer} Item index
   */
  get itemIndex() {
    return this.getProp('DT_ScriptCreatedItem', 'm_iItemDefinitionIndex');
  }

  /**
   * @returns {string} Name of the weapon
   */
  get itemName() {
    var weaponId = this.itemIndex;

    return itemDefinitionIndexMap[weaponId] != undefined ? itemDefinitionIndexMap[weaponId].itemName : 'unknown';
  }

  get name() {
    var weaponId = this.itemIndex;

    return itemDefinitionIndexMap[weaponId] != undefined ? itemDefinitionIndexMap[weaponId].name : 'unknown';
  }

  /**
   * @returns {Player|null} Previous Owner
   */
  get prevOwner() {
    var userId = this.getProp('DT_WeaponCSBase', 'm_hPrevOwner'),
        user = null;

    if (user = this._demo.entities.getByUserId(userId)) {
      return user;
    }

    return null;
  }
}

module.exports = Weapon;
<|endoftext|>


<commit_before>'use strict';

angular.module('gambo.posts')
    .constant('PostsQueries',
    {
        ACCESS_TOKEN : window.accessToken,

        MY : [
            'SELECT ',
                'type,',
                'attachment,',
                'permalink,',
                'post_id,',
                'message,',
                'message_tags,',
                'like_info.like_count,',
                'comment_info.comment_count,',
                'share_count,',
                'claim_count,',
                '(like_info.like_count * comment_info.comment_count * share_count)',
            ' FROM stream',
            ' WHERE filter_key = "owner" and type in (128,247,308)',
            ' ORDER BY (like_info.like_count * comment_info.comment_count * share_count) DESC '
        ].join(''),

        FRIENDS : [
            'SELECT ',
                'type,',
                'attachment,',
                'permalink,',
                'post_id,',
                'message,',
                'message_tags,',
                'like_info.like_count,',
                'comment_info.comment_count,',
                'share_count,',
                'claim_count,',
                '(like_info.like_count * comment_info.comment_count * share_count)',
            ' FROM stream',
            ' WHERE source_id in (SELECT gid FROM group_member WHERE uid in (SELECT uid1 from friend where uid2 = me())) and type in (128,247,308)',
            ' ORDER BY (like_info.like_count * comment_info.comment_count * share_count) DESC '
        ].join(''),

        POPULAR : ''
    }
);<commit_msg>change fql queries ordering logic<commit_after>'use strict';

angular.module('gambo.posts')
    .constant('PostsQueries',
    {
        ACCESS_TOKEN : window.accessToken,

        MY : [
            'SELECT ',
                'type,',
                'attachment,',
                'permalink,',
                'post_id,',
                'message,',
                'message_tags,',
                'like_info.like_count,',
                'comment_info.comment_count,',
                'share_count,',
                'claim_count,',
                '(1-like_info.like_count-comment_info.comment_count-share_count)',
            ' FROM stream',
            ' WHERE filter_key = "owner" and type in (128,247,308)',
            ' ORDER BY (1-like_info.like_count-comment_info.comment_count-share_count) '
        ].join(''),

        FRIENDS : [
            'SELECT ',
                'type,',
                'attachment,',
                'permalink,',
                'post_id,',
                'message,',
                'message_tags,',
                'like_info.like_count,',
                'comment_info.comment_count,',
                'share_count,',
                'claim_count,',
                '(1-like_info.like_count-comment_info.comment_count-share_count)',
            ' FROM stream',
            ' WHERE source_id in (SELECT gid FROM group_member WHERE uid in (SELECT uid1 from friend where uid2 = me())) and type in (128,247,308)',
            ' ORDER BY (1-like_info.like_count-comment_info.comment_count-share_count) '
        ].join(''),

        POPULAR : ''
    }
);<|endoftext|>