<commit_before>/*global $,app*/

app.views.results = function (parsedQuery) {
  console.debug('*results*', parsedQuery)

  // Breadcrumbs
  app.hooks.resultsCrumb.find('b').text(parsedQuery.label);
  app.hooks.crumbs.update(app.hooks.resultsCrumb);

  // Search
  app.hooks.searchRight.html(' ');
  app.hooks.searchLeft.removeClass('medium-14').addClass('medium-4').html(' ');
  app.hooks.searchBox.removeClass('medium-10 float-right').addClass('medium-16');

  // Empty both content areas
  app.hooks.content.children().detach();
  app.hooks.belowContent.children().detach();
  app.hooks.aboveContent.children().detach();

  var endpointMap = {
    'address': 'addresses',
    'account': 'account',
    'block': 'block',
    'owner': 'owner',
  };

  var queryType = parsedQuery.type,
      endpoint = endpointMap[queryType] + '/',
      isOwnerSearch = false,
      queryParam;

  switch(queryType) {
    case 'account':
      queryParam = parsedQuery.account;
      break;
    case 'block':
      queryParam = parsedQuery.address;
      break;
    case 'address':
      queryParam = parsedQuery.address;

      if (parsedQuery.unit) {
        queryParam += ' UNIT ' + parsedQuery.unit;
      }
      break;
    case 'owner':
      isOwnerSearch = true;
      queryParam = parsedQuery.owner;
      break;
  }

  endpoint += encodeURI(queryParam);

  app.hooks.content.empty(); // Remove loading message
  app.hooks.ownerSearchDisclaimer.addClass('hide');

  var state = history.state;

  if (app.globals.historyState && state && state.ais) {
    didGetAisData(history.state.ais);
  } else {
    app.hooks.content.append(app.hooks.loading);
    getAisData();
  }

  function getAisData () {
    var params = {
      // gatekeeperKey: app.config['gatekeeperKey'],
      include_units: null,
      opa_only: null,
    };

    $.ajax({
      url: 'https://api.phila.gov/ais_ps/v1/' + endpoint,
      data: params,
      success: didGetAisData,
      error: didGetAisError,
    });
  }

  function didGetAisData (aisData) {
    var property, accountNumber, href, withUnit;

    if (!app.globals.historyState) history.state = {};

    // If we didn't get a good result from AIS (or rehydrate a feature from
    // history), show the error message.
    if (!aisData || (!aisData.features && !aisData.properties)) {
      console.debug('no ais features', aisData);
      var error = app.config.defaultError;
      history.replaceState({error: error}, '');
      render();
      return;
    }

    // For business reasons, owner searches need to always show on the
    // results page for the disclaimer.
    if (!isOwnerSearch && (
      aisData.type == 'Feature' ||
      aisData.features.length === 1)) {
        // If only one property go straight to property view
        feature = (aisData.features ? aisData.features[0] : aisData);
        attrs = feature.properties;
        accountNumber = attrs.opa_account_num;
        href = '?' + $.param({p: accountNumber});
        withUnit = feature.properties.street_address;

        history.replaceState({
          ais: feature,
          address: withUnit,
        }, withUnit, href);

        app.views.property(accountNumber);
    } else {
      // Fetch market_value, sale data from OPA dataset
      var opaUrl = constructOpaUrl(aisData.features);
      $.ajax(opaUrl)
        .done(function (opaData) {
          var keyedOpaData = keyBy(opaData.rows, 'parcel_number')
          $.each(aisData.features, function (index, feature) {
            $.extend(feature.properties, keyedOpaData[feature.properties.opa_account_num] || {})
          })

          var newState = $.extend({}, history.state);
          // Used for rendering a special owner search disclaimer
          if (isOwnerSearch) {
            aisData = $.extend({isOwnerSearch: true}, aisData);
          }
          newState = aisData

          if (!app.globals.historyState) {
            history.state = newState;
          } else {
            history.replaceState(newState, ''); // Second param not optional in IE10
          }
          render();
        });
    }
  }

  function didGetAisError(jqXHR, textStatus, errorThrown) {
    var status = jqXHR.responseJSON.status,
        message;

    console.debug('did get ais error', status);

    switch(status) {
      case 404:
        message = "We couldn't find any " + queryType +
                  " results for " + queryParam +
                  ". Please review your search and try again.";
        break;
      default:
        message = app.config.defaultError;
        break;
    }

    history.replaceState({error: message}, '');
    render();
  }

  function constructOpaUrl (features) {
    var accountNumbers = $.map(features, function (feature) {
      return feature.properties.opa_account_num
    })

    var params = {
      select: [
        'parcel_number',
        'market_value',
        'sale_date',
        'sale_price'
      ].join(','),
      where: 'parcel_number in ("' + accountNumbers.join('","') + '")'
    };
    var query = 'SELECT parcel_number, market_value, sale_date, sale_price FROM '
      + app.config.carto.datasets.properties + " WHERE parcel_number IN ('"
      + accountNumbers.join("','") + "')"
    return app.config.carto.baseUrl + '?q=' + encodeURIComponent(query)
  }

  function keyBy (items, key) {
    var hash = {}
    for (var i = 0; i < items.length; i++) {
      hash[items[i][key]] = items[i]
    }
    return hash
  }

  function render () {
    var state = history.state;
    if (state.error) return app.hooks.content.html(state.error);
    var features = state.features;
    var total_size = state.total_size;
    var isOwnerSearch = state.isOwnerSearch;

    app.hooks.content.empty(); // Remove loading message

    if (total_size === 0) {
      return app.hooks.content.append(app.hooks.noResults);
    }

    if (isOwnerSearch) {
      renderOwnerSearchDisclaimer();
    }

    // TODO find a place for count
    //app.hooks.count.find('#total').text(state.total);
    //app.hooks.content.append(app.hooks.count);
    app.hooks.resultRows.empty(); // TODO reuse existing result nodes
    if (features) {
      $.each(features, addRow);

      if (total_size > features.length) {
        var seeMoreA = app.hooks.seeMore.find('a');
        seeMoreA.off('click'); // Drop previously created click events
        seeMoreA.on('click', function (e) {

          var params = {
            // gatekeeperKey: app.config['gatekeeperKey'],
            include_units: null,
            opa_only: null,
            page: state.page + 1
          };

          $.ajax({
            url: 'https://api.phila.gov/ais_ps/v1/' + endpoint,
            data: params
          })
            .done(function (aisData) {
              // Fetch market_value, sale data from OPA dataset
              var opaUrl = constructOpaUrl(aisData.features);
              $.ajax(opaUrl)
                .done(function (opaData) {
                  var keyedOpaData = keyBy(opaData, 'parcel_number')
                  $.each(aisData.features, function (index, feature) {
                    $.extend(feature.properties, keyedOpaData[feature.properties.opa_account_num] || {})
                  })

                  state.features = state.features.concat(aisData.features);
                  state.page = aisData.page;
                  history.replaceState(state, ''); // Second param not optional in IE10

                  $.each(aisData.features, addRow);
                  if (state.total_size === state.features.length) app.hooks.seeMore.hide();

                  // Remove old Tablesaw data and refresh
                  $('[data-hook="results-table"]').table().data("table").destroy();
                  $('[data-hook="results-table"]').table().data("table").refresh();
                });
            });
        });
        app.hooks.seeMore.show();
      } else {
        app.hooks.seeMore.hide();
      }
      app.hooks.content.append(app.hooks.results);

      // Update the Tablesaw responsive tables
      $(document).trigger('enhance.tablesaw');
    }
  }

  function renderOwnerSearchDisclaimer() {
    var now = new Date(),
        mins = now.getMinutes(),
        prettyMins = mins < 10 ? ('0' + mins) : mins,
        prettyNow = (now.getMonth() + 1) + '/' + now.getDate() + '/' +  now.getFullYear() +
                    ' ' + now.getHours() + ':' + prettyMins;

    app.hooks.ownerSearchDisclaimer.removeClass('hide');
    app.hooks.ownerSearchDisclaimerDatetime.text(prettyNow);
    app.hooks.ownerSearchDisclaimerQuery.text(parsedQuery.label);

    // Fetch IP & show it
    $.getJSON('https://api.ipify.org?format=json')
      .done(function(response) {
        if(response.ip) {
          app.hooks.ownerSearchDisclaimerIp.text(response.ip);
        }
      })
      .fail(function() {
        app.hooks.ownerSearchDisclaimerIp.text(app.hooks.ownerSearchDisclaimerIp.attr('data-default'));
      });
  }

  function addRow (index, property) {
    var row = app.hooks.resultRow.clone(),
        attrs = property.properties,
        accountNumber = attrs.opa_account_num,
        withUnit = attrs.street_address,
        href = '?' + $.param({p: accountNumber});

    row.append($('').append($('').text(withUnit)));
    row.append($('').text(accounting.formatMoney(attrs.market_value)));
    row.append($('').text(moment(attrs.sale_date).format('M/D/YYYY') + ', ' + accounting.formatMoney(attrs.sale_price)));
    row.append($('').text(attrs.opa_owners && attrs.opa_owners.join(', ')));
    row.append($('').html(''));

    row.on('click', function (e) {
        if (e.ctrlKey || e.altKey || e.shiftKey) return;
        e.preventDefault();
        history.pushState({ais: property, address: withUnit}, withUnit, href);
        window.scroll(0, 0);
        app.views.property(accountNumber);
      });
    app.hooks.resultRows.append(row);
  }
};
<commit_msg>Update style for consistency<commit_after>/*global $,app*/

app.views.results = function (parsedQuery) {
  console.debug('*results*', parsedQuery)

  // Breadcrumbs
  app.hooks.resultsCrumb.find('b').text(parsedQuery.label);
  app.hooks.crumbs.update(app.hooks.resultsCrumb);

  // Search
  app.hooks.searchRight.html(' ');
  app.hooks.searchLeft.removeClass('medium-14').addClass('medium-4').html(' ');
  app.hooks.searchBox.removeClass('medium-10 float-right').addClass('medium-16');

  // Empty both content areas
  app.hooks.content.children().detach();
  app.hooks.belowContent.children().detach();
  app.hooks.aboveContent.children().detach();

  var endpointMap = {
    address: 'addresses',
    account: 'account',
    block: 'block',
    owner: 'owner',
  };

  var queryType = parsedQuery.type,
      endpoint = endpointMap[queryType] + '/',
      isOwnerSearch = false,
      queryParam;

  switch(queryType) {
    case 'account':
      queryParam = parsedQuery.account;
      break;
    case 'block':
      queryParam = parsedQuery.address;
      break;
    case 'address':
      queryParam = parsedQuery.address;

      if (parsedQuery.unit) {
        queryParam += ' UNIT ' + parsedQuery.unit;
      }
      break;
    case 'owner':
      isOwnerSearch = true;
      queryParam = parsedQuery.owner;
      break;
  }

  endpoint += encodeURI(queryParam);

  app.hooks.content.empty(); // Remove loading message
  app.hooks.ownerSearchDisclaimer.addClass('hide');

  var state = history.state;

  if (app.globals.historyState && state && state.ais) {
    didGetAisData(history.state.ais);
  } else {
    app.hooks.content.append(app.hooks.loading);
    getAisData();
  }

  function getAisData() {
    var params = {
      // gatekeeperKey: app.config['gatekeeperKey'],
      include_units: null,
      opa_only: null,
    };

    $.ajax({
      url: 'https://api.phila.gov/ais_ps/v1/' + endpoint,
      data: params,
      success: didGetAisData,
      error: didGetAisError,
    });
  }

  function didGetAisData(aisData) {
    var property, accountNumber, href, withUnit;

    if (!app.globals.historyState) history.state = {};

    // If we didn't get a good result from AIS (or rehydrate a feature from
    // history), show the error message.
    if (!aisData || (!aisData.features && !aisData.properties)) {
      console.debug('no ais features', aisData);
      var error = app.config.defaultError;
      history.replaceState({error: error}, '');
      render();
      return;
    }

    // For business reasons, owner searches need to always show on the
    // results page for the disclaimer.
    if (!isOwnerSearch && (
      aisData.type == 'Feature' ||
      aisData.features.length === 1)) {
        // If only one property go straight to property view
        feature = (aisData.features ? aisData.features[0] : aisData);
        attrs = feature.properties;
        accountNumber = attrs.opa_account_num;
        href = '?' + $.param({p: accountNumber});
        withUnit = feature.properties.street_address;

        history.replaceState({
          ais: feature,
          address: withUnit,
        }, withUnit, href);

        app.views.property(accountNumber);
    } else {
      // Fetch market_value, sale data from OPA dataset
      var opaUrl = constructOpaUrl(aisData.features);
      $.ajax(opaUrl)
        .done(function (opaData) {
          var keyedOpaData = keyBy(opaData.rows, 'parcel_number')
          $.each(aisData.features, function (index, feature) {
            $.extend(feature.properties, keyedOpaData[feature.properties.opa_account_num] || {})
          })

          var newState = $.extend({}, history.state);
          // Used for rendering a special owner search disclaimer
          if (isOwnerSearch) {
            aisData = $.extend({isOwnerSearch: true}, aisData);
          }
          newState = aisData

          if (!app.globals.historyState) {
            history.state = newState;
          } else {
            history.replaceState(newState, ''); // Second param not optional in IE10
          }
          render();
        });
    }
  }

  function didGetAisError(jqXHR, textStatus, errorThrown) {
    var status = jqXHR.responseJSON.status,
        message;

    console.debug('did get ais error', status);

    switch(status) {
      case 404:
        message = "We couldn't find any " + queryType +
                  " results for " + queryParam +
                  ". Please review your search and try again.";
        break;
      default:
        message = app.config.defaultError;
        break;
    }

    history.replaceState({error: message}, '');
    render();
  }

  function constructOpaUrl(features) {
    var accountNumbers = $.map(features, function (feature) {
      return feature.properties.opa_account_num
    })

    var params = {
      select: [
        'parcel_number',
        'market_value',
        'sale_date',
        'sale_price'
      ].join(','),
      where: 'parcel_number in ("' + accountNumbers.join('","') + '")'
    };
    var query = 'SELECT parcel_number, market_value, sale_date, sale_price FROM '
      + app.config.carto.datasets.properties + " WHERE parcel_number IN ('"
      + accountNumbers.join("','") + "')"
    return app.config.carto.baseUrl + '?q=' + encodeURIComponent(query)
  }

  function keyBy(items, key) {
    var hash = {}
    for (var i = 0; i < items.length; i++) {
      hash[items[i][key]] = items[i]
    }
    return hash
  }

  function render() {
    var state = history.state;
    if (state.error) return app.hooks.content.html(state.error);
    var features = state.features;
    var totalSize = state.total_size;
    var isOwnerSearch = state.isOwnerSearch;

    app.hooks.content.empty(); // Remove loading message

    if (totalSize === 0) {
      return app.hooks.content.append(app.hooks.noResults);
    }

    if (isOwnerSearch) {
      renderOwnerSearchDisclaimer();
    }

    // TODO find a place for count
    //app.hooks.count.find('#total').text(state.total);
    //app.hooks.content.append(app.hooks.count);
    app.hooks.resultRows.empty(); // TODO reuse existing result nodes
    if (features) {
      $.each(features, addRow);

      if (totalSize > features.length) {
        var seeMoreA = app.hooks.seeMore.find('a');
        seeMoreA.off('click'); // Drop previously created click events
        seeMoreA.on('click', function (e) {

          var params = {
            // gatekeeperKey: app.config['gatekeeperKey'],
            include_units: null,
            opa_only: null,
            page: state.page + 1
          };

          $.ajax({
            url: 'https://api.phila.gov/ais_ps/v1/' + endpoint,
            data: params
          })
            .done(function (aisData) {
              // Fetch market_value, sale data from OPA dataset
              var opaUrl = constructOpaUrl(aisData.features);
              $.ajax(opaUrl)
                .done(function (opaData) {
                  var keyedOpaData = keyBy(opaData, 'parcel_number')
                  $.each(aisData.features, function (index, feature) {
                    $.extend(feature.properties, keyedOpaData[feature.properties.opa_account_num] || {})
                  })

                  state.features = state.features.concat(aisData.features);
                  state.page = aisData.page;
                  history.replaceState(state, ''); // Second param not optional in IE10

                  $.each(aisData.features, addRow);
                  if (state.totalSize === state.features.length) app.hooks.seeMore.hide();

                  // Remove old Tablesaw data and refresh
                  $('[data-hook="results-table"]').table().data("table").destroy();
                  $('[data-hook="results-table"]').table().data("table").refresh();
                });
            });
        });
        app.hooks.seeMore.show();
      } else {
        app.hooks.seeMore.hide();
      }
      app.hooks.content.append(app.hooks.results);

      // Update the Tablesaw responsive tables
      $(document).trigger('enhance.tablesaw');
    }
  }

  function renderOwnerSearchDisclaimer() {
    var now = new Date(),
        mins = now.getMinutes(),
        prettyMins = mins < 10 ? ('0' + mins) : mins,
        prettyNow = (now.getMonth() + 1) + '/' + now.getDate() + '/' +  now.getFullYear() +
                    ' ' + now.getHours() + ':' + prettyMins;

    app.hooks.ownerSearchDisclaimer.removeClass('hide');
    app.hooks.ownerSearchDisclaimerDatetime.text(prettyNow);
    app.hooks.ownerSearchDisclaimerQuery.text(parsedQuery.label);

    // Fetch IP & show it
    $.getJSON('https://api.ipify.org?format=json')
      .done(function (response) {
        if (response.ip) {
          app.hooks.ownerSearchDisclaimerIp.text(response.ip);
        }
      })
      .fail(function () {
        app.hooks.ownerSearchDisclaimerIp.text(app.hooks.ownerSearchDisclaimerIp.attr('data-default'));
      });
  }

  function addRow(index, property) {
    var row = app.hooks.resultRow.clone(),
        attrs = property.properties,
        accountNumber = attrs.opa_account_num,
        withUnit = attrs.street_address,
        href = '?' + $.param({p: accountNumber});

    row.append($('').append($('').text(withUnit)));
    row.append($('').text(accounting.formatMoney(attrs.market_value)));
    row.append($('').text(moment(attrs.sale_date).format('M/D/YYYY') + ', ' + accounting.formatMoney(attrs.sale_price)));
    row.append($('').text(attrs.opa_owners && attrs.opa_owners.join(', ')));
    row.append($('').html(''));

    row.on('click', function (e) {
        if (e.ctrlKey || e.altKey || e.shiftKey) return;
        e.preventDefault();
        history.pushState({ais: property, address: withUnit}, withUnit, href);
        window.scroll(0, 0);
        app.views.property(accountNumber);
      });
    app.hooks.resultRows.append(row);
  }
};
<|endoftext|>


<commit_before>$(document).ready(function() {

var width = 500,
    height = 500,
    centered;

var packer = sm.packer();

projection = d3.geo.albersUsa()
  .scale(160000)
  .translate([-41630, 4900]);

var path = d3.geo.path().projection(projection)

svg = d3.select("#content")
  .append("svg:svg")
  .attr("width", width)
  .attr("height", height)

svg.append("rect")
    .attr("class", "background")
    .attr("width", width)
    .attr("height", height)
    .on("click", clicked);

var g = svg.append("g");
g.append("g").attr("id", "neighborhoods");
g.append("g").attr("id", "schools");

d3.json("data/neighborhood_boundaries.json", function(error, dc) {
  g.select("#neighborhoods")
    .selectAll("path")
      .data(dc.features)
    .enter().append("path")
      .attr("d", path)
      .on("click", clicked);
  g.append("path")
      .datum(topojson.mesh(dc, dc.features, function(a, b) { return a !== b; }))
      .attr("id", "state-borders")
      .attr("d", path);
});

d3.csv('data/schools.csv', function(data){
  var scale = d3.scale.sqrt().range([1,10])
  g.select("#schools").selectAll("circle")
    .data(data).enter().append("circle")
      .attr("r", 4)
      .attr("fill-opacity", 0.5)
      .attr("fill", "#FF0000")
      .attr("transform", function(d) {
        return "translate(" +
          projection([d.long, d.lat]) +
          ")";})
      .on("click", function(d) {
        $("#details").prepend("

"+d.name+"

enrollment: " +
                              d.enrollment + "

allocation: " +
                              d.alloc + "

");
      })
      .append("title").text(function(d){return d.name;});
	packMetros();
  d3.select("#school_enrollment").on("click", function() {changeSchoolData("enrollment")});
  d3.select("#school_allocation").on("click", function() {changeSchoolData("alloc")});
  d3.select("#school_location").on("click", noSchoolData);
  function noSchoolData() {
    g.select("schools").selectAll("circle")
      .transition().duration(600)
      .attr("r", 4)
  }
  function changeSchoolData(new_data_column) {
    matchScaleToData(scale, function(d){return +d[new_data_column];})
    g.select("schools").selectAll("circle")
      .transition().duration(600)
      .attr("r", function(d) {return scale(d[new_data_column])})
  }
  function matchScaleToData(scale, fieldFunction) {
    var minimum = d3.min(data, fieldFunction),
        maximum = d3.max(data, fieldFunction);
    scale.domain([minimum, maximum]);
  }
});

function packMetros() {
	var elements = d3.selectAll('#content circle')[0];
	packer.elements(elements).start();
}

function clicked(d) {
  var x, y, k;

  if (d && centered !== d) {
    var centroid = path.centroid(d);
    x = centroid[0];
    y = centroid[1];
    k = 4;
    centered = d;
  } else {
    x = width / 2;
    y = height / 2;
    k = 1;
    centered = null;
  }

  g.selectAll("path")
      .classed("active", centered && function(d) { return d === centered; });

  g.transition()
      .duration(750)
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
      .style("stroke-width", 1.5 / k + "px");
}

}); // end document ready function
<commit_msg>fix school sizing<commit_after>$(document).ready(function() {

var width = 500,
    height = 500,
    centered;

var packer = sm.packer();

projection = d3.geo.albersUsa()
  .scale(160000)
  .translate([-41630, 4900]);

var path = d3.geo.path().projection(projection)

svg = d3.select("#content")
  .append("svg:svg")
  .attr("width", width)
  .attr("height", height)

svg.append("rect")
    .attr("class", "background")
    .attr("width", width)
    .attr("height", height)
    .on("click", clicked);

var g = svg.append("g");
g.append("g").attr("id", "neighborhoods");
g.append("g").attr("id", "schools");

d3.json("data/neighborhood_boundaries.json", function(error, dc) {
  g.select("#neighborhoods")
    .selectAll("path")
      .data(dc.features)
    .enter().append("path")
      .attr("d", path)
      .on("click", clicked);
  g.append("path")
      .datum(topojson.mesh(dc, dc.features, function(a, b) { return a !== b; }))
      .attr("id", "state-borders")
      .attr("d", path);
});

d3.csv('data/schools.csv', function(data){
  var scale = d3.scale.sqrt().range([1,10])
  g.select("#schools").selectAll("circle")
    .data(data).enter().append("circle")
      .attr("r", 4)
      .attr("fill-opacity", 0.5)
      .attr("fill", "#FF0000")
      .attr("transform", function(d) {
        return "translate(" +
          projection([d.long, d.lat]) +
          ")";})
      .on("click", function(d) {
        $("#details").prepend("

"+d.name+"

enrollment: " +
                              d.enrollment + "

allocation: " +
                              d.alloc + "

");
      })
      .append("title").text(function(d){return d.name;});
	packMetros();
  d3.select("#school_enrollment").on("click", function() {changeSchoolData("enrollment")});
  d3.select("#school_allocation").on("click", function() {changeSchoolData("alloc")});
  d3.select("#school_location").on("click", noSchoolData);
  function noSchoolData() {
    g.select("#schools").selectAll("circle")
      .transition().duration(600)
      .attr("r", 4)
  }
  function changeSchoolData(new_data_column) {
    matchScaleToData(scale, function(d){return +d[new_data_column];})
    g.select("#schools").selectAll("circle")
      .transition().duration(600)
      .attr("r", function(d) {return scale(d[new_data_column])})
  }
  function matchScaleToData(scale, fieldFunction) {
    var minimum = d3.min(data, fieldFunction),
        maximum = d3.max(data, fieldFunction);
    scale.domain([minimum, maximum]);
  }
});

function packMetros() {
	var elements = d3.selectAll('#content circle')[0];
	packer.elements(elements).start();
}

function clicked(d) {
  var x, y, k;

  if (d && centered !== d) {
    var centroid = path.centroid(d);
    x = centroid[0];
    y = centroid[1];
    k = 4;
    centered = d;
  } else {
    x = width / 2;
    y = height / 2;
    k = 1;
    centered = null;
  }

  g.selectAll("path")
      .classed("active", centered && function(d) { return d === centered; });

  g.transition()
      .duration(750)
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
      .style("stroke-width", 1.5 / k + "px");
}

}); // end document ready function
<|endoftext|>


<commit_before>var app = new Vue({
    el: '#app',
    data() {
        console.log("Starting data....");
        return {
            info: [200],
            errors: []
        }
    },
    async created() {
        console.log("Starting created....");
        // axios
        //     .get('https://ipapi.co/8.8.8.8/json/')
        //     .then(function (response) {
        //         console.log(response.status);
        //         this.info = response.status;
        //         console.log(this.info)})
        try {
            console.log("Status before: "+this.info)
            // const response = await axios.get(`https://ipapi.co/8.8.8.8/json/`)
            const response = await axios.get(`http://ip-api.com/json/24.48.0.1`)
            this.info = response.status
            console.log("Status after: "+this.info)
        } catch (e) {
            this.errors.push(e)
        }

    }
});
<commit_msg>Added new API for testing.<commit_after>var app = new Vue({
    el: '#app',
    data() {
        console.log("Starting data....");
        return {
            info: 200
        }
    },
    async created() {
        console.log("Starting created....");
        try {
            console.log("Status before: "+this.info)
            // const response = await axios.get(`https://ipapi.co/8.8.8.8/json/`)
            // const response = await axios.get(`http://ip-api.com/json/24.48.0.1`)
            // const response = await axios.get(`https://www.metaweather.com/static/img/weather/ico/c.ico`)
            const response = await axios.get(`https://spreadsheets.google.com/feeds/list/1LOzOn9s7RrDyaeNYxjIKN_rbu8DUvB3Ace3SYvM0s6Q/od6/public/basic?alt=json`)
            this.info = response.status
            console.log("Status after: "+this.info)
        } catch (e) {
            this.info=404
            console.log("Error: " + e)
            console.log("Status error: "+this.info)

        }

    }
});
<|endoftext|>


<commit_before>/**
 * @class CM_Layout_Abstract
 * @extends CM_View_Abstract
 */
var CM_Layout_Abstract = CM_View_Abstract.extend({

  /** @type String */
  _class: 'CM_Layout_Abstract',

  /** @type jQuery|Null */
  _$pagePlaceholder: null,

  /** @type PromiseThrottled|Null */
  _loadPageThrottled: promiseThrottler(function(path) {
    var layout = this;
    console.log('preparing a new request');
    layout._createPagePlaceholder();
    layout._chargeSpinnerTimeout();

    console.log('starting a new request');
    return this.ajaxModal('loadPage', {path: path})
      .finally(function() {
        console.log('finally cancels the request');
        clearTimeout(layout._timeoutLoading);
      })
      .then(function(response) {
        if (response.redirectExternal) {
          cm.router.route(response.redirectExternal);
          return;
        }
        var view = layout._injectView(response);
        var reload = (layout.getClass() != response.layoutClass);
        if (reload) {
          window.location.replace(response.url);
          return;
        }
        layout._removePagePlaceholder(view.$el);
        layout._updateHistory(path, response.url);
        layout._onPageSetup(response.title, response.menuEntryHashList, response.jsTracking);
        view._ready();
        cm.event.trigger('navigate:end', {page: view, path: path});
        return view;
      })
      .catch(function(error) {
        if (!(error instanceof Promise.CancellationError)) {
          layout._errorPagePlaceholder(error);
          layout._onPageError();
          throw error;
        }
      });
  }, {cancelLeading: true}),

  /** @type {Number} timeout ID */
  _timeoutLoading: null,

  /**
   * @returns {CM_View_Abstract|null}
   */
  findPage: function() {
    return this.findChild('CM_Page_Abstract');
  },

  /**
   * @returns {CM_View_Abstract}
   */
  getPage: function() {
    var page = this.findPage();
    if (!page) {
      throw new CM_Exception('Layout doesn\'t have a page');
    }
    return page;
  },

  /**
   * @param {String} path
   * @return Promise
   */
  loadPage: function(path) {
    cm.event.trigger('navigate', path); // deprecated
    cm.event.trigger('navigate:start', {path: path});
    return this._loadPageThrottled(path);
  },

  /**
   * @param {jQuery} $el
   */
  scrollTo: function($el) {
    var pageOffsetTop = 0;
    var page = cm.findView('CM_Page_Abstract');
    if (page) {
      pageOffsetTop = page.$el.offset().top;
    }
    $(document).scrollTop($el.offset().top - pageOffsetTop);
  },

  _onPageTeardown: function() {
    $(document).scrollTop(0);
    $('.floatbox-layer').floatIn();
  },

  /**
   * @param {String} title
   * @param {String[]} menuEntryHashList
   * @param {String} [jsTracking]
   */
  _onPageSetup: function(title, menuEntryHashList, jsTracking) {
    cm.window.title.setText(title);
    $('[data-menu-entry-hash]').removeClass('active');
    var menuEntrySelectors = _.map(menuEntryHashList, function(menuEntryHash) {
      return '[data-menu-entry-hash=' + menuEntryHash + ']';
    });
    $(menuEntrySelectors.join(',')).addClass('active');
    if (jsTracking) {
      new Function(jsTracking).call(this);
    }
    if (window.location.hash) {
      var hash = window.location.hash.substring(1);
      var $anchor = $('#' + hash).add('[name=' + hash + ']');
      if ($anchor.length) {
        this.scrollTo($anchor);
      }
    }
  },

  _onPageError: function() {
    $('[data-menu-entry-hash]').removeClass('active');
  },

  _createPagePlaceholder: function() {
    if (!this._$pagePlaceholder) {
      this._$pagePlaceholder = $('
');
      this.getPage().replaceWithHtml(this._$pagePlaceholder);
      this._onPageTeardown();
    } else {
      this._$pagePlaceholder.removeClass('error').html('');
    }
  },

  /**
   * @returns {jQuery}
   */
  _getPagePlaceholder: function() {
    if (!this._$pagePlaceholder) {
      this._createPagePlaceholder();
    }
    return this._$pagePlaceholder;
  },

  /**
   * @param {Element|String|jQuery} el
   */
  _removePagePlaceholder: function(el) {
    this._getPagePlaceholder().replaceWith(el);
    this._$pagePlaceholder = null;
  },

  /**
   * @param {Error} error
   */
  _errorPagePlaceholder: function(error) {
    this._getPagePlaceholder().addClass('error').html('
' + error.message + '
');
  },

  _chargeSpinnerTimeout: function() {
    clearTimeout(this._timeoutLoading);
    this._timeoutLoading = this.setTimeout(function() {
      this._getPagePlaceholder().html('
');
    }, 750);
  },

  /**
   * @param {String} requestPath
   * @param {String} responseUrl
   */
  _updateHistory: function(requestPath, responseUrl) {
    var responseFragment = responseUrl.substr(cm.getUrl().length);
    if (requestPath === responseFragment + window.location.hash) {
      responseFragment = requestPath;
    }
    window.history.replaceState(null, null, responseFragment);
  }

});
<commit_msg>Remove debug output<commit_after>/**
 * @class CM_Layout_Abstract
 * @extends CM_View_Abstract
 */
var CM_Layout_Abstract = CM_View_Abstract.extend({

  /** @type String */
  _class: 'CM_Layout_Abstract',

  /** @type jQuery|Null */
  _$pagePlaceholder: null,

  /** @type PromiseThrottled|Null */
  _loadPageThrottled: promiseThrottler(function(path) {
    var layout = this;
    layout._createPagePlaceholder();
    layout._chargeSpinnerTimeout();

    return this.ajaxModal('loadPage', {path: path})
      .finally(function() {
        clearTimeout(layout._timeoutLoading);
      })
      .then(function(response) {
        if (response.redirectExternal) {
          cm.router.route(response.redirectExternal);
          return;
        }
        var view = layout._injectView(response);
        var reload = (layout.getClass() != response.layoutClass);
        if (reload) {
          window.location.replace(response.url);
          return;
        }
        layout._removePagePlaceholder(view.$el);
        layout._updateHistory(path, response.url);
        layout._onPageSetup(response.title, response.menuEntryHashList, response.jsTracking);
        view._ready();
        cm.event.trigger('navigate:end', {page: view, path: path});
        return view;
      })
      .catch(function(error) {
        if (!(error instanceof Promise.CancellationError)) {
          layout._errorPagePlaceholder(error);
          layout._onPageError();
          throw error;
        }
      });
  }, {cancelLeading: true}),

  /** @type {Number} timeout ID */
  _timeoutLoading: null,

  /**
   * @returns {CM_View_Abstract|null}
   */
  findPage: function() {
    return this.findChild('CM_Page_Abstract');
  },

  /**
   * @returns {CM_View_Abstract}
   */
  getPage: function() {
    var page = this.findPage();
    if (!page) {
      throw new CM_Exception('Layout doesn\'t have a page');
    }
    return page;
  },

  /**
   * @param {String} path
   * @return Promise
   */
  loadPage: function(path) {
    cm.event.trigger('navigate', path); // deprecated
    cm.event.trigger('navigate:start', {path: path});
    return this._loadPageThrottled(path);
  },

  /**
   * @param {jQuery} $el
   */
  scrollTo: function($el) {
    var pageOffsetTop = 0;
    var page = cm.findView('CM_Page_Abstract');
    if (page) {
      pageOffsetTop = page.$el.offset().top;
    }
    $(document).scrollTop($el.offset().top - pageOffsetTop);
  },

  _onPageTeardown: function() {
    $(document).scrollTop(0);
    $('.floatbox-layer').floatIn();
  },

  /**
   * @param {String} title
   * @param {String[]} menuEntryHashList
   * @param {String} [jsTracking]
   */
  _onPageSetup: function(title, menuEntryHashList, jsTracking) {
    cm.window.title.setText(title);
    $('[data-menu-entry-hash]').removeClass('active');
    var menuEntrySelectors = _.map(menuEntryHashList, function(menuEntryHash) {
      return '[data-menu-entry-hash=' + menuEntryHash + ']';
    });
    $(menuEntrySelectors.join(',')).addClass('active');
    if (jsTracking) {
      new Function(jsTracking).call(this);
    }
    if (window.location.hash) {
      var hash = window.location.hash.substring(1);
      var $anchor = $('#' + hash).add('[name=' + hash + ']');
      if ($anchor.length) {
        this.scrollTo($anchor);
      }
    }
  },

  _onPageError: function() {
    $('[data-menu-entry-hash]').removeClass('active');
  },

  _createPagePlaceholder: function() {
    if (!this._$pagePlaceholder) {
      this._$pagePlaceholder = $('
');
      this.getPage().replaceWithHtml(this._$pagePlaceholder);
      this._onPageTeardown();
    } else {
      this._$pagePlaceholder.removeClass('error').html('');
    }
  },

  /**
   * @returns {jQuery}
   */
  _getPagePlaceholder: function() {
    if (!this._$pagePlaceholder) {
      this._createPagePlaceholder();
    }
    return this._$pagePlaceholder;
  },

  /**
   * @param {Element|String|jQuery} el
   */
  _removePagePlaceholder: function(el) {
    this._getPagePlaceholder().replaceWith(el);
    this._$pagePlaceholder = null;
  },

  /**
   * @param {Error} error
   */
  _errorPagePlaceholder: function(error) {
    this._getPagePlaceholder().addClass('error').html('
' + error.message + '
');
  },

  _chargeSpinnerTimeout: function() {
    clearTimeout(this._timeoutLoading);
    this._timeoutLoading = this.setTimeout(function() {
      this._getPagePlaceholder().html('
');
    }, 750);
  },

  /**
   * @param {String} requestPath
   * @param {String} responseUrl
   */
  _updateHistory: function(requestPath, responseUrl) {
    var responseFragment = responseUrl.substr(cm.getUrl().length);
    if (requestPath === responseFragment + window.location.hash) {
      responseFragment = requestPath;
    }
    window.history.replaceState(null, null, responseFragment);
  }

});
<|endoftext|>


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

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

var booleans = ['help'];
var supported_commands = fs.readdirSync(path.join(__dirname, 'generators'));
supported_commands = supported_commands.map(function(command) {
  command = command.split(/\./)[0];
  booleans = booleans.concat(require('./generators/' + command).booleans);
  return command;
});

optimist = optimist.boolean(booleans);
var args = optimist.argv;

function valid_arguments(arguments) {
  if ((arguments.help && arguments._.length == 1)
      || arguments._.length >= 2) {
    return supported_commands.indexOf(arguments._[0]) >= 0;
  }
  return false;
}

function help() {
  var message = '\n  To view how to use a gii command, run the following:\n\n'
    + '      gii [command] --help\n\n'
    + '  where [command] can be one of the following:\n\n'
    + '      ' + supported_commands.join('\r\n      ');

  console.log(message);
}

if (args.help && !args._.length) {
  help();
} else if (valid_arguments(args)) {
  var generator = require('./generators/' + args._[0]);
  if (args.help) {
    generator.help();
  } else {
    generator.generate(args);
    console.log('\n  ' + generator.status.full_message);
  }
} else {
  console.log('\n  Invalid Usage');
  help();
}<commit_msg>added support for --version flag<commit_after>#!/usr/bin/env node

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

var version = '1.1.0';

var booleans = ['help', 'version', 'v'];
var supported_commands = fs.readdirSync(path.join(__dirname, 'generators'));
supported_commands = supported_commands.map(function(command) {
  command = command.split(/\./)[0];
  booleans = booleans.concat(require('./generators/' + command).booleans);
  return command;
});

optimist = optimist.boolean(booleans);
var args = optimist.argv;

function valid_arguments(arguments) {
  if ((arguments.help && arguments._.length == 1)
      || arguments._.length >= 2) {
    return supported_commands.indexOf(arguments._[0]) >= 0;
  }
  return false;
}

function help() {
  var message = '\n  To view how to use a gii command, run the following:\n\n'
    + '      gii [command] --help\n\n'
    + '  where [command] can be one of the following:\n\n'
    + '      ' + supported_commands.join('\r\n      ');

  console.log(message);
}

if (args.help && !args._.length) {
  help();
} else if ((args.version || args.v) && !args._.length) {
  console.log('\n  gii-cli version: ' + version);
} else if (valid_arguments(args)) {
  var generator = require('./generators/' + args._[0]);
  if (args.help) {
    generator.help();
  } else {
    generator.generate(args);
    console.log('\n  ' + generator.status.full_message);
  }
} else {
  console.log('\n  Invalid Usage');
  help();
}<|endoftext|>


<commit_before>/*!
 * thoughtful-release <https://github.com/nknapp/thoughtful-release>
 *
 * Copyright (c) 2015 Nils Knappmeier.
 * Released under the MIT license.
 */
'use strict'

var cpp = require('../lib/q-child-process')
var qfs = require('q-io/fs')
var path = require('path')
var _ = require('lodash')

var env = {
  'LANG': 'en_US'
}

/**
 * Create a git-object for a directory
 * @param {string} dir the current directory
 * @returns {Git} the git object
 */
module.exports = (dir) => new Git(dir)

/**
 * The Git class for accessing git repositories
 * @param {string} dir the working directory
 * @param {object} options optional parameters
 * @param {
 * @constructor
 */
function Git (dir, options) {
  var gitcmd = process.env['THOUGHTFUL_GIT_CMD'] || 'git'
  /**
   * Return true, if the working directory is a git-repository (i.e. has ".git"-subdirectory)
   *
   * @return {Promise<boolean>} true, if the working directory is a git-repository
   */
  this.isRepo = function isRepo () {
    return qfs.stat(path.join(dir, '.git')).then((stat) => {
      // .git directory must be a directory
      return stat.isDirectory()
    }).catch((error) => {
      if (error.code === 'ENOENT') {
        // Not .git directory
        return false
      } else {
        throw error
      }
    })
  }

  /**
   * Answer the lastest release tag or `null` if no release tag exists
   */
  this.lastRelease = function lastReleaseTag () {
    return cpp.execFile(gitcmd, ['describe', '--long', '--match', 'v*'], {env: env})
      .then((output) => {
        if (output.stderr && output.stderr.trim()) {
          throw new Error(output.stderr)
        }
        var match = output.stdout.trim().match(/^(v.+)-(\d+)-g([\da-f]+)$/)
        if (match) {
          return {
            tag: match[1],
            newCommits: Number(match[2])
          }
        } else {
          throw new Error(`No version tag found in git output: ${output.stdout}`)
        }
      }, (err) => {
        if (err.message && err.message.indexOf('fatal: No names found, cannot describe anything.') >= 0) {
          return null
        }
        throw err
      })
  }

  /**
   * Generate changelog entries for a span between two tags
   * @param {string} from the start tag
   * @param {object=} options optional parameters
   * @param {string=} options.url repository remote url
   * @param {string=} options.to the end tag. This defaults to the current commit if not set.
   */
  this.changes = function changes (from, options) {
    var to = ''
    var commitPattern = '%h'

    if (options) {
      if (options.to) {
        to = options.to
      }
      commitPattern = markdownLinkPattern(options.url)
    }
    var args = ['log', '--no-merges', `--pretty=tformat:* ${commitPattern} %s - %an`]
    if (from || to) {
      args.push(`${from}..${to}`)
    }
    return cpp.execFile(gitcmd, args).then(function (output) {
      if (output.stderr && output.stderr.trim()) {
        throw new Error(output.stderr)
      }
      return output.stdout
    })
  }
}

/**
 * Convert a repository url like "git://github.com/nknapp/bootprint" and "git@github.com/nknapp/bootprint" to
 * a tformat-pattern for git creating a markdown link to the current commit
 * like "[%h](https://github.com/nknapp/bootprint/commit/%h)".
 * If the url is not github, '%h' will be returned to default.
 * Support for other git-providers (like gitlab) could be added here.
 */
function markdownLinkPattern (url) {
  if (!_.isString(url)) {
    return '%h'
  }
  var match = url.match(/.*?(:\/\/|@)github\.com[/:](.*?)(#.*?)?$/)
  if (match) {
    var repoPath = match[2].replace(/\.git$/, '')
    return `[%h](https://github.com/${repoPath}/commit/%h)`
  } else {
    return '%h'
  }
}
<commit_msg>[Fix] Call to "git" must inherit environment from parent process<commit_after>/*!
 * thoughtful-release <https://github.com/nknapp/thoughtful-release>
 *
 * Copyright (c) 2015 Nils Knappmeier.
 * Released under the MIT license.
 */
'use strict'

var cpp = require('../lib/q-child-process')
var qfs = require('q-io/fs')
var path = require('path')
var _ = require('lodash')

var env = _.defaults({
  'LANG': 'en_US'
}, process.env)

/**
 * Create a git-object for a directory
 * @param {string} dir the current directory
 * @returns {Git} the git object
 */
module.exports = (dir) => new Git(dir)

/**
 * The Git class for accessing git repositories
 * @param {string} dir the working directory
 * @param {object} options optional parameters
 * @param {
 * @constructor
 */
function Git (dir, options) {
  var gitcmd = process.env['THOUGHTFUL_GIT_CMD'] || 'git'
  /**
   * Return true, if the working directory is a git-repository (i.e. has ".git"-subdirectory)
   *
   * @return {Promise<boolean>} true, if the working directory is a git-repository
   */
  this.isRepo = function isRepo () {
    return qfs.stat(path.join(dir, '.git')).then((stat) => {
      // .git directory must be a directory
      return stat.isDirectory()
    }).catch((error) => {
      if (error.code === 'ENOENT') {
        // Not .git directory
        return false
      } else {
        throw error
      }
    })
  }

  /**
   * Answer the lastest release tag or `null` if no release tag exists
   */
  this.lastRelease = function lastReleaseTag () {
    return cpp.execFile(gitcmd, ['describe', '--long', '--match', 'v*'], {env: env})
      .then((output) => {
        if (output.stderr && output.stderr.trim()) {
          throw new Error(output.stderr)
        }
        var match = output.stdout.trim().match(/^(v.+)-(\d+)-g([\da-f]+)$/)
        if (match) {
          return {
            tag: match[1],
            newCommits: Number(match[2])
          }
        } else {
          throw new Error(`No version tag found in git output: ${output.stdout}`)
        }
      }, (err) => {
        if (err.message && err.message.indexOf('fatal: No names found, cannot describe anything.') >= 0) {
          return null
        }
        throw err
      })
  }

  /**
   * Generate changelog entries for a span between two tags
   * @param {string} from the start tag
   * @param {object=} options optional parameters
   * @param {string=} options.url repository remote url
   * @param {string=} options.to the end tag. This defaults to the current commit if not set.
   */
  this.changes = function changes (from, options) {
    var to = ''
    var commitPattern = '%h'

    if (options) {
      if (options.to) {
        to = options.to
      }
      commitPattern = markdownLinkPattern(options.url)
    }
    var args = ['log', '--no-merges', `--pretty=tformat:* ${commitPattern} %s - %an`]
    if (from || to) {
      args.push(`${from}..${to}`)
    }
    return cpp.execFile(gitcmd, args).then(function (output) {
      if (output.stderr && output.stderr.trim()) {
        throw new Error(output.stderr)
      }
      return output.stdout
    })
  }
}

/**
 * Convert a repository url like "git://github.com/nknapp/bootprint" and "git@github.com/nknapp/bootprint" to
 * a tformat-pattern for git creating a markdown link to the current commit
 * like "[%h](https://github.com/nknapp/bootprint/commit/%h)".
 * If the url is not github, '%h' will be returned to default.
 * Support for other git-providers (like gitlab) could be added here.
 */
function markdownLinkPattern (url) {
  if (!_.isString(url)) {
    return '%h'
  }
  var match = url.match(/.*?(:\/\/|@)github\.com[/:](.*?)(#.*?)?$/)
  if (match) {
    var repoPath = match[2].replace(/\.git$/, '')
    return `[%h](https://github.com/${repoPath}/commit/%h)`
  } else {
    return '%h'
  }
}
<|endoftext|>


<commit_before>(function(){
    'use strict';

    var main        = global.minify.main,
        path        = main.path,
        Util        = main.util,
        B64img      = main.require('css-b64-images'),

        ONE_KB      = Math.pow(2, 10),
        MAX_SIZE    = 100 * ONE_KB,
        OPTIONS     = {
            maxSize: MAX_SIZE
        },

        ErrorMsg    = 'can\'t load css-b64-images \n'           +
                      'npm install css-b64-images\n'            +
                      'https://github.com/Filirom1/css-base64-images';

    /**
     * minify css data.
     * if can not minify return data
     *
     * @param name
     * @param data
     * @param callback
     */
    exports.optimize = function(name, data, callback) {
        var dir = path.dirname(name) + '/../';

        if (!B64img) {
            Util.log(ErrorMsg);
            Util.exec(callback, data);
        } else
            B64img.fromString(data, name, dir, OPTIONS, function(error, css) {
                Util.log('minify: images converted to base64 and saved in css file');
                Util.log(error);
                Util.exec(callback, css);
            });
    };
})();
<commit_msg>fix(img) if path was relative img do not put to css<commit_after>(function(){
    'use strict';

    var main        = global.minify.main,
        path        = main.path,
        Util        = main.util,
        B64img      = main.require('css-b64-images'),

        ONE_KB      = Math.pow(2, 10),
        MAX_SIZE    = 100 * ONE_KB,
        OPTIONS     = {
            maxSize: MAX_SIZE
        },

        ErrorMsg    = 'can\'t load css-b64-images \n'           +
                      'npm install css-b64-images\n'            +
                      'https://github.com/Filirom1/css-base64-images';

    /**
     * minify css data.
     * if can not minify return data
     *
     * @param name
     * @param data
     * @param callback
     */
    exports.optimize = function(name, data, callback) {
        var dir         = path.dirname(name),
            dirRelative = dir + '/../';

        if (!B64img) {
            Util.log(ErrorMsg);
            Util.exec(callback, data);
        } else
            B64img.fromString(data, dir, dirRelative, OPTIONS, function(error, css) {
                Util.log('minify: images converted to base64 and saved in css file');
                Util.log(error);
                Util.exec(callback, css);
            });
    };
})();
<|endoftext|>


<commit_before>(function() {

  var callbacksCount = 1;
  var callbacks = {};

  var isArray = Array.isArray || function(obj) {
      return obj instanceof Array;
    };

  var extend = function(obj, source) {
    if (!source) return obj;

    for (var prop in source) {
      if (source[prop] !== undefined)
        obj[prop] = source[prop];
    }

    return obj;
  };

  var noop = function() {}

  var Efte = {

    send_message: function(method, args, callback) {
      var hasCallback = callback && typeof callback == 'function';

      var callbackId = hasCallback ? callbacksCount++ : 0;

      if (hasCallback) {
        callbacks[callbackId] = callback;
      }

      args = args || {};

      args['callbackId'] = callbackId;

      // args must an dictionary
      if (Object.prototype.toString.call(args) !== '[object Object]') {
        throw new Error('Efte.send_message: args must be an object');
      }

      args = JSON.stringify(args);

      var ifr = document.createElement('iframe');
      ifr.style.display = 'none';
      document.body.appendChild(ifr);
      ifr.contentWindow.location.href = 'js://_?method=' + method + '&args=' + encodeURIComponent(args) + '&callbackId=' + callbackId;
      // ifr.parentNode.removeChild(ifr);
      setTimeout(function() {
        ifr.parentNode.removeChild(ifr);
      }, 0);

      return callbackId;
    },

    callback: function(callbackId, retValue) {
      try {
        var callback = callbacks[callbackId];
        if (!callback) return;
        callback.apply(null, [retValue]);
        // delete callbacks[callbackId];
      } catch (e) {
        alert(e);
      }
    },

    ajax: function(opts) {
      var success = opts.success || noop;
      var error = opts.error || noop;

      // null data lead native error
      if (!opts.data) {
        delete opts.data;
      }

      var contentTypeToDataType = function (contentType) {
        var jsonType = 'application/json';
        var htmlType = 'text/html';
        var xmlTypeRE = /^(?:text|application)\/xml/i;

        if (contentType) {
          contentType = contentType.split(';', 2)[0];
        }

        return contentType && (contentType == jsonType ? 'json' : contentType == htmlType ? 'html' : xmlTypeRE.test(mime) && 'xml') || 'text';
      }

      var callbackID = Efte.send_message('ajax', opts, function(xhr) {
        var errMsg = '';
        var dataType = contentTypeToDataType(xhr.dataType);
        var result = xhr.responseText;

        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {
          try {
            if (dataType == 'json') {
              result = /^\s*$/.test(result) ? null : JSON.parse(result);
            }
          } catch (e) {
            error(xhr.status, 'parsererror', xhr);
            delete callbacks[callbackID];
          }

          success(result);
          delete callbacks[callbackID];
        } else {
          error(xhr.status, xhr.message);
          delete callbacks[callbackID];
        }
      });
      return {
        cancel: function() {
          delete callbacks[callbackID];
        }
      };
    },

    action: {
      get: function(callback) {
        var cid = Efte.send_message('actionGetQuery', {}, function(query) {
          if (typeof callback != 'function') return;
          callback(query);
          delete callbacks[cid];
        });
      },
      /**
       * 打开新窗口
       * @param  {[String]} unit     [description]
       * @param  {[String]} path     [description]
       * @param  {[Object]} query    [description]
       * @param  {[Boolean]} modal    [description]
       * @param  {[Boolean]} animated [description]
       */
      open: function(unit, path, query, modal, animated) {
        var opt = {
          unit: unit,
          path: path
        };

        if (Object.prototype.toString.call(query) === '[object Object]') {
          opt.query = query;
        }

        if (modal != null) {
          opt.modal = !! modal;
        }

        opt.animated = animated != null ? !! animated : true;

        var cid = Efte.send_message('actionOpen', opt, function() {
          delete callbacks[cid];
        });
      },
      back: function(animated) {
        if (animated === undefined) {
          animated = true;
        }
        var cid = Efte.send_message('actionBack', {
          animated: animated
        }, function() {
          delete callbacks[cid];
        });
      },
      dismiss: function(animated) {
        if (animated === undefined) {
          animated = true;
        }
        var cid = Efte.send_message('actionDismiss', {
          animated: animated
        }, function() {
          delete callbacks[cid];
        });
      }
    },

    getEnv: function(callback) {
      Efte.send_message('getEnv', {}, function(env) {
        window.AppEnv = window.AppEnv || {
          parseQuery: function() {
            // query not set
            if (this.query == '${query}') {
              this.query = null;
              return;
            }

            var params = {};
            this.query.split('&').forEach(function(param) {
              var kv = param.split('=');
              var k = kv[0];
              var v = kv.length > 0 ? kv[1] : '';
              params[k] = v;
            });

            this.query = params;
          }
        };

        extend(window.AppEnv, env);
        window.AppEnv.parseQuery();

        callback();
      });
    },

    startRefresh: function() {
        Efte.stopRefresh();
    },

    stopRefresh: function() {
      Efte.send_message('stopRefresh');
    },

    genUUID: function(id) {
      // buggy
      id = id || AppEnv.dpid;

      // MD5?
      var requid = CryptoJS.MD5(id + (new Date().getTime()) + (Math.random()));
      // console.log(requid.toString());
      return requid.toString();
    },
    setTitle: function(title) {
      var cid = Efte.send_message('setTitle', {
        title: title
      }, function() {
        delete callbacks[cid];
      });
    },
    takePhoto: function(callback) {
      var cid = Efte.send_message('imagePicker', {}, function(result) {
        typeof callback == 'function' && callback(result);
        delete callbacks[cid];
      });
    },
    takePhotoByName: function(name, callback, fail) {
      var cid = Efte.send_message('imagePickerWithName', {name: name}, function (result) {
        if (result.image) {
          typeof callback == 'function' && callback(result.image);
        } else {
          typeof fail == 'function' && fail(result.message);
        }
        delete callbacks[cid];
      })
    },

    // 设置导航栏按钮
    /**
     * [{
     *  title: 'Foo',
     *  action: function () {}
     * }]
     */
    setBarButtons: function(buttons) {
      buttons = isArray(buttons) ? buttons : [buttons];
      var actionFns = [];
      buttons.forEach(function(button) {
        actionFns.push(button.action || noop);
      });
      Efte.send_message('setBarButtons', {
        buttons: buttons
      }, function(result) {
        actionFns[result.index]();
      });
    },

    /* notification publish & subscribe */
    publish: function(name, value) {
      Efte.send_message('publish', {
        name: name,
        value: value
      });
    },

    /* callback(publisher's value); */
    subscribe: function(name, callback) {
      var cid = Efte.send_message('subscribe', {
        name: name
      }, function(result) {
        (typeof callback == 'function') && callback(result.value);
      });
      return {
        unsubscribe: function() {
          delete callbacks[cid];
        }
      }
    },

    multilevel: function(options, values, callback) {
      Efte.send_message('multilevel', {
        options: options,
        values: values
      }, callback)
    },
    /**
     * datePicker
     * @options  {Object}   options    [description]
     *
     *  type: {String} date|time|datetime(default)
     *  default: {String} 2014-11-11 12:12:12(default) | 2014-11-11 | 12:12:12
     *  ...
     *
     * @callback  {Function} callback [description]
     *
     */
    datePicker: function (type, defaultDate, callback) {
      Efte.send_message('datepicker', {
        'type': type || '',
        'default': defaultDate || ''
      }, callback);
    }
  };

  try {
    module.exports = Efte;
  } catch (e) {
    window.Efte = Efte;
  }

})();
<commit_msg>return on error<commit_after>(function() {

  var callbacksCount = 1;
  var callbacks = {};

  var isArray = Array.isArray || function(obj) {
      return obj instanceof Array;
    };

  var extend = function(obj, source) {
    if (!source) return obj;

    for (var prop in source) {
      if (source[prop] !== undefined)
        obj[prop] = source[prop];
    }

    return obj;
  };

  var noop = function() {}

  var Efte = {

    send_message: function(method, args, callback) {
      var hasCallback = callback && typeof callback == 'function';

      var callbackId = hasCallback ? callbacksCount++ : 0;

      if (hasCallback) {
        callbacks[callbackId] = callback;
      }

      args = args || {};

      args['callbackId'] = callbackId;

      // args must an dictionary
      if (Object.prototype.toString.call(args) !== '[object Object]') {
        throw new Error('Efte.send_message: args must be an object');
      }

      args = JSON.stringify(args);

      var ifr = document.createElement('iframe');
      ifr.style.display = 'none';
      document.body.appendChild(ifr);
      ifr.contentWindow.location.href = 'js://_?method=' + method + '&args=' + encodeURIComponent(args) + '&callbackId=' + callbackId;
      // ifr.parentNode.removeChild(ifr);
      setTimeout(function() {
        ifr.parentNode.removeChild(ifr);
      }, 0);

      return callbackId;
    },

    callback: function(callbackId, retValue) {
      try {
        var callback = callbacks[callbackId];
        if (!callback) return;
        callback.apply(null, [retValue]);
        // delete callbacks[callbackId];
      } catch (e) {
        alert(e);
      }
    },

    ajax: function(opts) {
      var success = opts.success || noop;
      var error = opts.error || noop;

      // null data lead native error
      if (!opts.data) {
        delete opts.data;
      }

      var contentTypeToDataType = function (contentType) {
        var jsonType = 'application/json';
        var htmlType = 'text/html';
        var xmlTypeRE = /^(?:text|application)\/xml/i;

        if (contentType) {
          contentType = contentType.split(';', 2)[0];
        }

        return contentType && (contentType == jsonType ? 'json' : contentType == htmlType ? 'html' : xmlTypeRE.test(mime) && 'xml') || 'text';
      }

      var callbackID = Efte.send_message('ajax', opts, function(xhr) {
        var errMsg = '';
        var dataType = contentTypeToDataType(xhr.dataType);
        var result = xhr.responseText;

        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {
          try {
            if (dataType == 'json') {
              result = /^\s*$/.test(result) ? null : JSON.parse(result);
            }
          } catch (e) {
            error(xhr.status, 'parsererror', xhr);
            delete callbacks[callbackID];
            return;
          }

          success(result);
          delete callbacks[callbackID];
        } else {
          error(xhr.status, xhr.message);
          delete callbacks[callbackID];
        }
      });
      return {
        cancel: function() {
          delete callbacks[callbackID];
        }
      };
    },

    action: {
      get: function(callback) {
        var cid = Efte.send_message('actionGetQuery', {}, function(query) {
          if (typeof callback != 'function') return;
          callback(query);
          delete callbacks[cid];
        });
      },
      /**
       * 打开新窗口
       * @param  {[String]} unit     [description]
       * @param  {[String]} path     [description]
       * @param  {[Object]} query    [description]
       * @param  {[Boolean]} modal    [description]
       * @param  {[Boolean]} animated [description]
       */
      open: function(unit, path, query, modal, animated) {
        var opt = {
          unit: unit,
          path: path
        };

        if (Object.prototype.toString.call(query) === '[object Object]') {
          opt.query = query;
        }

        if (modal != null) {
          opt.modal = !! modal;
        }

        opt.animated = animated != null ? !! animated : true;

        var cid = Efte.send_message('actionOpen', opt, function() {
          delete callbacks[cid];
        });
      },
      back: function(animated) {
        if (animated === undefined) {
          animated = true;
        }
        var cid = Efte.send_message('actionBack', {
          animated: animated
        }, function() {
          delete callbacks[cid];
        });
      },
      dismiss: function(animated) {
        if (animated === undefined) {
          animated = true;
        }
        var cid = Efte.send_message('actionDismiss', {
          animated: animated
        }, function() {
          delete callbacks[cid];
        });
      }
    },

    getEnv: function(callback) {
      Efte.send_message('getEnv', {}, function(env) {
        window.AppEnv = window.AppEnv || {
          parseQuery: function() {
            // query not set
            if (this.query == '${query}') {
              this.query = null;
              return;
            }

            var params = {};
            this.query.split('&').forEach(function(param) {
              var kv = param.split('=');
              var k = kv[0];
              var v = kv.length > 0 ? kv[1] : '';
              params[k] = v;
            });

            this.query = params;
          }
        };

        extend(window.AppEnv, env);
        window.AppEnv.parseQuery();

        callback();
      });
    },

    startRefresh: function() {
        Efte.stopRefresh();
    },

    stopRefresh: function() {
      Efte.send_message('stopRefresh');
    },

    genUUID: function(id) {
      // buggy
      id = id || AppEnv.dpid;

      // MD5?
      var requid = CryptoJS.MD5(id + (new Date().getTime()) + (Math.random()));
      // console.log(requid.toString());
      return requid.toString();
    },
    setTitle: function(title) {
      var cid = Efte.send_message('setTitle', {
        title: title
      }, function() {
        delete callbacks[cid];
      });
    },
    takePhoto: function(callback) {
      var cid = Efte.send_message('imagePicker', {}, function(result) {
        typeof callback == 'function' && callback(result);
        delete callbacks[cid];
      });
    },
    takePhotoByName: function(name, callback, fail) {
      var cid = Efte.send_message('imagePickerWithName', {name: name}, function (result) {
        if (result.image) {
          typeof callback == 'function' && callback(result.image);
        } else {
          typeof fail == 'function' && fail(result.message);
        }
        delete callbacks[cid];
      })
    },

    // 设置导航栏按钮
    /**
     * [{
     *  title: 'Foo',
     *  action: function () {}
     * }]
     */
    setBarButtons: function(buttons) {
      buttons = isArray(buttons) ? buttons : [buttons];
      var actionFns = [];
      buttons.forEach(function(button) {
        actionFns.push(button.action || noop);
      });
      Efte.send_message('setBarButtons', {
        buttons: buttons
      }, function(result) {
        actionFns[result.index]();
      });
    },

    /* notification publish & subscribe */
    publish: function(name, value) {
      Efte.send_message('publish', {
        name: name,
        value: value
      });
    },

    /* callback(publisher's value); */
    subscribe: function(name, callback) {
      var cid = Efte.send_message('subscribe', {
        name: name
      }, function(result) {
        (typeof callback == 'function') && callback(result.value);
      });
      return {
        unsubscribe: function() {
          delete callbacks[cid];
        }
      }
    },

    multilevel: function(options, values, callback) {
      Efte.send_message('multilevel', {
        options: options,
        values: values
      }, callback)
    },
    /**
     * datePicker
     * @options  {Object}   options    [description]
     *
     *  type: {String} date|time|datetime(default)
     *  default: {String} 2014-11-11 12:12:12(default) | 2014-11-11 | 12:12:12
     *  ...
     *
     * @callback  {Function} callback [description]
     *
     */
    datePicker: function (type, defaultDate, callback) {
      Efte.send_message('datepicker', {
        'type': type || '',
        'default': defaultDate || ''
      }, callback);
    }
  };

  try {
    module.exports = Efte;
  } catch (e) {
    window.Efte = Efte;
  }

})();
<|endoftext|>


<commit_before>(function() {

    var callbacksCount = 1;
    var callbacks = {};

    var isArray = Array.isArray || function(obj) {
            return obj instanceof Array;
        };

    var extend = function(obj, source) {
        if (!source) return obj;

        for (var prop in source) {
            if (source[prop] !== undefined)
                obj[prop] = source[prop];
        }

        return obj;
    };

    var emptyFn = function() {}

    var Efte = {

        send_message: function(method, args, callback) {
            // console.log('send_message', arguments);
            var hasCallback = callback && typeof callback == 'function';
            var callbackId = hasCallback ? callbacksCount++ : 0;
            if (hasCallback) callbacks[callbackId] = callback;

            args['callbackId'] = callbackId;
            args = (typeof args === 'object') ? JSON.stringify(args) : args + '';
            var ifr = document.createElement('iframe');
            ifr.style.display = 'none';
            document.body.appendChild(ifr);
            ifr.contentWindow.location.href = 'js://_?method=' + method + '&args=' + encodeURIComponent(args) + '&callbackId=' + callbackId;
            // ifr.parentNode.removeChild(ifr);
            setTimeout(function() {
                ifr.parentNode.removeChild(ifr);
            }, 0);

            return callbackId;
        },

        callback: function(callbackId, retValue) {
            try {
                var callback = callbacks[callbackId];
                if (!callback) return;
                callback.apply(null, [retValue]);
                // delete callbacks[callbackId];
            } catch (e) {
                alert(e);
            }
        },

        ajax: function(opts) {
            var success = opts.success || emptyFn;
            var fail = opts.fail || emptyFn;

            var callbackID = Efte.send_message('ajax', opts, function(json) {
                var errMsg = '';
                if (json.code == 0) {
                    var rsp = null;
                    try {
                        rsp = JSON.parse(json.responseText);
                        success(rsp);
                        delete callbacks[callbackID];
                    } catch (e) {
                        fail(-2, 'parse json error: ' + e.message);
                        console.log(json);
                        delete callbacks[callbackID];
                    }
                } else {
                    fail(json.code, json.message);
                    delete callbacks[callbackID];
                }
            });
            return {
                cancel: function() {
                    delete callbacks[callbackID];
                }
            };
        },

        action: {
            get: function(callback) {
                var cid = Efte.send_message('actionGetQuery', {}, function(query) {
                    if (typeof callback != 'function') return;
                    callback(query);
                    delete callbacks[cid];
                });
            },
            open: function(unit, path, query, modal, animated) {
                modal = !! modal;
                if (animated === undefined) {
                    animated = true;
                }
                var cid = Efte.send_message('actionOpen', {
                    unit: unit,
                    path: path,
                    query: query,
                    modal: modal,
                    animated: animated
                }, function() {
                    delete callbacks[cid];
                });
            },
            back: function(animated) {
                if (animated === undefined) {
                    animated = true;
                }
                var cid = Efte.send_message('actionBack', {
                    animated: animated
                }, function() {
                    delete callbacks[cid];
                });
            },
            dismiss: function(animated) {
                if (animated === undefined) {
                    animated = true;
                }
                var cid = Efte.send_message('actionDismiss', {
                    animated: animated
                }, function() {
                    delete callbacks[cid];
                });
            }
        },

        getEnv: function(callback) {
            Efte.send_message('getEnv', {}, function(env) {
                window.AppEnv = window.AppEnv || {
                    parseQuery: function() {
                        // query not set
                        if (this.query == '${query}') {
                            this.query = null;
                            return;
                        }

                        var params = {};
                        this.query.split('&').forEach(function(param) {
                            var kv = param.split('=');
                            var k = kv[0];
                            var v = kv.length > 0 ? kv[1] : '';
                            params[k] = v;
                        });

                        this.query = params;
                    }
                };

                extend(window.AppEnv, env);
                window.AppEnv.parseQuery();

                callback();
            });
        },

        /*
        startRefresh: function() {
            // override this method plz
        },
        */

        stopRefresh: function() {
            Efte.send_message('stopRefresh');
        },
        genUUID: function(id) {
            // buggy
            id = id || AppEnv.dpid;

            // MD5?
            var requid = CryptoJS.MD5(id + (new Date().getTime()) + (Math.random()));
            // console.log(requid.toString());
            return requid.toString();
        },
        setTitle: function(title) {
            var cid = Efte.send_message('setTitle', {
                title: title
            }, function() {
                delete callbacks[cid];
            });
        },
        takePhoto: function(callback) {
            var cid = Efte.send_message('imagePicker', {}, function(result) {
                typeof callback == 'function' && callback(result && result.image);
                delete callbacks[cid];
            });
        },

        // 设置导航栏按钮
        /**
         * [{
         *  title: 'Foo',
         *  action: function () {}
         * }]
         */
        setBarButtons: function(buttons) {
            buttons = isArray(buttons) ? buttons : [buttons];
            var actionFns = [];
            buttons.forEach(function(button) {
                actionFns.push(button.action || emptyFn);
            });
            Efte.send_message('setBarButtons', {
                buttons: buttons
            }, function(result) {
                actionFns[result.index]();
            });
        },

        /* notification publish & subscribe */
        publish: function(name, value) {
            Efte.send_message('publish', {
                name: name,
                value: value
            });
        },

        /* callback(publisher's value); */
        subscribe: function(name, callback) {
            var cid = Efte.send_message('subscribe', {
                name: name
            }, function(result) {
                (typeof callback == 'function') && callback(result.value);
            });
            return {
                unsubscribe: function() {
                    delete callbacks[cid];
                }
            }
        }
    };

    try {
        module.exports = Efte;
    } catch (e) {
        window.Efte = Efte;
    }

})();
<commit_msg>format tab<commit_after>(function() {

  var callbacksCount = 1;
  var callbacks = {};

  var isArray = Array.isArray || function(obj) {
    return obj instanceof Array;
  };

  var extend = function(obj, source) {
    if (!source) return obj;

    for (var prop in source) {
      if (source[prop] !== undefined)
        obj[prop] = source[prop];
    }

    return obj;
  };

  var emptyFn = function() {}

  var Efte = {

    send_message: function(method, args, callback) {
      // console.log('send_message', arguments);
      var hasCallback = callback && typeof callback == 'function';
      var callbackId = hasCallback ? callbacksCount++ : 0;
      if (hasCallback) callbacks[callbackId] = callback;

      args['callbackId'] = callbackId;
      args = (typeof args === 'object') ? JSON.stringify(args) : args + '';
      var ifr = document.createElement('iframe');
      ifr.style.display = 'none';
      document.body.appendChild(ifr);
      ifr.contentWindow.location.href = 'js://_?method=' + method + '&args=' + encodeURIComponent(args) + '&callbackId=' + callbackId;
      // ifr.parentNode.removeChild(ifr);
      setTimeout(function() {
        ifr.parentNode.removeChild(ifr);
      }, 0);

      return callbackId;
    },

    callback: function(callbackId, retValue) {
      try {
        var callback = callbacks[callbackId];
        if (!callback) return;
        callback.apply(null, [retValue]);
        // delete callbacks[callbackId];
      } catch (e) {
        alert(e);
      }
    },

    ajax: function(opts) {
      var success = opts.success || emptyFn;
      var fail = opts.fail || emptyFn;

      var callbackID = Efte.send_message('ajax', opts, function(json) {
        var errMsg = '';
        if (json.code == 0) {
          var rsp = null;
          try {
            rsp = JSON.parse(json.responseText);
            success(rsp);
            delete callbacks[callbackID];
          } catch (e) {
            fail(-2, 'parse json error: ' + e.message);
            console.log(json);
            delete callbacks[callbackID];
          }
        } else {
          fail(json.code, json.message);
          delete callbacks[callbackID];
        }
      });
      return {
        cancel: function() {
          delete callbacks[callbackID];
        }
      };
    },

    action: {
      get: function(callback) {
        var cid = Efte.send_message('actionGetQuery', {}, function(query) {
          if (typeof callback != 'function') return;
          callback(query);
          delete callbacks[cid];
        });
      },
      open: function(unit, path, query, modal, animated) {
        modal = !!modal;
        if (animated === undefined) {
          animated = true;
        }
        var cid = Efte.send_message('actionOpen', {
          unit: unit,
          path: path,
          query: query,
          modal: modal,
          animated: animated
        }, function() {
          delete callbacks[cid];
        });
      },
      back: function(animated) {
        if (animated === undefined) {
          animated = true;
        }
        var cid = Efte.send_message('actionBack', {
          animated: animated
        }, function() {
          delete callbacks[cid];
        });
      },
      dismiss: function(animated) {
        if (animated === undefined) {
          animated = true;
        }
        var cid = Efte.send_message('actionDismiss', {
          animated: animated
        }, function() {
          delete callbacks[cid];
        });
      }
    },

    getEnv: function(callback) {
      Efte.send_message('getEnv', {}, function(env) {
        window.AppEnv = window.AppEnv || {
          parseQuery: function() {
            // query not set
            if (this.query == '${query}') {
              this.query = null;
              return;
            }

            var params = {};
            this.query.split('&').forEach(function(param) {
              var kv = param.split('=');
              var k = kv[0];
              var v = kv.length > 0 ? kv[1] : '';
              params[k] = v;
            });

            this.query = params;
          }
        };

        extend(window.AppEnv, env);
        window.AppEnv.parseQuery();

        callback();
      });
    },

    /*
        startRefresh: function() {
            // override this method plz
        },
        */

    stopRefresh: function() {
      Efte.send_message('stopRefresh');
    },
    genUUID: function(id) {
      // buggy
      id = id || AppEnv.dpid;

      // MD5?
      var requid = CryptoJS.MD5(id + (new Date().getTime()) + (Math.random()));
      // console.log(requid.toString());
      return requid.toString();
    },
    setTitle: function(title) {
      var cid = Efte.send_message('setTitle', {
        title: title
      }, function() {
        delete callbacks[cid];
      });
    },
    takePhoto: function(callback) {
      var cid = Efte.send_message('imagePicker', {}, function(result) {
        typeof callback == 'function' && callback(result && result.image);
        delete callbacks[cid];
      });
    },

    // 设置导航栏按钮
    /**
     * [{
     *  title: 'Foo',
     *  action: function () {}
     * }]
     */
    setBarButtons: function(buttons) {
      buttons = isArray(buttons) ? buttons : [buttons];
      var actionFns = [];
      buttons.forEach(function(button) {
        actionFns.push(button.action || emptyFn);
      });
      Efte.send_message('setBarButtons', {
        buttons: buttons
      }, function(result) {
        actionFns[result.index]();
      });
    },

    /* notification publish & subscribe */
    publish: function(name, value) {
      Efte.send_message('publish', {
        name: name,
        value: value
      });
    },

    /* callback(publisher's value); */
    subscribe: function(name, callback) {
      var cid = Efte.send_message('subscribe', {
        name: name
      }, function(result) {
        (typeof callback == 'function') && callback(result.value);
      });
      return {
        unsubscribe: function() {
          delete callbacks[cid];
        }
      }
    }
  };

  try {
    module.exports = Efte;
  } catch (e) {
    window.Efte = Efte;
  }

})();<|endoftext|>


<commit_before>'use strict'
const _ = require('lodash')

function Job(row, queue) {
    _.extend(this, row)
    this.queue = queue
    this.db = queue.db
    this.handled = false
}

Job.prototype.finish = function() {
    this.handled = true
    this.state = 'finished'
    return this.db.none('UPDATE "JobQueue" SET "state"=${state}, "lastRun"=NOW() WHERE "id"=${id}', {
        state: this.state,
        id: this.id
    })
    .then(() => this.queue.logEvent('finished', this))
}

Job.prototype.destroy = function() {
    this.handled = true
    this.state = 'destroyed'
    return this.db.none('DELETE FROM "JobQueue" WHERE "id"=${id}', {
        id: this.id
    })
    .then(() => this.queue.logEvent('destroyed', this))
}

Job.prototype.reschedule = function(date) {
    this.handled = true
    this.state = 'waiting'
    this.scheduledFor = date
    return this.db.none('UPDATE "JobQueue" SET "state"=${state}, "scheduledFor"=${scheduledFor} WHERE "id"=${id}', {
        state: this.state,
        id: this.id,
        scheduledFor: this.scheduledFor
    })
    .then(() => this.queue.logEvent('rescheduled', this))
    .then(() => this.queue.logEvent('finished', this))
}

Job.prototype.fail = function (error, rescheduleFor) {
    var self = this;
    self.handled = true;
    return self.db.task(function*(t) {
        yield t.none('UPDATE "JobQueue" SET "lastFailureMessage"=${failureMessage}, "failedAttempts"="failedAttempts"+1, "lastRun"=NOW() WHERE "id"=${id}', {
            id: self.id,
            failureMessage: error.message
        });
        let JobQueue = yield t.one('SELECT * FROM "JobQueue" WHERE "id"=${id}', {id: self.id});
        if (JobQueue.failedAttempts >= JobQueue.maxAttempts) {
            // complete failure, ensure the job isn't run again
            self.state = 'failed';
            return yield t.none('UPDATE "JobQueue" SET "state"=${state} WHERE "id"=${id}', {
                id: self.id,
                state: self.state
            });
        }
        // reschedule the job to run in 3 minute
        var now = new Date();
        var minute = 3 * 60 * 1000;
        self.scheduledFor = rescheduleFor || new Date(now.getTime() + minute);
        self.state = 'waiting';
        return yield t.none('UPDATE "JobQueue" SET "state"=${state}, "scheduledFor"=${scheduledFor} WHERE "id"=${id}', {
            id: self.id,
            state: self.state,
            scheduledFor: self.scheduledFor
        });
    })
        .then(() => self.queue.logEvent('failed', self))
        .then(() => self.queue.logError(error, self));
};

module.exports = Job
<commit_msg>Update job.js<commit_after>'use strict'
const _ = require('lodash')

function Job(row, queue) {
    _.extend(this, row)
    this.queue = queue
    this.db = queue.db
    this.handled = false
}

Job.prototype.finish = function() {
    this.handled = true
    this.state = 'finished'
    return this.db.none('UPDATE "JobQueue" SET "state"=${state}, "lastRun"=NOW() WHERE "id"=${id}', {
        state: this.state,
        id: this.id
    })
    .then(() => this.queue.logEvent('finished', this))
}

Job.prototype.destroy = function() {
    this.handled = true
    this.state = 'destroyed'
    return this.db.none('DELETE FROM "JobQueue" WHERE "id"=${id}', {
        id: this.id
    })
    .then(() => this.queue.logEvent('destroyed', this))
}

Job.prototype.reschedule = function(date) {
    this.handled = true
    this.state = 'waiting'
    this.scheduledFor = date
    return this.db.none('UPDATE "JobQueue" SET "state"=${state}, "scheduledFor"=${scheduledFor} WHERE "id"=${id}', {
        state: this.state,
        id: this.id,
        scheduledFor: this.scheduledFor
    })
    .then(() => this.queue.logEvent('rescheduled', this))
    .then(() => this.queue.logEvent('finished', this))
}

Job.prototype.fail = function (error, rescheduleFor) {
    let self = this;
    self.handled = true;
    return self.db.tx(function*(t) {
        yield t.none('UPDATE "JobQueue" SET "lastFailureMessage"=${failureMessage}, "failedAttempts"="failedAttempts"+1, "lastRun"=NOW() WHERE "id"=${id}', {
            id: self.id,
            failureMessage: error.message
        });
        let JobQueue = yield t.one('SELECT * FROM "JobQueue" WHERE "id"=${id}', {id: self.id});
        if (JobQueue.failedAttempts >= JobQueue.maxAttempts) {
            // complete failure, ensure the job isn't run again
            self.state = 'failed';
            return yield t.none('UPDATE "JobQueue" SET "state"=${state} WHERE "id"=${id}', {
                id: self.id,
                state: self.state
            });
        }
        // reschedule the job to run in 3 minute
        let now = new Date();
        let minute = 3 * 60 * 1000;
        self.scheduledFor = rescheduleFor || new Date(now.getTime() + minute);
        self.state = 'waiting';
        return yield t.none('UPDATE "JobQueue" SET "state"=${state}, "scheduledFor"=${scheduledFor} WHERE "id"=${id}', {
            id: self.id,
            state: self.state,
            scheduledFor: self.scheduledFor
        });
    })
        .then(() => self.queue.logEvent('failed', self))
        .then(() => self.queue.logError(error, self));
};

module.exports = Job
<|endoftext|>


<commit_before>'use strict';

var Lexer = require('lex');
var acorn = require('acorn');

function getStringFromExpression(expr) {
    if (expr.type === 'BinaryExpression' && expr.operator === '+') {
        var left = getStringFromExpression(expr.left);
        var right = getStringFromExpression(expr.right);
        return (left === null || right === null) ? null : (left + right);
    } else if (expr.type === 'Literal') {
        return expr.value;
    } else {
        return null;
    }
}

function extractFromExpression(expression) {
    try {
        var expr = acorn.parseExpressionAt(expression, 0, {});
        return getStringFromExpression(expr);
    } catch (ignored) {
        return null;
    }
}

function extract(quoteChar, message) {
    var str = '';
    for (var i = 0, len = message.length; i < len; i++) {
        var c = message[i];
        if (c === quoteChar && i > 0 && message.charAt(i - 1) !== '\\') {
            break;
        }
        str += c;
    }

    if (str.length === len) {
        return str;
    }

    return extractFromExpression(quoteChar + message + quoteChar) || str;
}

function unescape(str) {
    return str.replace(/\\'/g, '\'').replace(/\s+/g, ' ').trim();
}

module.exports = function(config) {
    return {
        tokenize: function tokenize(source) {
            var tokens = [],
                lexer = new Lexer(function() {
                });
            config.stringsRules.forEach(function(rule) {
                lexer.addRule(rule, function(lexeme, quoteChar, message) {
                    var str = extract(quoteChar, message);
                    tokens.push(unescape(str));
                }, []);
            });
            lexer.setInput(source).lex();

            return tokens;
        },
        getScope: function(source) {
            var scope = '',
                lexer = new Lexer(function() {
                });
            config.scopeRules.forEach(function(rule) {
                lexer.addRule(rule, function(lexeme, value) {
                    if (value) {
                        scope = value;
                    }
                }, []);
            });
            lexer.setInput(source).lex();
            return scope;
        }
    };
};
<commit_msg>Add warnings for duplicated scope declaration, and for possible invalid string extraction<commit_after>'use strict';

var Lexer = require('lex');
var acorn = require('acorn');

function getStringFromExpression(expr) {
    if (expr.type === 'BinaryExpression' && expr.operator === '+') {
        var left = getStringFromExpression(expr.left);
        var right = getStringFromExpression(expr.right);
        return (left === null || right === null) ? null : (left + right);
    } else if (expr.type === 'Literal') {
        return expr.value;
    } else {
        return null;
    }
}

function extractFromExpression(expression) {
    try {
        var expr = acorn.parseExpressionAt(expression, 0, {});
        return getStringFromExpression(expr);
    } catch (ignored) {
        return null;
    }
}

function extract(quoteChar, message) {
    var str = '';
    for (var i = 0, len = message.length; i < len; i++) {
        var c = message[i];
        if (c === quoteChar && i > 0 && message.charAt(i - 1) !== '\\') {
            break;
        }
        str += c;
    }

    if (str.length === len) {
        return str;
    }

    var str2 = extractFromExpression(quoteChar + message + quoteChar);
    if (str2) {
        return str2;
    } else {
        console.error('Message is extracted partially:',
            quoteChar + message + quoteChar, '->', quoteChar + str + quoteChar);
        return str;
    }
}

function unescape(str) {
    return str.replace(/\\'/g, '\'').replace(/\s+/g, ' ').trim();
}

module.exports = function(config) {
    return {
        tokenize: function tokenize(source) {
            var tokens = [],
                lexer = new Lexer(function() {
                });
            config.stringsRules.forEach(function(rule) {
                lexer.addRule(rule, function(lexeme, quoteChar, message) {
                    var str = extract(quoteChar, message);
                    tokens.push(unescape(str));
                }, []);
            });
            lexer.setInput(source).lex();

            return tokens;
        },
        getScope: function(source) {
            var scope = '',
                lexer = new Lexer(function() {
                });
            config.scopeRules.forEach(function(rule) {
                lexer.addRule(rule, function(lexeme, value) {
                    if (value) {
                        if (scope) {
                            console.error('Scope is already defined as "' + scope +
                                '", and redefined to "' + value + '"');
                        }
                        scope = value;
                    }
                }, []);
            });
            lexer.setInput(source).lex();
            return scope;
        }
    };
};
<|endoftext|>


<commit_before>const verbosity = + process.env.npm_package_config_verbosity + 0;

const SUPPORTS_256_COLORS =
    /256/.test(process.env.TERM) ||
    'Apple_terminal' === process.env.TERM_PROGRAM ||
    'iTerm' === process.env.TERM_PROGRAM ||
    'Hyper' === process.env.TERM_PROGRAM;

function getColourFfixes (level)
{
    let prefix, suffix;
    if (SUPPORTS_256_COLORS)
    {
        let levelColour = 250 - (level-1) * 7;
        prefix = '\x1b[38;5;' + levelColour + 'm';
        suffix = '\x1b[m';
    }
    else
    {
        prefix = '';
        suffix = '';
    }

    return {prefix, suffix};
}

// level=1: api method calls
// level=2: browsers’ lifecycle, api method failures and finishes
// level=3: waiting and other intermediate steps
// level=4: full result data and full wait data
function log (level, ...argv)
{
    if (level <= verbosity)
    {
        let {prefix, suffix} = getColourFfixes(level);
        // eslint-disable-next-line no-console
        console.log(prefix + '📽  filmweb', new Date, ...argv, suffix);
    }
}

module.exports = log;
<commit_msg>Adjust log verbosity colours range<commit_after>const verbosity = + process.env.npm_package_config_verbosity + 0;

const MAX_VERBOSITY = 5;
const MAX_VERBOSITY_COLOUR = 250;
const MIN_VERBOSITY_COLOUR = 240;

const SUPPORTS_256_COLORS =
    /256/.test(process.env.TERM) ||
    'Apple_terminal' === process.env.TERM_PROGRAM ||
    'iTerm' === process.env.TERM_PROGRAM ||
    'Hyper' === process.env.TERM_PROGRAM;

function getColourFfixes (level)
{
    let prefix, suffix;
    if (SUPPORTS_256_COLORS)
    {
        let levelColour = parseInt(
            MAX_VERBOSITY_COLOUR -
            (MAX_VERBOSITY_COLOUR - MIN_VERBOSITY_COLOUR) *
            (level - 1) / (MAX_VERBOSITY - 1),
            10
        );
        prefix = '\x1b[38;5;' + levelColour + 'm';
        suffix = '\x1b[m';
    }
    else
    {
        prefix = '';
        suffix = '';
    }

    return {prefix, suffix};
}

// level=1: api method calls
// level=2: browsers’ lifecycle, api method failures and finishes
// level=3: waiting and other intermediate steps
// level=4: full result data and full wait data
function log (level, ...argv)
{
    if (level <= verbosity)
    {
        let {prefix, suffix} = getColourFfixes(level);
        // eslint-disable-next-line no-console
        console.log(prefix + '📽  filmweb', new Date, ...argv, suffix);
    }
}

module.exports = log;
<|endoftext|>