<commit_before>/* See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Esri Inc. licenses this file to You 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.
 */
define(["dojo/_base/declare",
        "dojo/_base/lang",
        "dojo/_base/array",
        "dojo/date",
        "dojo/date/stamp",
        "dojo/dom-construct",
        "dojo/dom-geometry",
        "dojo/text!./templates/TemporalFilter.html",
        "dojo/i18n!app/nls/resources",
        "app/search/SearchComponent",
        "app/search/DropPane",
        "app/search/QClause",
        "app/search/TemporalFilterSettings"],
function(declare, lang, array, djDate, stamp, domConstruct, domGeometry,
    template, i18n, SearchComponent, DropPane, QClause, TemporalFilterSettings) {

  var oThisClass = declare([SearchComponent], {

    i18n: i18n,
    templateString: template,

    allowSettings: null,
    field: null,
    toField: null,
    nestedPath: null,
    interval: "year", // year, quarter, month, week, day, hour, minute, second
    useUTC: true,

    label: i18n.search.temporalFilter.label,
    open: false,

    _aggDates: null,
    _aggEndDates: null,
    _aggInterval: null,
    _brushExtent: null,
    _searchDisabled: false,

    _fromDate: null,
    _toDate: null,

    _initialSettings: null,

    postCreate: function() {
      this.inherited(arguments);

      this._initialSettings = {
        label: this.label,
        field: this.field,
        toField: this.toField,
        nestedPath: this.nestedPath,
        interval: this.interval,
        useUTC: this.useUTC
      };

      $(this.intervalSelect).val(this.interval);
      this.plot();

      if (this.allowSettings === null) {
        if (AppContext.appConfig.search && !!AppContext.appConfig.search.allowSettings) {
          this.allowSettings = true;
        }
      }
      if (this.allowSettings) {
        var link = this.dropPane.addSettingsLink();
        link.onclick = lang.hitch(this,function(e) {
          var d = new TemporalFilterSettings({
            targetWidget: this
          });
          d.showDialog();
        });
      }
    },

    advanceToUpper: function(toDate) {
      if (!toDate) return null;
      if (!this.hasToField) return toDate;
      var dt = toDate;
      var interval = this._aggInterval;
      var intervals = ["year", "quarter", "month", "week", "day", "hour", "minute", "second"];
      if (intervals.indexOf(interval) !== -1) {
        dt = djDate.add(dt,interval,1);
        dt = djDate.add(dt,"millisecond",-1);
      }
      return dt;
    },

    applyBrushExtent: function() {
      var ext = this._brushExtent;
      if (ext && ext.length === 2) {
        this._fromDate = ext[0];
        this._toDate = ext[1];
        this.search();
      }
    },

    formatDate: function(date) {
      if (!date) return "";
      var options = {zulu:this.useUTC};
      return stamp.toISOString(date,options);
    },

    formatDateRange: function(fromDate,toDate,forSearchLink) {
      var v = "", rangePattern;
      if (fromDate || toDate) {
        rangePattern = i18n.search.temporalFilter.rangePattern;
        v = rangePattern.replace("{from}",this.formatDate(fromDate));
        v = v.replace("{to}",this.formatDate(toDate));
      }
      return v;
    },

    hasNestedPath: function() {
      return (typeof this.nestedPath === "string" && this.nestedPath.length > 0);
    },

    hasToField: function() {
      return (typeof this.toField === "string" && this.toField.length > 0);
    },

    intervalChanged: function() {
      this.interval = $(this.intervalSelect).val();
      this.search();
    },

    plot: function() {
      var self = this, svgNode = this.svgNode, hasTo = this.hasToField();
      domConstruct.empty(svgNode);
      this._brushExtent = null;
      this.setNodeText(this.brushExtentNode,"");

      var countPattern = i18n.search.temporalFilter.countPattern;
      var fmtTip = function(d) {
        var s1 = self.formatDate(d.date);
        var s2 = countPattern.replace("{count}",d.count);
        return s1+"
"+s2;
      };

      var data = [], dtLast = null;
      if (this._aggDates && this._aggDates.buckets) {
        array.forEach(this._aggDates.buckets,function(bucket){
          var dt = stamp.fromISOString(bucket.key_as_string);
          dtLast = dt;
          data.push({date:dt,count:bucket.doc_count});
        });
      }
      if (this._aggEndDates && this._aggEndDates.buckets) {
        array.forEach(this._aggEndDates.buckets,function(bucket){
          var dt = stamp.fromISOString(bucket.key_as_string);
          if (!dtLast || dt > dtLast) {
            data.push({date:dt,count:bucket.doc_count});
          }
        });
      }

      var w = 150; // 350
      var pos = domGeometry.position(this.dropPane.domNode);
      console.warn("pos",pos.w,pos);
      if (pos.w > 150) {
        w = (pos.w - 25);
      }
      var margin = {top: 10, right: 20, bottom: 80, left: 40};
      var width = w - margin.left - margin.right;
      var height = 70;
      var x = d3.time.scale().range([0, width]);
      var y = d3.scale.linear().range([height, 0]);
      var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(3);
      var yAxis = d3.svg.axis().scale(y).orient("left").ticks(3);
      var xMap = function(d) {return x(d.date);};
      var yMap = function(d) {return y(d.count);};
      x.domain(d3.extent(data.map(function(d){return d.date;})));
      y.domain([0, d3.max(data.map(function(d){return d.count;}))]);

      var margin2 = {top: margin.top+height+25, right: 20, bottom: 20, left: 40};
      var height2 = 35;
      var x2 = d3.time.scale().range([0, width]);
      var y2 = d3.scale.linear().range([height2, 0]);
      var xAxis2 = d3.svg.axis().scale(x2).orient("bottom").ticks(3);
      x2.domain(x.domain());
      y2.domain(y.domain());
      var area2 = d3.svg.area()
        .interpolate("monotone")
        .x(function(d){return x2(d.date);})
        .y0(height2)
        .y1(function(d){ return y2(d.count);});

      var svg = d3.select(svgNode).append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom);

      var tooltip = d3.select(svgNode).append("div")
        .attr("class", "tooltip")
        .style("opacity", 0);

      var focus = svg.append("g")
        .attr("class", "focus")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
      focus.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);
      focus.append("g")
        .attr("class", "y axis")
        .call(yAxis);
      /*
      var clipId = this.id+"_clip";
      var clipUrl = "url("+clipId+")";
      focus.append("defs").append("clipPath")
          .attr("id",clipId)
        .append("rect")
          .attr("width", width)
          .attr("height", height);
      focus.append("g").attr("clip-path",clipUrl);
      */
      focus.selectAll(".dot")
        .data(data)
      .enter().append("circle")
        .attr("class", "dot")
        .attr("r", 3.5)
        .attr("cx", function(d) {return x(d.date);})
        .attr("cy", function(d) {return y(d.count);})
        .on("mouseover", function(d) {
          tooltip.transition()
           .duration(200)
           .style("opacity", 1);
          tooltip.html(fmtTip(d))
           .style("left", (d3.event.pageX + 16) + "px")
           .style("top", (d3.event.pageY - 38) + "px");
        })
        .on("mouseout", function(d) {
          tooltip.transition()
           .duration(500)
           .style("opacity", 0);
        });

      var context = svg.append("g")
        .attr("class", "context")
        .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
      context.append("path")
        .datum(data)
        .attr("class", "area")
        .attr("d", area2);
      context.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height2 + ")")
        .call(xAxis2);
      if (data.length > 0) {
        var arc = d3.svg.arc()
        .outerRadius(height2 / 2)
        .startAngle(0)
        .endAngle(function(d, i) { return i ? -Math.PI : Math.PI; });
        var brush = d3.svg.brush()
          .x(x2)
          .extent(x2.domain())
          .on("brush",function(){brushmove();});
        var brushg = context.append("g")
          .attr("class", "brush")
          .call(brush);
        brushg.selectAll(".resize").append("path")
          .attr("transform", "translate(0," +  height2 / 2 + ")")
          .attr("d", arc);
        brushg.selectAll("rect")
          .attr("height", height2);
        var brushmove = function() {
          x.domain(brush.empty() ? x2.domain() : brush.extent());
          focus.selectAll(".dot").attr("cx",xMap).attr("cy",yMap);
          focus.select(".x.axis").call(xAxis);
          var ext = self._brushExtent = brush.extent();
          if (ext && ext.length === 2 && !isNaN(ext[0])) {
            ext = [ext[0],ext[1]];
            var isLast = (ext[1].getTime() === data[data.length-1].date.getTime());
            if (isLast) ext[1] = self.advanceToUpper(ext[1]);
            self._brushExtent = ext;
            var txt = self.formatDateRange(ext[0],ext[1],true);
            self.setNodeText(self.brushExtentNode,txt);
          } else {
            self._brushExtent = null;
            self.setNodeText(self.brushExtentNode,"");
          }
        };
        brushmove();
      }
    },

    /* SearchComponent API ============================================= */

    appendQueryParams: function(params) {
      var query = null, qFrom = null, qTo = null, qNested = null, condition = null;
      var lbl = this.label;
      this._aggInterval = this.interval; // TODO use params and searchResponse.params

      var from = null, to = null, dt;
      var dtFrom = this._fromDate, dtTo = this._toDate;
      var options = {zulu:true};
      var tip = this.formatDateRange(dtFrom,dtTo,false);
      if (dtFrom) from = stamp.toISOString(dtFrom,options);
      if (dtTo) to = stamp.toISOString(dtTo,options);

      if (from || to) {
        if (this.hasToField()) {
          if (from) {
            condition = {"gte":from};
            qFrom = {"range": {}};
            qFrom.range[this.field] = condition;
            query = qFrom;
          }
          if (to) {
            condition = {"lte":to};
            qTo = {"range": {}};
            qTo.range[this.toField] = condition;
            query = qTo;
          }
          if (from && to) {
            query = {"bool": {"must":[qFrom,qTo]}};
          }

          if (query && this.hasNestedPath()) {
            qNested = {"query":{"nested":{
              "path": this.nestedPath,
              "query": query
            }}};
            query = qNested;
          }
        } else {
          if (from && to) {
            condition = {"gte":from,"lte":to};
          } else if (from) {
            condition = {"gte":from};
          } else if (to) {
            condition = {"lte":to};
          }
          if (condition !== null) {
            query = {"range": {}};
            query.range[this.field] = condition;
            if (this.hasNestedPath()) {
              qNested = {"query":{"nested":{
                "path": this.nestedPath,
                "query": {"bool": {"must":[query]}}
              }}};
              query = qNested;
            }
          }
        }
      }

      if (!query) {
        this.activeQClauses = null;
      } else {
        var qClause = new QClause({
          label: lbl,
          tip: tip,
          parentQComponent: this,
          removable: true,
          query: query
        });
        this.activeQClauses = [qClause];
        this.appendQClauses(params);
      }

      var key = this.getAggregationKey();
      if (!params.aggregations) params.aggregations = {};
      var aggregationField = this.field;
      var interval = this.interval;
      var minDocCount = 1;
      var dateHistogram = {
        "date_histogram":{
          "field": aggregationField,
          "interval": interval,
          "min_doc_count": minDocCount
        }
      };
      var endDateHistogram = {
        "date_histogram":{
          "field": this.toField,
          "interval": interval,
          "min_doc_count": minDocCount
        }
      };
      if (this.hasNestedPath()) {
        params.aggregations[key] = {
          "nested" : {"path": this.nestedPath},
          "aggregations": {
            "dates": dateHistogram
          }
        };
        if (this.hasToField()) {
          params.aggregations[key].aggregations["endDates"] = endDateHistogram;
        }
      } else {
        params.aggregations[key] = dateHistogram;
        if (this.hasToField()) {
          params.aggregations[key+"_end"] = endDateHistogram;
        }
      }

    },

    processResults: function(searchResponse) {
      this._aggDates = this._aggEndDates = null;
      var key = this.getAggregationKey();
      if (searchResponse.aggregations) {
        var agg = searchResponse.aggregations[key];
        if (this.hasNestedPath()) {
          if (agg.dates) {
            this._aggDates = agg.dates;
          }
          if (agg.endDates) {
            this._aggEndDates = agg.endDates;
          }
        } else {
          this._aggDates = agg;
          if (this.hasToField()) {
            var agg2 = searchResponse.aggregations[key+"_end"];
            if (agg2) {
              this._aggEndDates = agg2;
            }
          }
        }
      }

      this.plot();
    },

    whenQClauseRemoved: function(qClause) {
      var self = this;
      if (this === qClause.parentQComponent) {
        this._searchDisabled = true;
        this._fromDate = this._toDate = this._brushExtent = null;
        this.setNodeText(this.brushExtentNode,"");
        setTimeout(function(){self._searchDisabled = false;},100);
      }
    }

  });

  return oThisClass;
});<commit_msg>Temporal filter.<commit_after>/* See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Esri Inc. licenses this file to You 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.
 */
define(["dojo/_base/declare",
        "dojo/_base/lang",
        "dojo/_base/array",
        "dojo/date",
        "dojo/date/stamp",
        "dojo/dom-construct",
        "dojo/dom-geometry",
        "dojo/text!./templates/TemporalFilter.html",
        "dojo/i18n!app/nls/resources",
        "app/search/SearchComponent",
        "app/search/DropPane",
        "app/search/QClause",
        "app/search/TemporalFilterSettings"],
function(declare, lang, array, djDate, stamp, domConstruct, domGeometry,
    template, i18n, SearchComponent, DropPane, QClause, TemporalFilterSettings) {

  var oThisClass = declare([SearchComponent], {

    i18n: i18n,
    templateString: template,

    allowSettings: null,
    field: null,
    toField: null,
    nestedPath: null,
    interval: "year", // year, quarter, month, week, day, hour, minute, second
    useUTC: true,

    label: i18n.search.temporalFilter.label,
    open: false,

    _aggDates: null,
    _aggEndDates: null,
    _aggInterval: null,
    _brushExtent: null,
    _searchDisabled: false,

    _fromDate: null,
    _toDate: null,

    _initialSettings: null,

    postCreate: function() {
      this.inherited(arguments);

      this._initialSettings = {
        label: this.label,
        field: this.field,
        toField: this.toField,
        nestedPath: this.nestedPath,
        interval: this.interval,
        useUTC: this.useUTC
      };

      $(this.intervalSelect).val(this.interval);
      this.plot();

      if (this.allowSettings === null) {
        if (AppContext.appConfig.search && !!AppContext.appConfig.search.allowSettings) {
          this.allowSettings = true;
        }
      }
      if (this.allowSettings) {
        var link = this.dropPane.addSettingsLink();
        link.onclick = lang.hitch(this,function(e) {
          var d = new TemporalFilterSettings({
            targetWidget: this
          });
          d.showDialog();
        });
      }
    },

    advanceToUpper: function(toDate) {
      if (!toDate) return null;
      if (!this.hasToField) return toDate;
      var dt = toDate;
      var interval = this._aggInterval;
      var intervals = ["year", "quarter", "month", "week", "day", "hour", "minute", "second"];
      if (intervals.indexOf(interval) !== -1) {
        dt = djDate.add(dt,interval,1);
        dt = djDate.add(dt,"millisecond",-1);
      }
      return dt;
    },

    applyBrushExtent: function() {
      var ext = this._brushExtent;
      if (ext && ext.length === 2) {
        this._fromDate = ext[0];
        this._toDate = ext[1];
        this.search();
      }
    },

    formatDate: function(date) {
      if (!date) return "";
      var options = {zulu:this.useUTC};
      return stamp.toISOString(date,options);
    },

    formatDateRange: function(fromDate,toDate,forSearchLink) {
      var v = "", rangePattern;
      if (fromDate || toDate) {
        rangePattern = i18n.search.temporalFilter.rangePattern;
        v = rangePattern.replace("{from}",this.formatDate(fromDate));
        v = v.replace("{to}",this.formatDate(toDate));
      }
      return v;
    },

    hasNestedPath: function() {
      return (typeof this.nestedPath === "string" && this.nestedPath.length > 0);
    },

    hasToField: function() {
      return (typeof this.toField === "string" && this.toField.length > 0);
    },

    intervalChanged: function() {
      this.interval = $(this.intervalSelect).val();
      this.search();
    },

    plot: function() {
      var self = this, svgNode = this.svgNode, hasTo = this.hasToField();
      domConstruct.empty(svgNode);
      this._brushExtent = null;
      this.setNodeText(this.brushExtentNode,"");

      var countPattern = i18n.search.temporalFilter.countPattern;
      var fmtTip = function(d) {
        var s1 = self.formatDate(d.date);
        var s2 = countPattern.replace("{count}",d.count);
        return s1+"
"+s2;
      };

      var data = [], dtLast = null;
      if (this._aggDates && this._aggDates.buckets) {
        array.forEach(this._aggDates.buckets,function(bucket){
          var dt = stamp.fromISOString(bucket.key_as_string);
          dtLast = dt;
          data.push({date:dt,count:bucket.doc_count});
        });
      }
      if (this._aggEndDates && this._aggEndDates.buckets) {
        array.forEach(this._aggEndDates.buckets,function(bucket){
          var dt = stamp.fromISOString(bucket.key_as_string);
          if (!dtLast || dt > dtLast) {
            data.push({date:dt,count:bucket.doc_count});
          }
        });
      }

      var w = 150; // 350
      var pos = domGeometry.position(this.dropPane.domNode);
      if (pos.w > 150) {
        w = (pos.w - 25);
      }
      var margin = {top: 10, right: 20, bottom: 80, left: 40};
      var width = w - margin.left - margin.right;
      var height = 70;
      var x = d3.time.scale().range([0, width]);
      var y = d3.scale.linear().range([height, 0]);
      var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(3);
      var yAxis = d3.svg.axis().scale(y).orient("left").ticks(3);
      var xMap = function(d) {return x(d.date);};
      var yMap = function(d) {return y(d.count);};
      x.domain(d3.extent(data.map(function(d){return d.date;})));
      y.domain([0, d3.max(data.map(function(d){return d.count;}))]);

      var margin2 = {top: margin.top+height+25, right: 20, bottom: 20, left: 40};
      var height2 = 35;
      var x2 = d3.time.scale().range([0, width]);
      var y2 = d3.scale.linear().range([height2, 0]);
      var xAxis2 = d3.svg.axis().scale(x2).orient("bottom").ticks(3);
      x2.domain(x.domain());
      y2.domain(y.domain());
      var area2 = d3.svg.area()
        .interpolate("monotone")
        .x(function(d){return x2(d.date);})
        .y0(height2)
        .y1(function(d){ return y2(d.count);});

      var svg = d3.select(svgNode).append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom);

      var tooltip = d3.select(svgNode).append("div")
        .attr("class", "tooltip")
        .style("opacity", 0);

      var focus = svg.append("g")
        .attr("class", "focus")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
      focus.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);
      focus.append("g")
        .attr("class", "y axis")
        .call(yAxis);
      /*
      var clipId = this.id+"_clip";
      var clipUrl = "url("+clipId+")";
      focus.append("defs").append("clipPath")
          .attr("id",clipId)
        .append("rect")
          .attr("width", width)
          .attr("height", height);
      focus.append("g").attr("clip-path",clipUrl);
      */
      focus.selectAll(".dot")
        .data(data)
      .enter().append("circle")
        .attr("class", "dot")
        .attr("r", 3.5)
        .attr("cx", function(d) {return x(d.date);})
        .attr("cy", function(d) {return y(d.count);})
        .on("mouseover", function(d) {
          tooltip.transition()
           .duration(200)
           .style("opacity", 1);
          tooltip.html(fmtTip(d))
           .style("left", (d3.event.pageX + 16) + "px")
           .style("top", (d3.event.pageY - 38) + "px");
        })
        .on("mouseout", function(d) {
          tooltip.transition()
           .duration(500)
           .style("opacity", 0);
        });

      var context = svg.append("g")
        .attr("class", "context")
        .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
      context.append("path")
        .datum(data)
        .attr("class", "area")
        .attr("d", area2);
      context.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height2 + ")")
        .call(xAxis2);
      if (data.length > 0) {
        var arc = d3.svg.arc()
        .outerRadius(height2 / 2)
        .startAngle(0)
        .endAngle(function(d, i) { return i ? -Math.PI : Math.PI; });
        var brush = d3.svg.brush()
          .x(x2)
          .extent(x2.domain())
          .on("brush",function(){brushmove();});
        var brushg = context.append("g")
          .attr("class", "brush")
          .call(brush);
        brushg.selectAll(".resize").append("path")
          .attr("transform", "translate(0," +  height2 / 2 + ")")
          .attr("d", arc);
        brushg.selectAll("rect")
          .attr("height", height2);
        var brushmove = function() {
          x.domain(brush.empty() ? x2.domain() : brush.extent());
          focus.selectAll(".dot").attr("cx",xMap).attr("cy",yMap);
          focus.select(".x.axis").call(xAxis);
          var ext = self._brushExtent = brush.extent();
          if (ext && ext.length === 2 && !isNaN(ext[0])) {
            ext = [ext[0],ext[1]];
            var isLast = (ext[1].getTime() === data[data.length-1].date.getTime());
            if (isLast) ext[1] = self.advanceToUpper(ext[1]);
            self._brushExtent = ext;
            var txt = self.formatDateRange(ext[0],ext[1],true);
            self.setNodeText(self.brushExtentNode,txt);
          } else {
            self._brushExtent = null;
            self.setNodeText(self.brushExtentNode,"");
          }
        };
        brushmove();
      }
    },

    /* SearchComponent API ============================================= */

    appendQueryParams: function(params) {
      var query = null, qFrom = null, qTo = null, qNested = null, condition = null;
      var lbl = this.label;
      this._aggInterval = this.interval; // TODO use params and searchResponse.params

      var from = null, to = null, dt;
      var dtFrom = this._fromDate, dtTo = this._toDate;
      var options = {zulu:true};
      var tip = this.formatDateRange(dtFrom,dtTo,false);
      if (dtFrom) from = stamp.toISOString(dtFrom,options);
      if (dtTo) to = stamp.toISOString(dtTo,options);

      if (from || to) {
        if (this.hasToField()) {
          if (from) {
            condition = {"gte":from};
            qFrom = {"range": {}};
            qFrom.range[this.field] = condition;
            query = qFrom;
          }
          if (to) {
            condition = {"lte":to};
            qTo = {"range": {}};
            qTo.range[this.toField] = condition;
            query = qTo;
          }
          if (from && to) {
            query = {"bool": {"must":[qFrom,qTo]}};
          }

          if (query && this.hasNestedPath()) {
            qNested = {"query":{"nested":{
              "path": this.nestedPath,
              "query": query
            }}};
            query = qNested;
          }
        } else {
          if (from && to) {
            condition = {"gte":from,"lte":to};
          } else if (from) {
            condition = {"gte":from};
          } else if (to) {
            condition = {"lte":to};
          }
          if (condition !== null) {
            query = {"range": {}};
            query.range[this.field] = condition;
            if (this.hasNestedPath()) {
              qNested = {"query":{"nested":{
                "path": this.nestedPath,
                "query": {"bool": {"must":[query]}}
              }}};
              query = qNested;
            }
          }
        }
      }

      if (!query) {
        this.activeQClauses = null;
      } else {
        var qClause = new QClause({
          label: lbl,
          tip: tip,
          parentQComponent: this,
          removable: true,
          query: query
        });
        this.activeQClauses = [qClause];
        this.appendQClauses(params);
      }

      var key = this.getAggregationKey();
      if (!params.aggregations) params.aggregations = {};
      var aggregationField = this.field;
      var interval = this.interval;
      var minDocCount = 1;
      var dateHistogram = {
        "date_histogram":{
          "field": aggregationField,
          "interval": interval,
          "min_doc_count": minDocCount
        }
      };
      var endDateHistogram = {
        "date_histogram":{
          "field": this.toField,
          "interval": interval,
          "min_doc_count": minDocCount
        }
      };
      if (this.hasNestedPath()) {
        params.aggregations[key] = {
          "nested" : {"path": this.nestedPath},
          "aggregations": {
            "dates": dateHistogram
          }
        };
        if (this.hasToField()) {
          params.aggregations[key].aggregations["endDates"] = endDateHistogram;
        }
      } else {
        params.aggregations[key] = dateHistogram;
        if (this.hasToField()) {
          params.aggregations[key+"_end"] = endDateHistogram;
        }
      }

    },

    processResults: function(searchResponse) {
      this._aggDates = this._aggEndDates = null;
      var key = this.getAggregationKey();
      if (searchResponse.aggregations) {
        var agg = searchResponse.aggregations[key];
        if (this.hasNestedPath()) {
          if (agg.dates) {
            this._aggDates = agg.dates;
          }
          if (agg.endDates) {
            this._aggEndDates = agg.endDates;
          }
        } else {
          this._aggDates = agg;
          if (this.hasToField()) {
            var agg2 = searchResponse.aggregations[key+"_end"];
            if (agg2) {
              this._aggEndDates = agg2;
            }
          }
        }
      }

      this.plot();
    },

    whenQClauseRemoved: function(qClause) {
      var self = this;
      if (this === qClause.parentQComponent) {
        this._searchDisabled = true;
        this._fromDate = this._toDate = this._brushExtent = null;
        this.setNodeText(this.brushExtentNode,"");
        setTimeout(function(){self._searchDisabled = false;},100);
      }
    }

  });

  return oThisClass;
});<|endoftext|>


<commit_before>"use strict";
/*global process require exports console */

// Copyright 2011 Chris Williams <chris@iterativedesigns.com>

var Buffer = require('buffer').Buffer;
var SerialPortBinding = require("bindings")("serialport.node");
var util = require('util');
var fs = require('fs');
var stream = require('stream');
var path = require('path');
var async = require('async');
var child_process = require('child_process');

var BAUDRATES = [500000, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200, 150, 134, 110, 75, 50];
var DATABITS = [8, 7, 6, 5];
var STOPBITS = [1, 2, 1.5];
var PARITY = ['none', 'even', 'mark', 'odd', 'space'];
var FLOWCONTROL = [false, true];

var parsers = {
  raw: function (emitter, buffer) {
    emitter.emit("data", buffer);
  },
  readline: function (delimiter) {
    if (typeof delimiter === "undefined" || delimiter === null) { delimiter = "\r"; }
    // Delimiter buffer saved in closure
    var data = "";
    return function (emitter, buffer) {
      // Collect data
      data += buffer.toString();
      // Split collected data by delimiter
      var parts = data.split(delimiter)
      data = parts.pop();
      parts.forEach(function (part, i, array) {
        emitter.emit('data', part);
      });
    };
  }
};

// The default options, can be overwritten in the 'SerialPort' constructor
var _options = {
  baudrate: 9600,
  databits: 8,
  stopbits: 1,
  parity: 'none',
  flowcontrol: false,
  buffersize: 255,
  parser: parsers.raw
};
function SerialPort (path, options) {
  options = options || {};
  options.__proto__ = _options;

  if (BAUDRATES.indexOf(options.baudrate) == -1) {
    throw new Error('Invalid "baudrate": ' + options.baudrate);
  }
  if (DATABITS.indexOf(options.databits) == -1) {
    throw new Error('Invalid "databits": ' + options.databits);
  }
  if (STOPBITS.indexOf(options.stopbits) == -1) {
    throw new Error('Invalid "stopbits": ' + options.stopbits);
  }
  if (PARITY.indexOf(options.parity) == -1) {
    throw new Error('Invalid "parity": ' + options.parity);
  }
  if (FLOWCONTROL.indexOf(options.flowcontrol) == -1) {
    throw new Error('Invalid "flowcontrol": ' + options.flowcontrol);
  }
  if (!path) {
    throw new Error('Invalid port specified: ' + path);
  }

  stream.Stream.call(this);

  var self = this;
  process.nextTick(function () {
    options = options || {};
    options.baudRate = options.baudRate || options.baudrate || 9600;
    options.dataBits = options.dataBits || options.databits || 8;
    options.parity = options.parity || 'none';
    options.stopBits = options.stopBits || options.stopbits || 1;
    options.bufferSize = options.bufferSize || options.buffersize || 100;
    if (!('flowControl' in options)) {
      options.flowControl = false;
    }
    options.dataCallback = function (data) {
      options.parser(self, data);
    };
    options.errorCallback = function (err) {
      self.emit('error', err);
    };
    options.disconnectedCallback = function () {
      if (self.closing) {
        return;
      }
      self.emit('error', new Error("Disconnected"));
      self.close();
    };

    if (process.platform == 'win32') {
      path = '\\\\.\\' + path;
    }

    SerialPortBinding.open(path, options, function (err, fd) {
      self.fd = fd;
      if (err) {
        return self.emit('error', err);
      }
      if (process.platform !== 'win32') {
        self.readStream = fs.createReadStream(path, { bufferSize: options.bufferSize, fd: fd });
        self.readStream.on("data", options.dataCallback);
        self.readStream.on("error", options.errorCallback);
        self.readStream.on("close", function () {
          self.close();
        });
        self.readStream.on("end", function () {
          self.emit('end');
        });
      }

      self.emit('open');
    });
  });
}

util.inherits(SerialPort, stream.Stream);

SerialPort.prototype.write = function (buffer, callback) {
  var self = this;
  if (!this.fd) {
    if (callback) {
      return callback(new Error("Serialport not open."));
    } else {
      return;
    }
  }

  if (!Buffer.isBuffer(buffer)) {
    buffer = new Buffer(buffer);
  }
  SerialPortBinding.write(this.fd, buffer, function (err, results) {
    if (err) {
      self.emit('error', err);
    }
    if (callback) {
      callback(err, results);
    }
  });
};

SerialPort.prototype.close = function (callback) {
  var self = this;

  var fd = this.fd;
  this.fd = 0;

  if (self.closing) {
    return;
  }
  if (!fd) {
    if (callback) {
      return callback(new Error("Serialport not open."));
    } else {
      return;
    }
  }

  self.closing = true;
  try {
    if (self.readStream) {
      self.readStream.destroy();
    }

    SerialPortBinding.close(fd, function (err) {
      if (err) {
        self.emit('error', err);
      }
      if (callback) {
        callback(err);
      }
      self.emit('close');
      self.closing = false;
    });
  } catch (ex) {
    self.closing = false;
    throw ex;
  }
};

function listUnix (callback) {
  fs.readdir("/dev/serial/by-id", function (err, files) {
    if (err) {
      // if this directory is not found this could just be because it's not plugged in
      if (err.errno === 34) {
        return callback(null, []);
      }
      return console.log(err);
    }
    var dirName = "/dev/serial/by-id";
    async.map(files, function (file, callback) {
      var fileName = path.join(dirName, file);
      fs.readlink(fileName, function (err, link) {
        if (err) {
          return callback(err);
        }
        link = path.resolve(dirName, link);
        callback(null, {
          comName: link,
          manufacturer: undefined,
          pnpId: file
        });
      }, callback);
    // Suspect code per ticket: #104 removed for deeper inspection.
    // fs.readdir("/dev/serial/by-path", function(err_path, paths) {
    //   if (err_path) {
    //     if (err.errno === 34) return callback(null, []);
    //     return console.log(err);
    //   }

    //   var dirName, items;
    //   //check if multiple devices of the same id are connected
    //   if (files.length !== paths.length) {
    //     dirName = "/dev/serial/by-path";
    //     items = paths;
    //   } else {
    //     dirName = "/dev/serial/by-id";
    //     items = files;
    //   }

    //   async.map(items, function (file, callback) {
    //     var fileName = path.join(dirName, file);
    //     fs.readlink(fileName, function (err, link) {
    //       if (err) {
    //         return callback(err);
    //       }
    //       link = path.resolve(dirName, link);
    //       callback(null, {
    //         comName: link,
    //         manufacturer: undefined,
    //         pnpId: file
    //       });
    //     });
    //   }, callback);
    });
  });
}

function listOSX (callback) {
  child_process.exec('/usr/sbin/system_profiler SPUSBDataType', function (err, stdout, stderr) {
    if (err) {
      return callback(err);
    }

    stderr = stderr.trim();
    if (stderr.length > 0) {
      return callback(new Error(stderr));
    }

    var lines = stdout.split('\n');

    var items = [];
    var currentItem = {};
    lines.forEach(function (line) {
      line = line.trim();
      line = line.replace(/\s+/, ' ');
      var m;

      if (m = line.match(/^Serial Number: (.+)$/)) {
        currentItem['serialNumber'] = m[1];
      } else if (m = line.match(/^Location ID: (.+)$/)) {
        currentItem['locationId'] = m[1];
      } else if (m = line.match(/^Product ID: (.+)$/)) {
        currentItem['productId'] = m[1];
      } else if (m = line.match(/^Vendor ID: (.+)$/)) {
        currentItem['vendorId'] = m[1];
      } else if (m = line.match(/^Manufacturer: (.+)$/)) {
        currentItem['manufacturer'] = m[1];
      } else if (/^$/.test(line)) {
        if ('serialNumber' in currentItem) {
          currentItem['comName'] = "/dev/cu.usbmodem" + currentItem['locationId'].substring(2, 6) + '1';
          items.push(currentItem);
          currentItem = {};
        }
      }
    });
    callback(null, items);
  });
}

exports.list = function (callback) {
  if (process.platform === 'win32') {
    SerialPortBinding.list(callback);
  } else if (process.platform === 'darwin') {
    listOSX(callback);
  } else {
    listUnix(callback);
  }
};

SerialPort.prototype.flush = function (callback) {
  var self = this;
  var fd = this.fd;

  if (!fd) {
    if (callback) {
      return callback(new Error("Serialport not open."));
    } else {
      return;
    }
  }

  SerialPortBinding.flush(fd, function (err, result) {
    if (err) {
      self.emit('error', err);
    }
    if (callback) {
      callback(err, result);
    }
  });
};

module.exports.SerialPort = SerialPort;
module.exports.parsers = parsers;
<commit_msg>optimize osx serialport.list<commit_after>"use strict";
/*global process require exports console */

// Copyright 2011 Chris Williams <chris@iterativedesigns.com>

var Buffer = require('buffer').Buffer;
var SerialPortBinding = require("bindings")("serialport.node");
var util = require('util');
var fs = require('fs');
var stream = require('stream');
var path = require('path');
var async = require('async');
var child_process = require('child_process');

var BAUDRATES = [500000, 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200, 150, 134, 110, 75, 50];
var DATABITS = [8, 7, 6, 5];
var STOPBITS = [1, 2, 1.5];
var PARITY = ['none', 'even', 'mark', 'odd', 'space'];
var FLOWCONTROL = [false, true];

var parsers = {
  raw: function (emitter, buffer) {
    emitter.emit("data", buffer);
  },
  readline: function (delimiter) {
    if (typeof delimiter === "undefined" || delimiter === null) { delimiter = "\r"; }
    // Delimiter buffer saved in closure
    var data = "";
    return function (emitter, buffer) {
      // Collect data
      data += buffer.toString();
      // Split collected data by delimiter
      var parts = data.split(delimiter)
      data = parts.pop();
      parts.forEach(function (part, i, array) {
        emitter.emit('data', part);
      });
    };
  }
};

// The default options, can be overwritten in the 'SerialPort' constructor
var _options = {
  baudrate: 9600,
  databits: 8,
  stopbits: 1,
  parity: 'none',
  flowcontrol: false,
  buffersize: 255,
  parser: parsers.raw
};
function SerialPort (path, options) {
  options = options || {};
  options.__proto__ = _options;

  if (BAUDRATES.indexOf(options.baudrate) == -1) {
    throw new Error('Invalid "baudrate": ' + options.baudrate);
  }
  if (DATABITS.indexOf(options.databits) == -1) {
    throw new Error('Invalid "databits": ' + options.databits);
  }
  if (STOPBITS.indexOf(options.stopbits) == -1) {
    throw new Error('Invalid "stopbits": ' + options.stopbits);
  }
  if (PARITY.indexOf(options.parity) == -1) {
    throw new Error('Invalid "parity": ' + options.parity);
  }
  if (FLOWCONTROL.indexOf(options.flowcontrol) == -1) {
    throw new Error('Invalid "flowcontrol": ' + options.flowcontrol);
  }
  if (!path) {
    throw new Error('Invalid port specified: ' + path);
  }

  stream.Stream.call(this);

  var self = this;
  process.nextTick(function () {
    options = options || {};
    options.baudRate = options.baudRate || options.baudrate || 9600;
    options.dataBits = options.dataBits || options.databits || 8;
    options.parity = options.parity || 'none';
    options.stopBits = options.stopBits || options.stopbits || 1;
    options.bufferSize = options.bufferSize || options.buffersize || 100;
    if (!('flowControl' in options)) {
      options.flowControl = false;
    }
    options.dataCallback = function (data) {
      options.parser(self, data);
    };
    options.errorCallback = function (err) {
      self.emit('error', err);
    };
    options.disconnectedCallback = function () {
      if (self.closing) {
        return;
      }
      self.emit('error', new Error("Disconnected"));
      self.close();
    };

    if (process.platform == 'win32') {
      path = '\\\\.\\' + path;
    }

    SerialPortBinding.open(path, options, function (err, fd) {
      self.fd = fd;
      if (err) {
        return self.emit('error', err);
      }
      if (process.platform !== 'win32') {
        self.readStream = fs.createReadStream(path, { bufferSize: options.bufferSize, fd: fd });
        self.readStream.on("data", options.dataCallback);
        self.readStream.on("error", options.errorCallback);
        self.readStream.on("close", function () {
          self.close();
        });
        self.readStream.on("end", function () {
          self.emit('end');
        });
      }

      self.emit('open');
    });
  });
}

util.inherits(SerialPort, stream.Stream);

SerialPort.prototype.write = function (buffer, callback) {
  var self = this;
  if (!this.fd) {
    if (callback) {
      return callback(new Error("Serialport not open."));
    } else {
      return;
    }
  }

  if (!Buffer.isBuffer(buffer)) {
    buffer = new Buffer(buffer);
  }
  SerialPortBinding.write(this.fd, buffer, function (err, results) {
    if (err) {
      self.emit('error', err);
    }
    if (callback) {
      callback(err, results);
    }
  });
};

SerialPort.prototype.close = function (callback) {
  var self = this;

  var fd = this.fd;
  this.fd = 0;

  if (self.closing) {
    return;
  }
  if (!fd) {
    if (callback) {
      return callback(new Error("Serialport not open."));
    } else {
      return;
    }
  }

  self.closing = true;
  try {
    if (self.readStream) {
      self.readStream.destroy();
    }

    SerialPortBinding.close(fd, function (err) {
      if (err) {
        self.emit('error', err);
      }
      if (callback) {
        callback(err);
      }
      self.emit('close');
      self.closing = false;
    });
  } catch (ex) {
    self.closing = false;
    throw ex;
  }
};

function listUnix (callback) {
  fs.readdir("/dev/serial/by-id", function (err, files) {
    if (err) {
      // if this directory is not found this could just be because it's not plugged in
      if (err.errno === 34) {
        return callback(null, []);
      }
      return console.log(err);
    }

    var dirName = "/dev/serial/by-id";
    async.map(files, function (file, callback) {
      var fileName = path.join(dirName, file);
      fs.readlink(fileName, function (err, link) {
        if (err) {
          return callback(err);
        }
        link = path.resolve(dirName, link);
        callback(null, {
          comName: link,
          manufacturer: undefined,
          pnpId: file
        });
      });
    }, callback);
  });
}

function listOSX (callback) {
  function getBSDDeviceName(deviceType, callback) {
    child_process.exec('/usr/sbin/system_profiler SPNetworkDataType', function (err, stdout, stderr) {
      if (err) {
        return callback(err);
      }

      stderr = stderr.trim();
      if (stderr.length > 0) {
        return callback(new Error(stderr));
      }

      var lines = stdout.split('\n');
      var name = null;
      var currentItem = {};
      for (var i = 0, len = lines.length; i < len; i ++) {
        var line = lines[i].trim();
        line = line.replace(/\s+/, ' ');
        var m;

        if (m = line.match(/^BSD Device Name: (.+)$/)) {
          var header = lines[i - 4];
          var re = new RegExp(deviceType + ':');
          if (re.test(header)) {
            name = m[1];
          }
        }
      }
      callback(null, name);
    });
  }

  child_process.exec('/usr/sbin/system_profiler SPUSBDataType', function (err, stdout, stderr) {
    if (err) {
      return callback(err);
    }

    stderr = stderr.trim();
    if (stderr.length > 0) {
      return callback(new Error(stderr));
    }

    var lines = stdout.split('\n');
    var items = [];
    var currentItem = {};
    for (var i = 0, len = lines.length; i < len; i ++) {
      var line = lines[i].trim();
      line = line.replace(/\s+/, ' ');
      var m;

      if (m = line.match(/^Product ID: (.+)$/)) {
        currentItem['productId'] = m[1];

        var header = lines[i - 2];
        if (/:/.test(header)) {
          header = header.trim();
          header = header.substring(0, header.length - 1);
          currentItem['deviceType'] = header;
        }
      } else if (m = line.match(/^Vendor ID: (.+)$/)) {
        currentItem['vendorId'] = m[1];
      } else if (m = line.match(/^Serial Number: (.+)$/)) {
        currentItem['serialNumber'] = m[1];
      } else if (m = line.match(/^Location ID: (.+)$/)) {
        currentItem['locationId'] = m[1];
      } else if (m = line.match(/^Manufacturer: (.+)$/)) {
        currentItem['manufacturer'] = m[1];
      } else if (/^$/.test(line)) {
        if ('serialNumber' in currentItem) {
          currentItem['comName'] = "/dev/cu.usbserial-" + currentItem['serialNumber'];
          items.push(currentItem);
          currentItem = {};
        } else if ('productId' in currentItem && 'vendorId' in currentItem) {
          items.push(currentItem);
          currentItem = {};
        }
      }
    }

    async.forEach(items, function(item, callback) {
      getBSDDeviceName(item.deviceType, function(err, name) {
        if (name) {
          item.comName = '/dev/cu.' + name;
        }
        callback(err);
      });
    }, function(err) {
      callback(null, items);
    });
  });
}

exports.list = function (callback) {
  if (process.platform === 'win32') {
    SerialPortBinding.list(callback);
  } else if (process.platform === 'darwin') {
    listOSX(callback);
  } else {
    listUnix(callback);
  }
};

SerialPort.prototype.flush = function (callback) {
  var self = this;
  var fd = this.fd;

  if (!fd) {
    if (callback) {
      return callback(new Error("Serialport not open."));
    } else {
      return;
    }
  }

  SerialPortBinding.flush(fd, function (err, result) {
    if (err) {
      self.emit('error', err);
    }
    if (callback) {
      callback(err, result);
    }
  });
};

module.exports.SerialPort = SerialPort;
module.exports.parsers = parsers;
<|endoftext|>


<commit_before>/*! ObjectKey 0.0.0 | Copyright (c) 2014 Gias Kay Lee | MIT License */

'use strict';

angular.module('ObjectKey', []).

constant('ObjectKey', new function() {
  var _deepTransform = function(style) {
    var stylize = function(object, config) {
      /*
      // config
      // | except
      */

      var config = config || {},
          o = {},
          isException;

      if (config.except instanceof RegExp) {
        isException = function(string) {
          return string.match(config.except);
        };
      } else {
        isException = function() {return false};
      }

      for (var k in object) {
        object.hasOwnProperty(k) &&
        !isException(k) && (
          o[style(k)] = 'object' === typeof object[k] ? stylize(object[k]) : object[k]
        );
      }

      return o;
    };

    return stylize;
  };

  this.toCamelCase = _deepTransform(function(string) {
    return string.replace(/[-_\s]+(.)?/g, function(match, $1) {return $1 ? $1.toUpperCase() : ''});
  });

  this.toSnakeCase = _deepTransform(function(string) {
    return string.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
  });

  this.toPoodleCase = _deepTransform(function(string) {
    return string.replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
  });
}());
<commit_msg>Replace repeated underscores with a single one in `toSnakeCase()`<commit_after>/*! ObjectKey 0.0.0 | Copyright (c) 2014 Gias Kay Lee | MIT License */

'use strict';

angular.module('ObjectKey', []).

constant('ObjectKey', new function() {
  var _deepTransform = function(style) {
    var stylize = function(object, config) {
      /*
      // config
      // | except
      */

      var config = config || {},
          o = {},
          isException;

      if (config.except instanceof RegExp) {
        isException = function(string) {
          return string.match(config.except);
        };
      } else {
        isException = function() {return false};
      }

      for (var k in object) {
        object.hasOwnProperty(k) &&
        !isException(k) && (
          o[style(k)] = 'object' === typeof object[k] ? stylize(object[k]) : object[k]
        );
      }

      return o;
    };

    return stylize;
  };

  this.toCamelCase = _deepTransform(function(string) {
    return string.replace(/[-_\s]+(.)?/g, function(match, $1) {return $1 ? $1.toUpperCase() : ''});
  });

  this.toSnakeCase = _deepTransform(function(string) {
    return string.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-_\s]+/g, '_').toLowerCase();
  });

  this.toPoodleCase = _deepTransform(function(string) {
    return string.replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
  });
}());
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');
const paths = require('./paths');

// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];

const NODE_ENV = process.env.NODE_ENV || 'development';

// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
var dotenvFiles = [
  `${paths.dotenv}.${NODE_ENV}.local`,
  `${paths.dotenv}.${NODE_ENV}`,
  // Don't include `.env.local` for `test` environment
  // since normally you expect tests to produce the same
  // results for everyone
  NODE_ENV !== 'test' && `${paths.dotenv}.local`,
  paths.dotenv
].filter(Boolean);

// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
dotenvFiles.forEach(dotenvFile => {
  if (fs.existsSync(dotenvFile)) {
    require('dotenv').config({
      path: dotenvFile
    });
  }
});

// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebookincubator/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
  .split(path.delimiter)
  .filter(folder => folder && !path.isAbsolute(folder))
  .map(folder => path.resolve(appDirectory, folder))
  .join(path.delimiter);

// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
const REACT_APP = /^REACT_APP_/i;

function getClientEnvironment(publicUrl) {
  const raw = Object.keys(process.env).filter(key => REACT_APP.test(key)).reduce((
    env,
    key
  ) => {
    env[key] = process.env[key];
    return env;
  }, {
    // Useful for determining whether we’re running in production mode.
    // Most importantly, it switches React into the correct mode.
    NODE_ENV: process.env.NODE_ENV || 'development',
    // Useful for resolving the correct path to static assets in `public`.
    // For example, .
    // This should only be used as an escape hatch. Normally you would put
    // images into the `src` and `import` them in code to get their paths.
    PUBLIC_URL: publicUrl
  });
  // Stringify all values so we can feed into Webpack DefinePlugin
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) => {
      env[key] = JSON.stringify(raw[key]);
      return env;
    }, {})
  };

  return {raw, stringified};
}

module.exports = getClientEnvironment;
<commit_msg>remove dupe NODE_ENV default<commit_after>'use strict';

const fs = require('fs');
const path = require('path');
const paths = require('./paths');

// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];

const NODE_ENV = process.env.NODE_ENV || 'development';

// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
var dotenvFiles = [
  `${paths.dotenv}.${NODE_ENV}.local`,
  `${paths.dotenv}.${NODE_ENV}`,
  // Don't include `.env.local` for `test` environment
  // since normally you expect tests to produce the same
  // results for everyone
  NODE_ENV !== 'test' && `${paths.dotenv}.local`,
  paths.dotenv
].filter(Boolean);

// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
dotenvFiles.forEach(dotenvFile => {
  if (fs.existsSync(dotenvFile)) {
    require('dotenv').config({
      path: dotenvFile
    });
  }
});

// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebookincubator/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
  .split(path.delimiter)
  .filter(folder => folder && !path.isAbsolute(folder))
  .map(folder => path.resolve(appDirectory, folder))
  .join(path.delimiter);

// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
const REACT_APP = /^REACT_APP_/i;

function getClientEnvironment(publicUrl) {
  const raw = Object.keys(process.env).filter(key => REACT_APP.test(key)).reduce((
    env,
    key
  ) => {
    env[key] = process.env[key];
    return env;
  }, {
    // Useful for determining whether we’re running in production mode.
    // Most importantly, it switches React into the correct mode.
    NODE_ENV: NODE_ENV,
    // Useful for resolving the correct path to static assets in `public`.
    // For example, .
    // This should only be used as an escape hatch. Normally you would put
    // images into the `src` and `import` them in code to get their paths.
    PUBLIC_URL: publicUrl
  });
  // Stringify all values so we can feed into Webpack DefinePlugin
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) => {
      env[key] = JSON.stringify(raw[key]);
      return env;
    }, {})
  };

  return {raw, stringified};
}

module.exports = getClientEnvironment;
<|endoftext|>


<commit_before>// This API proposal depends on:
//  DOM: http://www.w3.org/TR/domcore/
//  URLs: http://url.spec.whatwg.org/
//  Futures: https://github.com/slightlyoff/DOMFuture/
//  Shared Workers:
//    http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#shared-workers
//
// In an effort to provide an API that explains it, we liberally reference and
// steal from:
//    http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html
//
// See WebKit's Navigation Controllers to understand how it all works today:
//    http://code.google.com/searchframe#OAMlx_jo-ck/src/content/public/browser/navigation_controller.h
//    http://code.google.com/searchframe#OAMlx_jo-ck/src/content/public/browser/navigation_details.h
//    http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/loader/cache/CachedResource.h
//
// This API is described below in the style of ES6 classes. See:
//   http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes

// Roughly speaking, this is how it's gonna go down:
//
//    * Controllers are installed declaratively against a globbing URL match
//    * The execution context for controllers is effectively the SharedWorker
//      API, with a few additions:
//        http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#shared-workers
//    * All communication with the controller happens through events and Message
//      Ports: http://www.w3.org/TR/webmessaging/#messageport
//    * We define events for installation and upgrade of the controller,
//      resource loading, and navigation initiated by script or by user action,
//      e.g. clicking a link:
//        - The list of special messages (with payloads defined below) is:
//          "request"
//            All forms of resource loading loading including top-level
//            navigations. These are distinguished internally in the Event
//            object by a "type" field which can have values of:
//              "toplevel"
//                Synchrously Within toplevel request handlers, a window object
//                may be focus()'d, however this throws an error at any other
//                time.
//              "resource"
//                All sub-resource requests for a page are of this type.
//             Requets are modeled by the Request class (defined below).
//             Responses need not be provided synchronously.
//          "update"
//            A new controller receives this message upon installation. This can
//            be a *different version* of a controller or a brand new controller
//            installation.
//          "upgraded"
//            Sent to existing controller instances which are "alive" when a new
//            controller version is installed. The timing of this message is
//            defined to be: some time after the update hander of a new
//            version of the controller returns without error or exception.
//    * "toplevel" requests are *only* dispatched to a handler for URLs that
//      fall within the declared set of URLs "owned" by a controller. This is a
//      subset of "same-origin" and akin to the visibility of cookies.
//    * "resource" requrests are dispatched for *ALL* resources of a a
//      document claimed by a navigation controller, regardless of the domain of
//      the sub-resource. This is to say, a controller for foo.com/*, in
//      response to a "request" event dispatched from and instance of the
//      document foo.com/index.html for cdn.com/example.js, may override (and
//      block) the loading of that resource. As this behavior is per-resource-
//      load and does not affect default caching behavior in any way, there is
//      no risk of cache poisioning.
//    * Pages can open up channels to controllers via:
//        navigator.controller.ready.then();
//    * Controllers are the only bits of the system that have access to cache
//      groups
//    * In order to handle bringing an app into focus and navigating to some bit
//      of data (instead of opening a new window), Controllers also have access
//      to a list of top-level window objects whose URLs fall within the scope
//      of the URLs "owned" by the controller
//
//  DBK brings up some great points:
//    1.) UAs must ensure that they give controller scripts whatever level of
//    durability in their HTTP caches that they grant to existing AppCache
//    resources and manifests.
//    2.) If resources are evicted from the cache, we should notify (perhaps
//    with a special type of update event or message) the controller so that it
//    can handle the situation on next start. There's no mechanism in place for
//    that now.

////////////////////////////////////////////////////////////////////////////////
// Document APIs
////////////////////////////////////////////////////////////////////////////////

navigator.controller.register = function(/*URL|String*/ scope,
                                       /*URL|String*/ url) {
  // Install the controller specified at the URL.
  // This future is rejected if:
  //    - the URL is not same-origin
  //    - no scope is provided or the scope does not resolve/parse correctly
  //    - fetching the controller returns with an eror
  //    - installing the controller (the event the controller is sent) fails
  //      with an unhandled exception
  // TBD: possible error values upon rejection
  //
  // Else the future resolves successfully when controller.ready()'s Future
  // would

  return new Future();
};

navigator.controller.ready = function() {
  // Resolves successfully when a controller is found and initialized for the
  // document. If no controller is registered, the "update" event for it fails,
  // or the URL is cross-origin, we reject. If no controller is currently
  // running but one is registered, this method starts it.
  return new Future();
};

////////////////////////////////////////////////////////////////////////////////
// The Controller
////////////////////////////////////////////////////////////////////////////////

// The scope in which controller code is executed
class ControllerScope extends SharedWorker {
  constructor(url) {
    // Mirrors navigator.onLine. We also get network status change events
    // (ononline, etc.). The proposed ping() API must be made available here as
    // well.
    this.onLine = true;

    // New objects in the global scope
    this.caches = new CacheList();
    this.windows = new WindowList();

    // New events:
    this.onupdate = function(/*UpdateEvent*/ e) { };
    this.onupgraded = function(/*UpgradeEvent*/ e) { };
    this.onrequest = function(/*RequestEvent*/ e) { };

    // Execute user-provided code in this context via super
    super(url);

    if (upgrading) {
      this.dispatchEvent("update", ...);
    }

  }
}

////////////////////////////////////////////////////////////////////////////////
// Controller APIs
////////////////////////////////////////////////////////////////////////////////

class Request {
  // TODO
}

class Response {
  // TODO
}

class CachedResponse extends Response {
  // TODO
}

class RequestEvent extends Event {
  constructor() {
    super();
    // This is the meat of the API for most use-cases.
    // If preventDefault() is not called on the event, the request is sent to
    // the default browser controller. That is to say, to respond with something
    // from the cache, you must preventDefault() and respond with it manually,
    // digging the resource out of the cache and calling
    // evt.respondWith(cachedItem).
    //
    // Note:
    //    while preventDefault() must be called synchronously to cancel the
    //    default, responding does not need to be synchronous. That is to say,
    //    you can do something async (like fetch contents, go to IDB, whatever)
    //    within whatever the network time out is and as long as you still have
    //    the RequestEvent instance, you can fulfill the request later.
    this.request = new Request(); // filled in by browser, obviously
    this.type = "navigate"; // || "resource"
    this.window = null; // to allow postMessage, window.topLevel, etc
    this.respondWith = function(/*Response*/ r) { };
    this.redirectTo = function(urlOrString) { };
  }
}

// This largely describes the current Application Cache API. It's only available
// inside controller instances (not in regular documents), meaning that caching
// is a feature of the controller.
class Cache extends EventTarget {
  constructor(/*iterable*/ urls = []) {
    // Note that items may ONLY contain Response instasnces
    this.items = new Map();
    if (urls.length) {
      // Begin fetching on the URLs and storing them in this.items
    }
    // Events cribbed from existing AppCache
    this.onchecking = undefined;
    this.onerror = undefined;
    this.onnoupdate = undefined;
    this.ondownloading = undefined;
    this.onprogress = undefined;
    this.onupdateready = undefined;
    this.oncached = undefined;
    this.onobsolete = undefined;

  }

  match(urlOrString) {
    if (/*urlOrString matches something in items*/) {
      return this.items[urlOrString]
    }
  }

  // Cribbed from Mozilla's proposal, but with sane returns
  add(urlOrStringOrResponse) {
    // If a URL (or URL string) is passed, a new CachedResponse is added to
    // items upon successful fetching
    return new Future();
  }
  remove(urlOrStringOrResponse) {
    // FIXME: does this need to be async?
    return new Future();
  }

  // For the below, see current AppCache, although we extend with sane returns
  swapCache() { return new Future(); }
  update() { return new Future(); }
}

class CacheList extends Map {
  constructor(iterable) {
    super(iterable);
  }
  // Overrides to prevent non-URLs to be added go here.
}
<commit_msg>Typo fix<commit_after>// This API proposal depends on:
//  DOM: http://www.w3.org/TR/domcore/
//  URLs: http://url.spec.whatwg.org/
//  Futures: https://github.com/slightlyoff/DOMFuture/
//  Shared Workers:
//    http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#shared-workers
//
// In an effort to provide an API that explains it, we liberally reference and
// steal from:
//    http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html
//
// See WebKit's Navigation Controllers to understand how it all works today:
//    http://code.google.com/searchframe#OAMlx_jo-ck/src/content/public/browser/navigation_controller.h
//    http://code.google.com/searchframe#OAMlx_jo-ck/src/content/public/browser/navigation_details.h
//    http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/loader/cache/CachedResource.h
//
// This API is described below in the style of ES6 classes. See:
//   http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes

// Roughly speaking, this is how it's gonna go down:
//
//    * Controllers are installed declaratively against a globbing URL match
//    * The execution context for controllers is effectively the SharedWorker
//      API, with a few additions:
//        http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#shared-workers
//    * All communication with the controller happens through events and Message
//      Ports: http://www.w3.org/TR/webmessaging/#messageport
//    * We define events for installation and upgrade of the controller,
//      resource loading, and navigation initiated by script or by user action,
//      e.g. clicking a link:
//        - The list of special messages (with payloads defined below) is:
//          "request"
//            All forms of resource loading loading including top-level
//            navigations. These are distinguished internally in the Event
//            object by a "type" field which can have values of:
//              "toplevel"
//                Synchrously Within toplevel request handlers, a window object
//                may be focus()'d, however this throws an error at any other
//                time.
//              "resource"
//                All sub-resource requests for a page are of this type.
//             Requets are modeled by the Request class (defined below).
//             Responses need not be provided synchronously.
//          "update"
//            A new controller receives this message upon installation. This can
//            be a *different version* of a controller or a brand new controller
//            installation.
//          "upgraded"
//            Sent to existing controller instances which are "alive" when a new
//            controller version is installed. The timing of this message is
//            defined to be: some time after the update hander of a new
//            version of the controller returns without error or exception.
//    * "toplevel" requests are *only* dispatched to a handler for URLs that
//      fall within the declared set of URLs "owned" by a controller. This is a
//      subset of "same-origin" and akin to the visibility of cookies.
//    * "resource" requrests are dispatched for *ALL* resources of a
//      document claimed by a navigation controller, regardless of the domain of
//      the sub-resource. This is to say, a controller for foo.com/*, in
//      response to a "request" event dispatched from and instance of the
//      document foo.com/index.html for cdn.com/example.js, may override (and
//      block) the loading of that resource. As this behavior is per-resource-
//      load and does not affect default caching behavior in any way, there is
//      no risk of cache poisioning.
//    * Pages can open up channels to controllers via:
//        navigator.controller.ready.then();
//    * Controllers are the only bits of the system that have access to cache
//      groups
//    * In order to handle bringing an app into focus and navigating to some bit
//      of data (instead of opening a new window), Controllers also have access
//      to a list of top-level window objects whose URLs fall within the scope
//      of the URLs "owned" by the controller
//
//  DBK brings up some great points:
//    1.) UAs must ensure that they give controller scripts whatever level of
//    durability in their HTTP caches that they grant to existing AppCache
//    resources and manifests.
//    2.) If resources are evicted from the cache, we should notify (perhaps
//    with a special type of update event or message) the controller so that it
//    can handle the situation on next start. There's no mechanism in place for
//    that now.

////////////////////////////////////////////////////////////////////////////////
// Document APIs
////////////////////////////////////////////////////////////////////////////////

navigator.controller.register = function(/*URL|String*/ scope,
                                       /*URL|String*/ url) {
  // Install the controller specified at the URL.
  // This future is rejected if:
  //    - the URL is not same-origin
  //    - no scope is provided or the scope does not resolve/parse correctly
  //    - fetching the controller returns with an eror
  //    - installing the controller (the event the controller is sent) fails
  //      with an unhandled exception
  // TBD: possible error values upon rejection
  //
  // Else the future resolves successfully when controller.ready()'s Future
  // would

  return new Future();
};

navigator.controller.ready = function() {
  // Resolves successfully when a controller is found and initialized for the
  // document. If no controller is registered, the "update" event for it fails,
  // or the URL is cross-origin, we reject. If no controller is currently
  // running but one is registered, this method starts it.
  return new Future();
};

////////////////////////////////////////////////////////////////////////////////
// The Controller
////////////////////////////////////////////////////////////////////////////////

// The scope in which controller code is executed
class ControllerScope extends SharedWorker {
  constructor(url) {
    // Mirrors navigator.onLine. We also get network status change events
    // (ononline, etc.). The proposed ping() API must be made available here as
    // well.
    this.onLine = true;

    // New objects in the global scope
    this.caches = new CacheList();
    this.windows = new WindowList();

    // New events:
    this.onupdate = function(/*UpdateEvent*/ e) { };
    this.onupgraded = function(/*UpgradeEvent*/ e) { };
    this.onrequest = function(/*RequestEvent*/ e) { };

    // Execute user-provided code in this context via super
    super(url);

    if (upgrading) {
      this.dispatchEvent("update", ...);
    }

  }
}

////////////////////////////////////////////////////////////////////////////////
// Controller APIs
////////////////////////////////////////////////////////////////////////////////

class Request {
  // TODO
}

class Response {
  // TODO
}

class CachedResponse extends Response {
  // TODO
}

class RequestEvent extends Event {
  constructor() {
    super();
    // This is the meat of the API for most use-cases.
    // If preventDefault() is not called on the event, the request is sent to
    // the default browser controller. That is to say, to respond with something
    // from the cache, you must preventDefault() and respond with it manually,
    // digging the resource out of the cache and calling
    // evt.respondWith(cachedItem).
    //
    // Note:
    //    while preventDefault() must be called synchronously to cancel the
    //    default, responding does not need to be synchronous. That is to say,
    //    you can do something async (like fetch contents, go to IDB, whatever)
    //    within whatever the network time out is and as long as you still have
    //    the RequestEvent instance, you can fulfill the request later.
    this.request = new Request(); // filled in by browser, obviously
    this.type = "navigate"; // || "resource"
    this.window = null; // to allow postMessage, window.topLevel, etc
    this.respondWith = function(/*Response*/ r) { };
    this.redirectTo = function(urlOrString) { };
  }
}

// This largely describes the current Application Cache API. It's only available
// inside controller instances (not in regular documents), meaning that caching
// is a feature of the controller.
class Cache extends EventTarget {
  constructor(/*iterable*/ urls = []) {
    // Note that items may ONLY contain Response instasnces
    this.items = new Map();
    if (urls.length) {
      // Begin fetching on the URLs and storing them in this.items
    }
    // Events cribbed from existing AppCache
    this.onchecking = undefined;
    this.onerror = undefined;
    this.onnoupdate = undefined;
    this.ondownloading = undefined;
    this.onprogress = undefined;
    this.onupdateready = undefined;
    this.oncached = undefined;
    this.onobsolete = undefined;

  }

  match(urlOrString) {
    if (/*urlOrString matches something in items*/) {
      return this.items[urlOrString]
    }
  }

  // Cribbed from Mozilla's proposal, but with sane returns
  add(urlOrStringOrResponse) {
    // If a URL (or URL string) is passed, a new CachedResponse is added to
    // items upon successful fetching
    return new Future();
  }
  remove(urlOrStringOrResponse) {
    // FIXME: does this need to be async?
    return new Future();
  }

  // For the below, see current AppCache, although we extend with sane returns
  swapCache() { return new Future(); }
  update() { return new Future(); }
}

class CacheList extends Map {
  constructor(iterable) {
    super(iterable);
  }
  // Overrides to prevent non-URLs to be added go here.
}
<|endoftext|>


<commit_before>var fs = require("fs");
var _ = require("lodash");
var path = require("path");
var Provider = require("./provider");
var ConfigurationError = require('./errors/configurationerror');
var requireNoCache = require("./require-nocache");
var findUp = require("find-up");

var DEFAULT_CONFIG_FILENAME = "truffle.js";

function Config(truffle_directory, working_directory) {
  var self = this;

  this._values = {
    truffle_directory: truffle_directory || path.resolve(path.join(__dirname, "../")),
    working_directory: working_directory || process.cwd()
  };

  var props = {
    // First two already set.
    truffle_directory: function() {},
    working_directory: function() {},

    build_directory: function() {
      return path.join(self.working_directory, "build");
    },
    contracts_directory: function() {
      return path.join(self.working_directory, "contracts");
    },
    contracts_build_directory: function() {
      return path.join(self.build_directory, "contracts");
    },
    migrations_directory: function() {
      return path.join(self.working_directory, "migrations");
    },
    test_directory: function() {
      return path.join(self.working_directory, "test");
    },
    test_file_extension_regexp: function() {
      return /.*\.(js|es|es6|jsx)$/
    },
    network: function() {
      return "default"
    },
    networks: function() {
      return {
        "default": {},
        "test": {}
      }
    },
    example_project_directory: function() {
      return path.join(self.truffle_directory, "example");
    },
    templates: function() {
      return {
        test: {
          filename: path.join(self.truffle_directory, "templates", "example.js"),
          variable: "example"
        },
        contract: {
          filename: path.join(self.truffle_directory, "templates", "Example.sol"),
          name: "Example",
          variable: "example"
        }
      };
    },
    rpc: function() {
      return {
        host: "localhost",
        port: "8545",
        gas: 3141592,
        gasPrice: 100000000000, // 100 Shannon,
        from: null
      }
    }
  };

  Object.keys(props).forEach(function(prop) {
    self.addProp(prop, props[prop]);
  });
};

Config.prototype.addProp = function(key, default_getter) {
  Object.defineProperty(this, key, {
    get: function() {
      return this._values[key] || default_getter();
    },
    set: function(val) {
      this._values[key] = val;
    },
    configurable: true,
    enumerable: true
  });
};

Config.prototype.getProvider = function(network_id) {
  if (network_id == null) {
    network_id = "default";
  }

  if (this.networks[network_id] == null) {
    throw new ConfigurationError("Cannot find network '" + network_id + "'");
  }

  return Provider.create(_.merge({}, this.rpc, this.networks[network_id]));
};

// Helper function for expecting paths to exist.
Config.expect = function(expected_path, description, extra, callback) {
  if (typeof description == "function") {
    callback = description;
    description = "file";
    extra = "";
  }

  if (typeof extra == "function") {
    callback = extra;
    extra = "";
  }

  if (description == null) {
    description = "file";
  }

  if (extra == null) {
    extra = "";
  }

  if (!fs.existsSync(expected_path)) {
    var display_path = expected_path.replace(this.working_dir, "./");
    var error = new ConfigurationError("Couldn't find " + description + " at " + display_path + ". " + extra);

    if (callback != null) {
      callback(error);
      return false;
    } else {
      throw error;
    }
  }
  return true;
}

Config.default = function() {
  return new Config();
};

Config.detect = function(filename) {
  if (filename == null) {
    filename = DEFAULT_CONFIG_FILENAME;
  }

  var file = findUp.sync(filename);

  if (file == null) {
    throw new ConfigurationError("Could not find suitable configuration file.");
  }

  return this.load(file);
};

Config.load = function(file) {
  var config = new Config();

  config.working_directory = path.dirname(path.resolve(file));

  var static_config = requireNoCache(file);

  return _.merge(config, static_config);
};

module.exports = Config;
<commit_msg>Continue work on managing networks through the config. Currently unfinished.<commit_after>var fs = require("fs");
var _ = require("lodash");
var path = require("path");
var Provider = require("./provider");
var ConfigurationError = require('./errors/configurationerror');
var requireNoCache = require("./require-nocache");
var findUp = require("find-up");

var DEFAULT_CONFIG_FILENAME = "truffle.js";

function Config(truffle_directory, working_directory, network) {
  var self = this;

  this._values = {
    truffle_directory: truffle_directory || path.resolve(path.join(__dirname, "../")),
    working_directory: working_directory || process.cwd(),
    network: network || "default"
  };

  var props = {
    // First three already set.
    truffle_directory: function() {},
    working_directory: function() {},
    network: function() {},

    build_directory: function() {
      return path.join(self.working_directory, "build");
    },
    contracts_directory: function() {
      return path.join(self.working_directory, "contracts");
    },
    contracts_build_directory: function() {
      return path.join(self.build_directory, "contracts");
    },
    migrations_directory: function() {
      return path.join(self.working_directory, "migrations");
    },
    test_directory: function() {
      return path.join(self.working_directory, "test");
    },
    test_file_extension_regexp: function() {
      return /.*\.(js|es|es6|jsx)$/
    },
    networks: function() {
      return {
        "default": {},
        "test": {}
      }
    },
    example_project_directory: function() {
      return path.join(self.truffle_directory, "example");
    },
    templates: function() {
      return {
        test: {
          filename: path.join(self.truffle_directory, "templates", "example.js"),
          variable: "example"
        },
        contract: {
          filename: path.join(self.truffle_directory, "templates", "Example.sol"),
          name: "Example",
          variable: "example"
        }
      };
    },
    rpc: function() {
      return {
        host: "localhost",
        port: "8545",
        gas: 4712388,
        gasPrice: 100000000000, // 100 Shannon,
        from: null
      }
    }
  };

  Object.keys(props).forEach(function(prop) {
    self.addProp(prop, props[prop]);
  });
};

Config.prototype.addProp = function(key, default_getter) {
  Object.defineProperty(this, key, {
    get: function() {
      return this._values[key] || default_getter();
    },
    set: function(val) {
      this._values[key] = val;
    },
    configurable: true,
    enumerable: true
  });
};

Config.prototype.getProvider = function(options) {
  options = options || {};

  var network_id = options.network_id || this.network;

  if (this.networks[network_id] == null) {
    throw new ConfigurationError("Cannot find network '" + network_id + "'");
  }

  return Provider.create(_.merge(options, this.rpc, this.networks[network_id]));
};

// Helper function for expecting paths to exist.
Config.expect = function(expected_path, description, extra, callback) {
  if (typeof description == "function") {
    callback = description;
    description = "file";
    extra = "";
  }

  if (typeof extra == "function") {
    callback = extra;
    extra = "";
  }

  if (description == null) {
    description = "file";
  }

  if (extra == null) {
    extra = "";
  }

  if (!fs.existsSync(expected_path)) {
    var display_path = expected_path.replace(this.working_dir, "./");
    var error = new ConfigurationError("Couldn't find " + description + " at " + display_path + ". " + extra);

    if (callback != null) {
      callback(error);
      return false;
    } else {
      throw error;
    }
  }
  return true;
}

Config.default = function() {
  return new Config();
};

Config.detect = function(network, filename) {
  if (filename == null) {
    filename = DEFAULT_CONFIG_FILENAME;
  }

  var file = findUp.sync(filename);

  if (file == null) {
    throw new ConfigurationError("Could not find suitable configuration file.");
  }

  return this.load(file, network);
};

Config.load = function(file, network) {
  var config = new Config();

  config.working_directory = path.dirname(path.resolve(file));

  var static_config = requireNoCache(file);

  config = _.merge(config, static_config);

  if (network) {
    config.network = network;
  }

  return config;
};

module.exports = Config;
<|endoftext|>


<commit_before>const Discord = require("discord.js");
const settings = require('./setting.json');
const SimplerDiscord = require("Simpler-Discord");
//const SimplerDiscord = require("../SimplerDiscord/index");

const client = new Discord.Client();

var DeleteQueue = new SimplerDiscord.DeleteQueue();
var Commands = new SimplerDiscord.CommandHandler("d!", { color: undefined, notfound: true }, 5000);
var Messages = new SimplerDiscord.MessageHandler();

var PingCommand = new SimplerDiscord.Command("ping", null, "Ping the bot", Ping);
var EchoCommand = new SimplerDiscord.Command("echo", true, "Echo the string", Echo);

Commands.regester(PingCommand, "Utility Commands");
Commands.regester(EchoCommand, "Fun Commands");

Messages.add("poop", function (msg) { msg.channel.send("POOP!"); });
Messages.add("did you know you can become a discord partner", function (msg) { msg.channel.send("DIE, PLEASE!"); }, true);
Messages.add("AAAAAAAA", function (msg) { msg.channel.send("AAAAAAAAAAAAAAAAAAAAAAAAAAAA"); }, 2);

function Ping(message, args, handler) {
    var responses = new SimplerDiscord.RandomMessage(["POOP", "POP", "NOP", "DAB", SimplerDiscord.getEmoji("god", message.guild)]);
    message.channel.send(responses.chooose())
        .then(x => DeleteQueue.add(x, 10000));
    return true;
}

function Echo(message, args, handler) {
    message.channel.send(args + " " + SimplerDiscord.getEmoji("god", message.guild));
}

client.on('ready', () => {
    console.log(`Logged in as ${client.user.username}!`);

});

client.on('message', msg => {
    Commands.handle(msg);
    Messages.handle(msg);
});

client.login(settings.token);

var loggerHandler = new SimplerDiscord.LoggerCommandHandler(client);

var logger = new SimplerDiscord.BetterLogger(loggerHandler);

logger.start();

console.log("LOG");
console.info("INFO");
console.warn("WARN");
console.error("ERROR");<commit_msg>Update app.js<commit_after>const Discord = require("discord.js");
const settings = require('./setting.json');
const SimplerDiscord = require("Simpler-Discord");
//const SimplerDiscord = require("../SimplerDiscord/index");

const client = new Discord.Client();

var DeleteQueue = new SimplerDiscord.DeleteQueue();
var Commands = new SimplerDiscord.CommandHandler("d!", { color: undefined, notfound: true }, 5000);
var Messages = new SimplerDiscord.MessageHandler();

var PingCommand = new SimplerDiscord.Command("ping", null, "Ping the bot", Ping);
var EchoCommand = new SimplerDiscord.Command("echo", true, "Echo the string", Echo);

Commands.register(PingCommand, "Utility Commands");
Commands.register(EchoCommand, "Fun Commands");

Messages.add("poop", function (msg) { msg.channel.send("POOP!"); });
Messages.add("did you know you can become a discord partner", function (msg) { msg.channel.send("DIE, PLEASE!"); }, true);
Messages.add("AAAAAAAA", function (msg) { msg.channel.send("AAAAAAAAAAAAAAAAAAAAAAAAAAAA"); }, 2);

function Ping(message, args, handler) {
    var responses = new SimplerDiscord.RandomMessage(["POOP", "POP", "NOP", "DAB", SimplerDiscord.getEmoji("god", message.guild)]);
    message.channel.send(responses.chooose())
        .then(x => DeleteQueue.add(x, 10000));
    return true;
}

function Echo(message, args, handler) {
    message.channel.send(args + " " + SimplerDiscord.getEmoji("god", message.guild));
}

client.on('ready', () => {
    console.log(`Logged in as ${client.user.username}!`);

});

client.on('message', msg => {
    Commands.handle(msg);
    Messages.handle(msg);
});

client.login(settings.token);

var loggerHandler = new SimplerDiscord.LoggerCommandHandler(client);

var logger = new SimplerDiscord.BetterLogger(loggerHandler);

logger.start();

console.log("LOG");
console.info("INFO");
console.warn("WARN");
console.error("ERROR");
<|endoftext|>