<commit_before>export function fireEvent(node, eventName) {
  let doc = {};
  if (node.ownerDocument) {
    doc = node.ownerDocument;
  } else if (node.nodeType === 9) {
    doc = node;
  }
  if (node.dispatchEvent) {
    let eventClass = '';
    switch (eventName) {
      case 'click':
      case 'mousedown':
      case 'mouseup':
        eventClass = 'MouseEvents';
        break;
      case 'focus':
      case 'change':
      case 'blur':
      case 'select':
        eventClass = 'HTMLEvents';
        break;
      default:
        break;
    }
    const event = doc.createEvent(eventClass);
    event.initEvent(eventName, true, true); // All events created as bubbling and cancelable.

    event.synthetic = true; // allow detection of synthetic events
    // The second parameter says go ahead with the default action
    node.dispatchEvent(event, true);
  } else if (node.fireEvent) {
    // IE-old school style
    const event = doc.createEventObject();
    event.synthetic = true; // allow detection of synthetic events
    node.fireEvent('on' + eventName, event);
  }
}

export function executionEnvironment() {
  const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);

  return {
    canUseDOM,
    canUseWorkers: typeof Worker !== 'undefined',
    canUseEventListeners:
    canUseDOM && !!(window.addEventListener || window.attachEvent),
    canUseViewport: canUseDOM && !!window.screen
  };
}

export function getWindowHeight() {
  if (!executionEnvironment().canUseDOM) {
    return 0;
  }
  const w = window;
  const d = document;
  const e = d.documentElement;
  const g = d.getElementsByTagName('body')[0];
  return w.innerHeight || e.clientHeight || g.clientHeight;
}

export function getWindowWidth() {
  if (!executionEnvironment().canUseDOM) {
    return 0;
  }
  const w = window;
  const d = document;
  const e = d.documentElement;
  const g = d.getElementsByTagName('body')[0];
  return w.innerWidth || e.clientWidth || g.clientWidth;
}

export function getDeviceType() {
  if (!executionEnvironment().canUseDOM) {
    return 0;
  }
  const w = window || null;
  const d = document;
  const e = d.documentElement;
  const g = d.getElementsByTagName('body')[0];
  const witdh = w.innerWidth || e.clientWidth || g.clientWidth;
  if (witdh < 768) {
    return 'mobile';
  }
  if (witdh >= 768 && witdh < 1024) {
    return 'tablet';
  }
  return 'desktop';
}
<commit_msg>[feat] add cookie helpers<commit_after>export function fireEvent(node, eventName) {
  let doc = {};
  if (node.ownerDocument) {
    doc = node.ownerDocument;
  } else if (node.nodeType === 9) {
    doc = node;
  }
  if (node.dispatchEvent) {
    let eventClass = '';
    switch (eventName) {
      case 'click':
      case 'mousedown':
      case 'mouseup':
        eventClass = 'MouseEvents';
        break;
      case 'focus':
      case 'change':
      case 'blur':
      case 'select':
        eventClass = 'HTMLEvents';
        break;
      default:
        break;
    }
    const event = doc.createEvent(eventClass);
    event.initEvent(eventName, true, true); // All events created as bubbling and cancelable.

    event.synthetic = true; // allow detection of synthetic events
    // The second parameter says go ahead with the default action
    node.dispatchEvent(event, true);
  } else if (node.fireEvent) {
    // IE-old school style
    const event = doc.createEventObject();
    event.synthetic = true; // allow detection of synthetic events
    node.fireEvent('on' + eventName, event);
  }
}

export function executionEnvironment() {
  const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);

  return {
    canUseDOM,
    canUseWorkers: typeof Worker !== 'undefined',
    canUseEventListeners:
    canUseDOM && !!(window.addEventListener || window.attachEvent),
    canUseViewport: canUseDOM && !!window.screen
  };
}

export function getWindowHeight() {
  if (!executionEnvironment().canUseDOM) {
    return 0;
  }
  const w = window;
  const d = document;
  const e = d.documentElement;
  const g = d.getElementsByTagName('body')[0];
  return w.innerHeight || e.clientHeight || g.clientHeight;
}

export function getWindowWidth() {
  if (!executionEnvironment().canUseDOM) {
    return 0;
  }
  const w = window;
  const d = document;
  const e = d.documentElement;
  const g = d.getElementsByTagName('body')[0];
  return w.innerWidth || e.clientWidth || g.clientWidth;
}

export function getDeviceType() {
  if (!executionEnvironment().canUseDOM) {
    return 0;
  }
  const w = window || null;
  const d = document;
  const e = d.documentElement;
  const g = d.getElementsByTagName('body')[0];
  const witdh = w.innerWidth || e.clientWidth || g.clientWidth;
  if (witdh < 768) {
    return 'mobile';
  }
  if (witdh >= 768 && witdh < 1024) {
    return 'tablet';
  }
  return 'desktop';
}

/* eslint-disable */
// https://learn.javascript.ru/cookie#функция-getcookie-name
function getCookie(name) {
  if (!executionEnvironment().canUseDOM) return;

  var matches = document.cookie.match(new RegExp(
    "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
  ));
  return matches ? decodeURIComponent(matches[1]) : undefined;
}

// https://learn.javascript.ru/cookie#функция-setcookie-name-value-options
function setCookie(name, value, options) {
  if (!executionEnvironment().canUseDOM) return;

  options = options || {};

  var expires = options.expires;

  if (typeof expires == "number" && expires) {
    var d = new Date();
    d.setTime(d.getTime() + expires * 1000);
    expires = options.expires = d;
  }
  if (expires && expires.toUTCString) {
    options.expires = expires.toUTCString();
  }

  value = encodeURIComponent(value);

  var updatedCookie = name + "=" + value;

  for (var propName in options) {
    updatedCookie += "; " + propName;
    var propValue = options[propName];
    if (propValue !== true) {
      updatedCookie += "=" + propValue;
    }
  }

  document.cookie = updatedCookie;
}

// https://learn.javascript.ru/cookie#функция-deletecookie-name
function deleteCookie(name) {
  setCookie(name, "", {
    expires: -1
  })
}
/* eslint-enable */
<|endoftext|>


<commit_before>user_pref("layout.spellcheckDefault", 2);
user_pref("spellchecker.dictionary", "en-GB");
user_pref("plugins.click_to_play", true);
user_pref("browser.newtab.url", "https://www.google.co.nz");
user_pref("browser.fixup.alternate.enabled", false);
user_pref("keyword.enabled", false);
user_pref("browser.tabs.tabClipWidth", 1);
<commit_msg>Added locale to firefox user preferences.<commit_after>user_pref("layout.spellcheckDefault", 2);
user_pref("spellchecker.dictionary", "en-GB");
user_pref("general.useragent.locale", "en-GB");
user_pref("plugins.click_to_play", true);
user_pref("browser.newtab.url", "https://www.google.co.nz");
user_pref("browser.fixup.alternate.enabled", false);
user_pref("keyword.enabled", false);
user_pref("browser.tabs.tabClipWidth", 1);
<|endoftext|>


<commit_before>(function(global) {
  class TemplateTHREENode extends NIN.THREENode {
    constructor(id, options) {
      super(id, {
        outputs: {
          render: new NIN.TextureOutput()
        }
      });

      this.cube = new THREE.Mesh(new THREE.BoxGeometry(50, 5, 5),
                                 new THREE.MeshBasicMaterial({ color: 0x000fff }));
      this.scene.add(this.cube);

      var light = new THREE.PointLight(0xffffff, 1, 100);
      light.position.set(50, 50, 50);
      this.scene.add(light);

      this.camera.position.z = 100;
    }

    update(frame) {
      super.update(frame);

      this.cube.rotation.x = Math.sin(frame / 10);
      this.cube.rotation.y = Math.cos(frame / 10);
    }
  }

  global.TemplateTHREENode = TemplateTHREENode;
})(this);
<commit_msg>Pass through camera option in threenode<commit_after>(function(global) {
  class TemplateTHREENode extends NIN.THREENode {
    constructor(id, options) {
      super(id, {
        camera: options.camera,
        outputs: {
          render: new NIN.TextureOutput()
        }
      });

      this.cube = new THREE.Mesh(new THREE.BoxGeometry(50, 5, 5),
                                 new THREE.MeshBasicMaterial({ color: 0x000fff }));
      this.scene.add(this.cube);

      var light = new THREE.PointLight(0xffffff, 1, 100);
      light.position.set(50, 50, 50);
      this.scene.add(light);

      this.camera.position.z = 100;
    }

    update(frame) {
      super.update(frame);

      this.cube.rotation.x = Math.sin(frame / 10);
      this.cube.rotation.y = Math.cos(frame / 10);
    }
  }

  global.TemplateTHREENode = TemplateTHREENode;
})(this);
<|endoftext|>


<commit_before>//= require Chart.bundle
//= require chartkick
//= require moment
//= require EpicEditor
//= require jquery-sortable/jquery-sortable
//= require bootstrap-daterangepicker
//= require jquery.fix.clone
//= require admin/file_uploads
//= require admin/s3_uploads.js
//= require admin/email_tabulation
//= require admin/petitions
//= require admin/epic_editor_helper
//= require s3_cors_fileupload
//= require bootstrap-sass/bootstrap/tab
//= require bootstrap-responsive-tabs

$(document).on('ready', function() {

  var editor = initEpicEditor('action-page-description', 'description');
  var editor2 = initEpicEditor('action-page-what-to-say', 'what-to-say');
  var editor3 = initEpicEditor('epic-petition-description', 'petition-description');
  var editor4 = initEpicEditor('epic-action-summary', 'action-summary');
  var editor5 = initEpicEditor('epic-email-text', 'email-text');
  var editor6 = initEpicEditor('epic-victory-message', 'victory-message');

  $("#action-page-description").data("editor", editor);
  $("#action-page-what-to-say").data("editor", editor2);
  $("#epic-petition-description-").data("editor", editor3);
  $("#epic-action-summary").data("editor", editor4);
  $("#epic-email-text").data("editor", editor5);
  $("#epic-victory-message").data("editor", editor);

  $("#date_control_container").each(function() {
    var date_start = $(this).data("date-start");
    var date_end = $(this).data("date-end");

    var action = $(".date_submit", this)[0];
    var base_url = window.location.pathname;
    action.href = base_url + "?date_start=" + date_start + "&date_end=" + date_end + window.location.hash;

    $("input#date_range", this).daterangepicker({
      format: "YYYY-MM-DD",
      startDate: date_start,
      endDate: date_end
    });

    $("input#date_range", this).on('apply.daterangepicker', function(ev, picker){
      date_start = picker.startDate.format("YYYY-MM-DD");
      date_end = picker.endDate.format("YYYY-MM-DD");
      action.href = base_url + "?date_start=" + date_start + "&date_end=" + date_end + window.location.hash;
      $('.daterangepicker').hide();
    });

    $("input#date_range", this).on('cancel.daterangepicker', function(ev, picker){
      $('.daterangepicker').hide();
    });
  });

  $(".edit-action .panel-heading").click(function(){
    setTimeout(function() {editor2.reflow()}, 100);
  });

  // This is a hack to make the "edit petition description" Epiceditor display at the right height when the panel is openened.
  $("#action_page_enable_petition").change(function(){
    setTimeout(function(){editor3.reflow()}, 100);
  });

  $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
    if(typeof editor5 != 'undefined'){
      editor5.reflow();
      editor6.reflow();
    }
  });

  $('.thumbnail').on('click', function (ev) {
    var image = $(ev.currentTarget);
    var md  = image.attr('src');
    $('.markdown-image-code').text(md);
    return false;
  });

  // the campaign tag should mirror the title, unless changed
  // this is for tracking analytics and will be delivered to congress-forms
  var campaign_tag_changed = false;
  var $title = $('#action_page_title');
  var campaign_tag_selector = '#action_page_email_campaign_attributes_campaign_tag';
  var $campaign_tag = $(campaign_tag_selector);
  if($title.val() != $campaign_tag.val())
    campaign_tag_changed = true;
  $title.keyup(function(e){
    var $campaign_tag = $(campaign_tag_selector);
    if(!campaign_tag_changed){
      $campaign_tag.val($title.val());
    }
  });
  $campaign_tag.on("change keyup",function(){
    campaign_tag_changed = true;
  });

  if (window.location.hash.length) {
    $('a[data-tab="'+window.location.hash.slice(1)+'"]').tab('show');
    window.scrollTo(0, 0); // Otherwise page starts scrolled to initial tab location
  }
  $('.edit-action .nav-tabs a').on('show.bs.tab', function(e) {
    var anchor = $(e.target).data('tab');
    $('#anchor').val(anchor);
    history.pushState(null,null,'#' + anchor);
  });
  $('.action_pages-index .nav-tabs a').on('show.bs.tab', function(e) {
    var anchor = $(e.target).data('tab');
    $('#anchor').val(anchor);
    history.pushState(null,null,'#' + anchor);
  });

  var updated_at = $('#action_page_updated_at');
  if (updated_at.length > 0) {
    var t = window.setInterval(function() {
      $.get(updated_at.data('url'), { updated_at: updated_at.val() },
        function(data) {
          if (data.updated) {
            $('#action-page-form').submit(function(e) {
              if (confirm('Are you sure? This page has been updated since you started editing.')) {
                return;
              }
              e.preventDefault();
            });
            window.clearInterval(t);
          }
        }
      );
    }, 10000);
  }

  var preview_button = $('#action-page-preview').click(function() {
    var form = $('#action-page-form').clone()
                 .attr("id", null).css("display", "none")
                 .attr('action', preview_button.attr('href'))
                 .attr('target', '_blank');
    $("body").append(form);
    form.submit();
    return false;
  });

  var $target_house = $('#action_page_email_campaign_attributes_target_house');
  var $target_senate = $('#action_page_email_campaign_attributes_target_senate');
  var $target_email = $('#action_page_email_campaign_attributes_target_email');
  var $addresses = $('#action_page_email_campaign_attributes_email_addresses');
  var $target_bioguide_id = $('#action_page_email_campaign_attributes_target_bioguide_id');
  var $bioguide_id = $('#action_page_email_campaign_attributes_bioguide_id');
  var $topic_category = $('#topic_category_form_group');
  var $campaign_tag = $('#campaign_tag_form_group');
  var $text_replacement = $('#text_replacement_form_group');

  function setup_target_ux($target_checkbox, $text_field, hide_cf_fields, show_alt_text_fields){
    if($target_checkbox.is(':checked')){
      $target_house.prop('disabled', true);
      $target_senate.prop('disabled', true);
      $target_bioguide_id.prop('disabled', true);
      $target_email.prop('disabled', true);
      $bioguide_id.hide();
      $addresses.hide();

      if(hide_cf_fields){
        $topic_category.hide();
        $campaign_tag.hide();
      }
      if(show_alt_text_fields){
        $text_replacement.show();
      }

      $text_field.show();
      $target_checkbox.prop('disabled', false);
    }
  }

  function create_target_listener($target_checkbox, $text_field, toggle_cf_fields, toggle_alt_text_fields){
    $target_checkbox.change(function(e){
      if($(this).is(':checked')){
        $target_house.prop('checked', false);
        $target_house.prop('disabled', true);
        $target_senate.prop('checked', false);
        $target_senate.prop('disabled', true);
        $target_bioguide_id.prop('checked', false);
        $target_bioguide_id.prop('disabled', true);
        $target_email.prop('checked', false);
        $target_email.prop('disabled', true);

        $target_checkbox.prop('checked', true);
        $target_checkbox.prop('disabled', false);

        if(toggle_cf_fields){
          $topic_category.hide();
          $campaign_tag.hide();
        }

        if(toggle_alt_text_fields){
          $text_replacement.show();
        }

        $text_field.show();
      } else {
        $target_house.prop('disabled', false);
        $target_senate.prop('disabled', false);
        $target_bioguide_id.prop('disabled', false);
        $target_email.prop('disabled', false);

        if(toggle_cf_fields){
          $topic_category.show();
          $campaign_tag.show();
        }

        if(toggle_alt_text_fields){
          $text_replacement.hide();
        }

        $text_field.hide();
      }
    });
  }

  create_target_listener($target_email, $addresses, true, false);
  create_target_listener($target_bioguide_id, $bioguide_id, false, true);

  setup_target_ux($target_email, $addresses, true, false);
  setup_target_ux($target_bioguide_id, $bioguide_id, false, true);

  // Bootstrap popovers and tooltips
  $('.action_pages-index i.has-tooltip').tooltip();

  var popovers = "#protip2, #protip3, .photo-specs-popover, .photo-popover";
  $(popovers).popover();

  $(popovers).on('shown.bs.popover', function(){
    $(".popover").click(function(e){
      e.stopPropagation();
    });

    $("body").click(function(){
      $(popovers).popover('hide');
      $("body").off('click');
    });
  });

  // Prevent scrolling to the top of the page when clicking on protip popovers.
  $( 'a[href="#"]' ).click( function(e) {
    e.preventDefault();
  } );
});

// Make chart.js redraw charts when we resize the browser
Chart.defaults.global.responsive = true;

// Bootstrap responsive tabs: https://github.com/openam/bootstrap-responsive-tabs
fakewaffle.responsiveTabs(['xs']);
<commit_msg>Move responsiveTab initialization into document.ready<commit_after>//= require Chart.bundle
//= require chartkick
//= require moment
//= require EpicEditor
//= require jquery-sortable/jquery-sortable
//= require bootstrap-daterangepicker
//= require jquery.fix.clone
//= require admin/file_uploads
//= require admin/s3_uploads.js
//= require admin/email_tabulation
//= require admin/petitions
//= require admin/epic_editor_helper
//= require s3_cors_fileupload
//= require bootstrap-sass/bootstrap/tab
//= require bootstrap-responsive-tabs

$(document).on('ready', function() {

  var editor = initEpicEditor('action-page-description', 'description');
  var editor2 = initEpicEditor('action-page-what-to-say', 'what-to-say');
  var editor3 = initEpicEditor('epic-petition-description', 'petition-description');
  var editor4 = initEpicEditor('epic-action-summary', 'action-summary');
  var editor5 = initEpicEditor('epic-email-text', 'email-text');
  var editor6 = initEpicEditor('epic-victory-message', 'victory-message');

  $("#action-page-description").data("editor", editor);
  $("#action-page-what-to-say").data("editor", editor2);
  $("#epic-petition-description-").data("editor", editor3);
  $("#epic-action-summary").data("editor", editor4);
  $("#epic-email-text").data("editor", editor5);
  $("#epic-victory-message").data("editor", editor);

  $("#date_control_container").each(function() {
    var date_start = $(this).data("date-start");
    var date_end = $(this).data("date-end");

    var action = $(".date_submit", this)[0];
    var base_url = window.location.pathname;
    action.href = base_url + "?date_start=" + date_start + "&date_end=" + date_end + window.location.hash;

    $("input#date_range", this).daterangepicker({
      format: "YYYY-MM-DD",
      startDate: date_start,
      endDate: date_end
    });

    $("input#date_range", this).on('apply.daterangepicker', function(ev, picker){
      date_start = picker.startDate.format("YYYY-MM-DD");
      date_end = picker.endDate.format("YYYY-MM-DD");
      action.href = base_url + "?date_start=" + date_start + "&date_end=" + date_end + window.location.hash;
      $('.daterangepicker').hide();
    });

    $("input#date_range", this).on('cancel.daterangepicker', function(ev, picker){
      $('.daterangepicker').hide();
    });
  });

  $(".edit-action .panel-heading").click(function(){
    setTimeout(function() {editor2.reflow()}, 100);
  });

  // This is a hack to make the "edit petition description" Epiceditor display at the right height when the panel is openened.
  $("#action_page_enable_petition").change(function(){
    setTimeout(function(){editor3.reflow()}, 100);
  });

  $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
    if(typeof editor5 != 'undefined'){
      editor5.reflow();
      editor6.reflow();
    }
  });

  $('.thumbnail').on('click', function (ev) {
    var image = $(ev.currentTarget);
    var md  = image.attr('src');
    $('.markdown-image-code').text(md);
    return false;
  });

  // the campaign tag should mirror the title, unless changed
  // this is for tracking analytics and will be delivered to congress-forms
  var campaign_tag_changed = false;
  var $title = $('#action_page_title');
  var campaign_tag_selector = '#action_page_email_campaign_attributes_campaign_tag';
  var $campaign_tag = $(campaign_tag_selector);
  if($title.val() != $campaign_tag.val())
    campaign_tag_changed = true;
  $title.keyup(function(e){
    var $campaign_tag = $(campaign_tag_selector);
    if(!campaign_tag_changed){
      $campaign_tag.val($title.val());
    }
  });
  $campaign_tag.on("change keyup",function(){
    campaign_tag_changed = true;
  });

  if (window.location.hash.length) {
    $('a[data-tab="'+window.location.hash.slice(1)+'"]').tab('show');
    window.scrollTo(0, 0); // Otherwise page starts scrolled to initial tab location
  }
  $('.edit-action .nav-tabs a').on('show.bs.tab', function(e) {
    var anchor = $(e.target).data('tab');
    $('#anchor').val(anchor);
    history.pushState(null,null,'#' + anchor);
  });
  $('.action_pages-index .nav-tabs a').on('show.bs.tab', function(e) {
    var anchor = $(e.target).data('tab');
    $('#anchor').val(anchor);
    history.pushState(null,null,'#' + anchor);
  });

  var updated_at = $('#action_page_updated_at');
  if (updated_at.length > 0) {
    var t = window.setInterval(function() {
      $.get(updated_at.data('url'), { updated_at: updated_at.val() },
        function(data) {
          if (data.updated) {
            $('#action-page-form').submit(function(e) {
              if (confirm('Are you sure? This page has been updated since you started editing.')) {
                return;
              }
              e.preventDefault();
            });
            window.clearInterval(t);
          }
        }
      );
    }, 10000);
  }

  var preview_button = $('#action-page-preview').click(function() {
    var form = $('#action-page-form').clone()
                 .attr("id", null).css("display", "none")
                 .attr('action', preview_button.attr('href'))
                 .attr('target', '_blank');
    $("body").append(form);
    form.submit();
    return false;
  });

  var $target_house = $('#action_page_email_campaign_attributes_target_house');
  var $target_senate = $('#action_page_email_campaign_attributes_target_senate');
  var $target_email = $('#action_page_email_campaign_attributes_target_email');
  var $addresses = $('#action_page_email_campaign_attributes_email_addresses');
  var $target_bioguide_id = $('#action_page_email_campaign_attributes_target_bioguide_id');
  var $bioguide_id = $('#action_page_email_campaign_attributes_bioguide_id');
  var $topic_category = $('#topic_category_form_group');
  var $campaign_tag = $('#campaign_tag_form_group');
  var $text_replacement = $('#text_replacement_form_group');

  function setup_target_ux($target_checkbox, $text_field, hide_cf_fields, show_alt_text_fields){
    if($target_checkbox.is(':checked')){
      $target_house.prop('disabled', true);
      $target_senate.prop('disabled', true);
      $target_bioguide_id.prop('disabled', true);
      $target_email.prop('disabled', true);
      $bioguide_id.hide();
      $addresses.hide();

      if(hide_cf_fields){
        $topic_category.hide();
        $campaign_tag.hide();
      }
      if(show_alt_text_fields){
        $text_replacement.show();
      }

      $text_field.show();
      $target_checkbox.prop('disabled', false);
    }
  }

  function create_target_listener($target_checkbox, $text_field, toggle_cf_fields, toggle_alt_text_fields){
    $target_checkbox.change(function(e){
      if($(this).is(':checked')){
        $target_house.prop('checked', false);
        $target_house.prop('disabled', true);
        $target_senate.prop('checked', false);
        $target_senate.prop('disabled', true);
        $target_bioguide_id.prop('checked', false);
        $target_bioguide_id.prop('disabled', true);
        $target_email.prop('checked', false);
        $target_email.prop('disabled', true);

        $target_checkbox.prop('checked', true);
        $target_checkbox.prop('disabled', false);

        if(toggle_cf_fields){
          $topic_category.hide();
          $campaign_tag.hide();
        }

        if(toggle_alt_text_fields){
          $text_replacement.show();
        }

        $text_field.show();
      } else {
        $target_house.prop('disabled', false);
        $target_senate.prop('disabled', false);
        $target_bioguide_id.prop('disabled', false);
        $target_email.prop('disabled', false);

        if(toggle_cf_fields){
          $topic_category.show();
          $campaign_tag.show();
        }

        if(toggle_alt_text_fields){
          $text_replacement.hide();
        }

        $text_field.hide();
      }
    });
  }

  create_target_listener($target_email, $addresses, true, false);
  create_target_listener($target_bioguide_id, $bioguide_id, false, true);

  setup_target_ux($target_email, $addresses, true, false);
  setup_target_ux($target_bioguide_id, $bioguide_id, false, true);

  // Bootstrap popovers and tooltips
  $('.action_pages-index i.has-tooltip').tooltip();

  var popovers = "#protip2, #protip3, .photo-specs-popover, .photo-popover";
  $(popovers).popover();

  $(popovers).on('shown.bs.popover', function(){
    $(".popover").click(function(e){
      e.stopPropagation();
    });

    $("body").click(function(){
      $(popovers).popover('hide');
      $("body").off('click');
    });
  });

  // Prevent scrolling to the top of the page when clicking on protip popovers.
  $( 'a[href="#"]' ).click( function(e) {
    e.preventDefault();
  } );

  // Bootstrap responsive tabs: https://github.com/openam/bootstrap-responsive-tabs
  fakewaffle.responsiveTabs(['xs']);
});

// Make chart.js redraw charts when we resize the browser
Chart.defaults.global.responsive = true;

<|endoftext|>


<commit_before>/* eslint-disable func-names, space-before-function-paren, no-var, space-before-blocks, prefer-rest-params, wrap-iife, no-use-before-define, no-param-reassign, quotes, yoda, no-else-return, consistent-return, comma-dangle, semi, object-shorthand, prefer-template, one-var, one-var-declaration-per-line, no-unused-vars, max-len, vars-on-top, padded-blocks */
/* global Breakpoints */
/* global Turbolinks */

(function() {
  var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  this.Build = (function() {
    Build.interval = null;

    Build.state = null;

    function Build(options) {
      options = options || $('.js-build-options').data();
      this.pageUrl = options.pageUrl;
      this.buildUrl = options.buildUrl;
      this.buildStatus = options.buildStatus;
      this.state = options.logState;
      this.buildStage = options.buildStage;
      this.updateDropdown = bind(this.updateDropdown, this);
      this.$document = $(document);
      this.$body = $('body');
      this.$buildTrace = $('#build-trace');
      this.$autoScrollContainer = $('.autoscroll-container');
      this.$autoScrollStatus = $('#autoscroll-status');
      this.$upBuildTrace = $('#up-build-trace');
      this.$downBuildTrace = $('#down-build-trace');
      this.$scrollTopBtn = $('#scroll-top');
      this.$scrollBottomBtn = $('#scroll-bottom');

      clearInterval(Build.interval);
      // Init breakpoint checker
      this.bp = Breakpoints.get();

      this.initSidebar();
      this.$buildScroll = $('#js-build-scroll');

      this.populateJobs(this.buildStage);
      this.updateStageDropdownText(this.buildStage);
      this.sidebarOnResize();

      this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this));
      this.$document.off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown);
      this.$document.on('scroll', this.initScrollMonitor.bind(this));
      $(window).off('resize.build').on('resize.build', this.sidebarOnResize.bind(this));
      $('a', this.$buildScroll).off('click.stepTrace').on('click.stepTrace', this.stepTrace);
      this.updateArtifactRemoveDate();
      if ($('#build-trace').length) {
        this.getInitialBuildTrace();
        this.initScrollButtonAffix();
      }
      if (this.buildStatus === "running" || this.buildStatus === "pending") {
        Build.interval = setInterval((function(_this) {
          // Check for new build output if user still watching build page
          // Only valid for runnig build when output changes during time
          return function() {
            if (_this.location() === _this.pageUrl) {
              return _this.getBuildTrace();
            }
          };
        })(this), 4000);
      }
    }

    Build.prototype.initSidebar = function() {
      this.$sidebar = $('.js-build-sidebar');
      this.sidebarTranslationLimits = {
        min: $('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight()
      }
      this.sidebarTranslationLimits.max = this.sidebarTranslationLimits.min + $('.scrolling-tabs-container').outerHeight();
      this.$sidebar.css({
        top: this.sidebarTranslationLimits.max
      });
      this.$sidebar.niceScroll();
      this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar);
      this.$document.off('scroll.translateSidebar').on('scroll.translateSidebar', this.translateSidebar.bind(this));
    };

    Build.prototype.location = function() {
      return window.location.href.split("#")[0];
    };

    Build.prototype.getInitialBuildTrace = function() {
      var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped']

      return $.ajax({
        url: this.buildUrl,
        dataType: 'json',
        success: (function(_this) {
          return function(buildData) {
            $('.js-build-output').html(buildData.trace_html);
            if (removeRefreshStatuses.indexOf(buildData.status) >= 0) {
              _this.initScrollMonitor();
              return $('.js-build-refresh').remove();
            }
          };
        })(this)
      });
    };

    Build.prototype.getBuildTrace = function() {
      return $.ajax({
        url: this.pageUrl + "/trace.json?state=" + (encodeURIComponent(this.state)),
        dataType: "json",
        success: (function(_this) {
          return function(log) {
            if (log.state) {
              _this.state = log.state;
            }
            if (log.status === "running") {
              if (log.append) {
                $('.js-build-output').append(log.html);
              } else {
                $('.js-build-output').html(log.html);
              }
              return _this.checkAutoscroll();
            } else if (log.status !== _this.buildStatus) {
              return Turbolinks.visit(_this.pageUrl);
            }
          };
        })(this)
      });
    };

    Build.prototype.checkAutoscroll = function() {
      if ($("#autoscroll-status").data("state") === "enabled") {
        return $("html,body").scrollTop($("#build-trace").height());
      }

      // Handle a situation where user started new build
      // but never scrolled a page
      if (!this.$scrollTopBtn.is(':visible') &&
          !this.$scrollBottomBtn.is(':visible') &&
          !gl.utils.isInViewport(this.$downBuildTrace[0])) {
        this.$scrollBottomBtn.show();
      }
    };

    Build.prototype.initScrollButtonAffix = function() {
      // Hide everything initially
      this.$scrollTopBtn.hide();
      this.$scrollBottomBtn.hide();
      this.$autoScrollContainer.hide();
    }

    // Page scroll listener to detect if user has scrolling page
    // and handle following cases
    // 1) User is at Top of Build Log;
    //      - Hide Top Arrow button
    //      - Show Bottom Arrow button
    //      - Disable Autoscroll and hide indicator (when build is running)
    // 2) User is at Bottom of Build Log;
    //      - Show Top Arrow button
    //      - Hide Bottom Arrow button
    //      - Enable Autoscroll and show indicator (when build is running)
    // 3) User is somewhere in middle of Build Log;
    //      - Show Top Arrow button
    //      - Show Bottom Arrow button
    //      - Disable Autoscroll and hide indicator (when build is running)
    Build.prototype.initScrollMonitor = function() {
      if (gl.utils.isInViewport(this.$upBuildTrace[0])) { // User is at Top of Build Log
        this.$scrollTopBtn.hide();
        this.$scrollBottomBtn.show();
      }

      if (gl.utils.isInViewport(this.$downBuildTrace[0])) { // User is at Bottom of Build Log
        this.$scrollTopBtn.show();
        this.$scrollBottomBtn.hide();

        // Show and Reposition Autoscroll Status Indicator
        this.$autoScrollContainer.css({ top: this.$body.outerHeight() - 75 }).fadeIn(100);
        this.$autoScrollStatus.find('.status-text').addClass('animate');
      }

      if (!gl.utils.isInViewport(this.$upBuildTrace[0]) && !gl.utils.isInViewport(this.$downBuildTrace[0])) { // User is somewhere in middle of Build Log
        this.$scrollTopBtn.show();
        this.$scrollBottomBtn.show();

        // Hide Autoscroll Status Indicator
        this.$autoScrollContainer.hide();
        this.$autoScrollStatus.find('.status-text').removeClass('animate');
      }

      if (this.buildStatus === "running" || this.buildStatus === "pending") {
        // Check if Refresh Animation is in Viewport and enable Autoscroll, disable otherwise.
        this.$autoScrollStatus.data("state", gl.utils.isInViewport($('.js-build-refresh')[0]) ? 'enabled' : 'disabled');
      }
    };

    Build.prototype.shouldHideSidebarForViewport = function() {
      var bootstrapBreakpoint;
      bootstrapBreakpoint = this.bp.getBreakpointSize();
      return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm';
    };

    Build.prototype.translateSidebar = function(e) {
      var newPosition = this.sidebarTranslationLimits.max - (document.body.scrollTop || document.documentElement.scrollTop);
      if (newPosition < this.sidebarTranslationLimits.min) newPosition = this.sidebarTranslationLimits.min;
      this.$sidebar.css({
        top: newPosition
      });
    };

    Build.prototype.toggleSidebar = function(shouldHide) {
      var shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined;
      this.$buildScroll.toggleClass('sidebar-expanded', shouldShow)
        .toggleClass('sidebar-collapsed', shouldHide);
      this.$sidebar.toggleClass('right-sidebar-expanded', shouldShow)
        .toggleClass('right-sidebar-collapsed', shouldHide);
    };

    Build.prototype.sidebarOnResize = function() {
      this.toggleSidebar(this.shouldHideSidebarForViewport());
    };

    Build.prototype.sidebarOnClick = function() {
      if (this.shouldHideSidebarForViewport()) this.toggleSidebar();
    };

    Build.prototype.updateArtifactRemoveDate = function() {
      var $date, date;
      $date = $('.js-artifacts-remove');
      if ($date.length) {
        date = $date.text();
        return $date.text(gl.utils.timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3')), ' '));
      }
    };

    Build.prototype.populateJobs = function(stage) {
      $('.build-job').hide();
      $('.build-job[data-stage="' + stage + '"]').show();
    };

    Build.prototype.updateStageDropdownText = function(stage) {
      $('.stage-selection').text(stage);
    };

    Build.prototype.updateDropdown = function(e) {
      e.preventDefault();
      var stage = e.currentTarget.text;
      this.updateStageDropdownText(stage);
      this.populateJobs(stage);
    };

    Build.prototype.stepTrace = function(e) {
      var $currentTarget;
      e.preventDefault();
      $currentTarget = $(e.currentTarget);
      $.scrollTo($currentTarget.attr('href'), {
        offset: -($('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight())
      });
    };

    return Build;

  })();

}).call(this);
<commit_msg>Use `bind` instead of currying to access outer context<commit_after>/* eslint-disable func-names, space-before-function-paren, no-var, space-before-blocks, prefer-rest-params, wrap-iife, no-use-before-define, no-param-reassign, quotes, yoda, no-else-return, consistent-return, comma-dangle, semi, object-shorthand, prefer-template, one-var, one-var-declaration-per-line, no-unused-vars, max-len, vars-on-top, padded-blocks */
/* global Breakpoints */
/* global Turbolinks */

(function() {
  var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  this.Build = (function() {
    Build.interval = null;

    Build.state = null;

    function Build(options) {
      options = options || $('.js-build-options').data();
      this.pageUrl = options.pageUrl;
      this.buildUrl = options.buildUrl;
      this.buildStatus = options.buildStatus;
      this.state = options.logState;
      this.buildStage = options.buildStage;
      this.updateDropdown = bind(this.updateDropdown, this);
      this.$document = $(document);
      this.$body = $('body');
      this.$buildTrace = $('#build-trace');
      this.$autoScrollContainer = $('.autoscroll-container');
      this.$autoScrollStatus = $('#autoscroll-status');
      this.$upBuildTrace = $('#up-build-trace');
      this.$downBuildTrace = $('#down-build-trace');
      this.$scrollTopBtn = $('#scroll-top');
      this.$scrollBottomBtn = $('#scroll-bottom');

      clearInterval(Build.interval);
      // Init breakpoint checker
      this.bp = Breakpoints.get();

      this.initSidebar();
      this.$buildScroll = $('#js-build-scroll');

      this.populateJobs(this.buildStage);
      this.updateStageDropdownText(this.buildStage);
      this.sidebarOnResize();

      this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.sidebarOnClick.bind(this));
      this.$document.off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown);
      this.$document.on('scroll', this.initScrollMonitor.bind(this));
      $(window).off('resize.build').on('resize.build', this.sidebarOnResize.bind(this));
      $('a', this.$buildScroll).off('click.stepTrace').on('click.stepTrace', this.stepTrace);
      this.updateArtifactRemoveDate();
      if ($('#build-trace').length) {
        this.getInitialBuildTrace();
        this.initScrollButtonAffix();
      }
      if (this.buildStatus === "running" || this.buildStatus === "pending") {
        Build.interval = setInterval((function(_this) {
          // Check for new build output if user still watching build page
          // Only valid for runnig build when output changes during time
          return function() {
            if (_this.location() === _this.pageUrl) {
              return _this.getBuildTrace();
            }
          };
        })(this), 4000);
      }
    }

    Build.prototype.initSidebar = function() {
      this.$sidebar = $('.js-build-sidebar');
      this.sidebarTranslationLimits = {
        min: $('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight()
      }
      this.sidebarTranslationLimits.max = this.sidebarTranslationLimits.min + $('.scrolling-tabs-container').outerHeight();
      this.$sidebar.css({
        top: this.sidebarTranslationLimits.max
      });
      this.$sidebar.niceScroll();
      this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar);
      this.$document.off('scroll.translateSidebar').on('scroll.translateSidebar', this.translateSidebar.bind(this));
    };

    Build.prototype.location = function() {
      return window.location.href.split("#")[0];
    };

    Build.prototype.getInitialBuildTrace = function() {
      var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped']

      return $.ajax({
        url: this.buildUrl,
        dataType: 'json',
        success: function(buildData) {
          $('.js-build-output').html(buildData.trace_html);
          if (removeRefreshStatuses.indexOf(buildData.status) >= 0) {
            this.initScrollMonitor();
            return $('.js-build-refresh').remove();
          }
        }.bind(this)
      });
    };

    Build.prototype.getBuildTrace = function() {
      return $.ajax({
        url: this.pageUrl + "/trace.json?state=" + (encodeURIComponent(this.state)),
        dataType: "json",
        success: (function(_this) {
          return function(log) {
            if (log.state) {
              _this.state = log.state;
            }
            if (log.status === "running") {
              if (log.append) {
                $('.js-build-output').append(log.html);
              } else {
                $('.js-build-output').html(log.html);
              }
              return _this.checkAutoscroll();
            } else if (log.status !== _this.buildStatus) {
              return Turbolinks.visit(_this.pageUrl);
            }
          };
        })(this)
      });
    };

    Build.prototype.checkAutoscroll = function() {
      if ($("#autoscroll-status").data("state") === "enabled") {
        return $("html,body").scrollTop($("#build-trace").height());
      }

      // Handle a situation where user started new build
      // but never scrolled a page
      if (!this.$scrollTopBtn.is(':visible') &&
          !this.$scrollBottomBtn.is(':visible') &&
          !gl.utils.isInViewport(this.$downBuildTrace[0])) {
        this.$scrollBottomBtn.show();
      }
    };

    Build.prototype.initScrollButtonAffix = function() {
      // Hide everything initially
      this.$scrollTopBtn.hide();
      this.$scrollBottomBtn.hide();
      this.$autoScrollContainer.hide();
    }

    // Page scroll listener to detect if user has scrolling page
    // and handle following cases
    // 1) User is at Top of Build Log;
    //      - Hide Top Arrow button
    //      - Show Bottom Arrow button
    //      - Disable Autoscroll and hide indicator (when build is running)
    // 2) User is at Bottom of Build Log;
    //      - Show Top Arrow button
    //      - Hide Bottom Arrow button
    //      - Enable Autoscroll and show indicator (when build is running)
    // 3) User is somewhere in middle of Build Log;
    //      - Show Top Arrow button
    //      - Show Bottom Arrow button
    //      - Disable Autoscroll and hide indicator (when build is running)
    Build.prototype.initScrollMonitor = function() {
      if (gl.utils.isInViewport(this.$upBuildTrace[0])) { // User is at Top of Build Log
        this.$scrollTopBtn.hide();
        this.$scrollBottomBtn.show();
      }

      if (gl.utils.isInViewport(this.$downBuildTrace[0])) { // User is at Bottom of Build Log
        this.$scrollTopBtn.show();
        this.$scrollBottomBtn.hide();

        // Show and Reposition Autoscroll Status Indicator
        this.$autoScrollContainer.css({ top: this.$body.outerHeight() - 75 }).fadeIn(100);
        this.$autoScrollStatus.find('.status-text').addClass('animate');
      }

      if (!gl.utils.isInViewport(this.$upBuildTrace[0]) && !gl.utils.isInViewport(this.$downBuildTrace[0])) { // User is somewhere in middle of Build Log
        this.$scrollTopBtn.show();
        this.$scrollBottomBtn.show();

        // Hide Autoscroll Status Indicator
        this.$autoScrollContainer.hide();
        this.$autoScrollStatus.find('.status-text').removeClass('animate');
      }

      if (this.buildStatus === "running" || this.buildStatus === "pending") {
        // Check if Refresh Animation is in Viewport and enable Autoscroll, disable otherwise.
        this.$autoScrollStatus.data("state", gl.utils.isInViewport($('.js-build-refresh')[0]) ? 'enabled' : 'disabled');
      }
    };

    Build.prototype.shouldHideSidebarForViewport = function() {
      var bootstrapBreakpoint;
      bootstrapBreakpoint = this.bp.getBreakpointSize();
      return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm';
    };

    Build.prototype.translateSidebar = function(e) {
      var newPosition = this.sidebarTranslationLimits.max - (document.body.scrollTop || document.documentElement.scrollTop);
      if (newPosition < this.sidebarTranslationLimits.min) newPosition = this.sidebarTranslationLimits.min;
      this.$sidebar.css({
        top: newPosition
      });
    };

    Build.prototype.toggleSidebar = function(shouldHide) {
      var shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined;
      this.$buildScroll.toggleClass('sidebar-expanded', shouldShow)
        .toggleClass('sidebar-collapsed', shouldHide);
      this.$sidebar.toggleClass('right-sidebar-expanded', shouldShow)
        .toggleClass('right-sidebar-collapsed', shouldHide);
    };

    Build.prototype.sidebarOnResize = function() {
      this.toggleSidebar(this.shouldHideSidebarForViewport());
    };

    Build.prototype.sidebarOnClick = function() {
      if (this.shouldHideSidebarForViewport()) this.toggleSidebar();
    };

    Build.prototype.updateArtifactRemoveDate = function() {
      var $date, date;
      $date = $('.js-artifacts-remove');
      if ($date.length) {
        date = $date.text();
        return $date.text(gl.utils.timeFor(new Date(date.replace(/([0-9]+)-([0-9]+)-([0-9]+)/g, '$1/$2/$3')), ' '));
      }
    };

    Build.prototype.populateJobs = function(stage) {
      $('.build-job').hide();
      $('.build-job[data-stage="' + stage + '"]').show();
    };

    Build.prototype.updateStageDropdownText = function(stage) {
      $('.stage-selection').text(stage);
    };

    Build.prototype.updateDropdown = function(e) {
      e.preventDefault();
      var stage = e.currentTarget.text;
      this.updateStageDropdownText(stage);
      this.populateJobs(stage);
    };

    Build.prototype.stepTrace = function(e) {
      var $currentTarget;
      e.preventDefault();
      $currentTarget = $(e.currentTarget);
      $.scrollTo($currentTarget.attr('href'), {
        offset: -($('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight())
      });
    };

    return Build;

  })();

}).call(this);
<|endoftext|>


<commit_before>/**
 * @since 2021-02-18 15:23
 * @author vivaxy
 * 2 ways of getting request header size
 * 1. bytesRead - previousBytesRead
 * 2. byteLength(socket.data)
 */
const http = require('http');
const { Buffer } = require('buffer');

const PORT = 3000;
const server = http.createServer(function (req, res) {
  const { socket } = req;
  const size = socket.bytesRead - (socket._lastBytesRead || 0);
  const responseText = `size: ${size} bytes`;
  console.log(responseText);
  res.end(responseText);
  socket._lastBytesRead = socket.bytesRead;
});

// server.on('connection', function (socket) {
//   let data = '';
//   socket.on('data', function (chunk) {
//     data += String(chunk);
//   });
//   socket.on('end', function () {
//     console.log('size', Buffer.byteLength(data));
//   });
// });

server.listen(PORT, function () {
  console.log(`server started on http://127.0.0.1:${PORT}`);
});
<commit_msg>feat: :sparkles: http request header size 增加 clientError 事件监听<commit_after>/**
 * @since 2021-02-18 15:23
 * @author vivaxy
 * 2 ways of getting request header size
 * 1. bytesRead - previousBytesRead
 * 2. byteLength(socket.data)
 */
const http = require('http');
const { Buffer } = require('buffer');

const PORT = 3000;
const server = http.createServer(function (req, res) {
  const { socket } = req;
  const size = socket.bytesRead - (socket._lastBytesRead || 0);
  const responseText = `size: ${size} bytes`;
  console.log(responseText);
  res.end(responseText);
  socket._lastBytesRead = socket.bytesRead;
});

server.on('clientError', function (err) {
  console.log('clientError', err);
});

// server.on('connection', function (socket) {
//   let data = '';
//   socket.on('data', function (chunk) {
//     data += String(chunk);
//   });
//   socket.on('end', function () {
//     console.log('size', Buffer.byteLength(data));
//   });
// });

server.listen(PORT, function () {
  console.log(`server started on http://127.0.0.1:${PORT}`);
});
<|endoftext|>


<commit_before>/**
 * @constructor
 * @arguments Backbone.Model
 */
var Parameter = Backbone.Model.extend({
    defaults: {
        name: null,
        view: null,
        value: undefined
    },

    initialize: function () {

    },

    onPropertyChanged: function (property, handler) {
        if (typeof property == 'function') {
            handler = property;
            this.on('onPropertyChanged', handler);
        } else {
            this.on('onPropertyChanged:' + property, handler);
        }

    },

    getName: function(){
        return this.get('name');
    },

    setName: function(newName){
        this.set('name', newName);
    },

    getView: function(){
        return this.get('view');
    },

    getValue: function(){
        return this.getProperty('');
    },

    setValue: function(value){
        this.setProperty('', value);
    },

    getProperty: function(property){
        var value = this.get('value');

        if (property == '') {
            return value;
        } else {
            return this._nullToUndefined (InfinniUI.ObjectUtils.getPropertyValue(value, property));
        }
    },

    setProperty: function(property, value){
        var fullParameterValue = this.getValue(),
            oldValue = this.getProperty(property);

        if(value == oldValue){
            return;
        }

        if (property == '') {
            this.set('value', value);

        } else {
            InfinniUI.ObjectUtils.setPropertyValue(fullParameterValue, property, value);
        }

        this._notifyAboutPropertyChanged(property, value, oldValue);
    },

    _notifyAboutPropertyChanged: function (property, newValue, oldValue) {
        var context = this._getContext(),
            argument = {};

        argument.property = property;
        argument.newValue = newValue;
        argument.oldValue = oldValue;

        this.trigger('onPropertyChanged', context, argument);
        this.trigger('onPropertyChanged:' + property, context, argument);
    },

    _getContext: function(){
        var view = this.getView();
        if(view){
            return view.getContext();
        }else{
            return undefined;
        }
    },

    _nullToUndefined: function(val){
        if(val === null){
            return undefined;
        }else{
            return val;
        }
    }
});

//{
//
//    var _name;
//    var _value;
//    var _bindings = [];
//
//    var notifyOnValueChanged = function () {
//        for(var i = 0; i < onValueChangedHandlers.length; i++){
//            //Уведомление от DataBinding об изменившемся значении
//            onValueChangedHandlers[i](null, _value);
//        }
//    };
//
//
//    /**
//     * @description Уведомить PropertyBinding об изменении значения
//     */
//    var notifyParameterBinding = function () {
//        for (var i = 0, ln = _bindings.length; i < ln; i = i + 1) {
//            _bindings[i].propertyValueChanged(_value);
//        }
//    };
//
//    this.getName = function(){
//        return _name;
//    };
//
//    this.setName = function(value){
//        _name = value;
//    };
//
//    this.getValue = function() {
//        return _value;
//    };
//
//    /**
//     * @description Установка значения из источника данных
//     * @param value
//     */
//    this.setValue = function(value){
//        if (_.isEqual(value, _value)) {
//            return;
//        }
//        _value = value;
//        notifyOnValueChanged();
//        notifyParameterBinding();
//    };
//
//    /**
//     *
//     * @param {ParameterBinding} binding
//     */
//    this.addDataBinding = function (binding) {
//        if (typeof binding === 'undefined' || binding === null) {
//            return;
//        }
//        //Подписка на изменение значения в элементе
//        binding.onSetPropertyValue(onSetPropertyValueHandler);
//        //Установка текущего значения
//        binding.propertyValueChanged(this.getValue());
//        _bindings.push(binding);
//    };
//
//    var onValueChangedHandlers = [];
//
//    this.onValueChanged = function(handler) {
//        onValueChangedHandlers.push(handler);
//    };
//
//    /**
//     * @description Обработчик изменения значения в элементе.
//     * Устанавливает значение в параметре
//     * @param context
//     * @param args
//     */
//    var onSetPropertyValueHandler = function (context, args) {
//        var propertyName = args.property;
//        var propertyValue = args.value;
//
//        if (propertyName !== undefined && propertyName !== null) {
//            InfinniUI.ObjectUtils.setPropertyValue(_value, propertyName, propertyValue);
//        } else {
//            _value = propertyValue;
//        }
//
//        //@TODO Сгенерировать событие для уведомления об изменении значения параметра
//    }
//}
<commit_msg>name property of parameters<commit_after>/**
 * @constructor
 * @arguments Backbone.Model
 */
var Parameter = Backbone.Model.extend({
    defaults: {
        name: null,
        view: null,
        value: undefined
    },

    initialize: function () {

    },

    onPropertyChanged: function (property, handler) {
        if (typeof property == 'function') {
            handler = property;
            this.on('onPropertyChanged', handler);
        } else {
            this.on('onPropertyChanged:' + property, handler);
        }

    },

    getName: function(){
        return this.get('name');
    },

    setName: function(newName){
        this.set('name', newName);
        this.name = newName;
    },

    getView: function(){
        return this.get('view');
    },

    getValue: function(){
        return this.getProperty('');
    },

    setValue: function(value){
        this.setProperty('', value);
    },

    getProperty: function(property){
        var value = this.get('value');

        if (property == '') {
            return value;
        } else {
            return this._nullToUndefined (InfinniUI.ObjectUtils.getPropertyValue(value, property));
        }
    },

    setProperty: function(property, value){
        var fullParameterValue = this.getValue(),
            oldValue = this.getProperty(property);

        if(value == oldValue){
            return;
        }

        if (property == '') {
            this.set('value', value);

        } else {
            InfinniUI.ObjectUtils.setPropertyValue(fullParameterValue, property, value);
        }

        this._notifyAboutPropertyChanged(property, value, oldValue);
    },

    _notifyAboutPropertyChanged: function (property, newValue, oldValue) {
        var context = this._getContext(),
            argument = {};

        argument.property = property;
        argument.newValue = newValue;
        argument.oldValue = oldValue;

        this.trigger('onPropertyChanged', context, argument);
        this.trigger('onPropertyChanged:' + property, context, argument);
    },

    _getContext: function(){
        var view = this.getView();
        if(view){
            return view.getContext();
        }else{
            return undefined;
        }
    },

    _nullToUndefined: function(val){
        if(val === null){
            return undefined;
        }else{
            return val;
        }
    }
});

//{
//
//    var _name;
//    var _value;
//    var _bindings = [];
//
//    var notifyOnValueChanged = function () {
//        for(var i = 0; i < onValueChangedHandlers.length; i++){
//            //Уведомление от DataBinding об изменившемся значении
//            onValueChangedHandlers[i](null, _value);
//        }
//    };
//
//
//    /**
//     * @description Уведомить PropertyBinding об изменении значения
//     */
//    var notifyParameterBinding = function () {
//        for (var i = 0, ln = _bindings.length; i < ln; i = i + 1) {
//            _bindings[i].propertyValueChanged(_value);
//        }
//    };
//
//    this.getName = function(){
//        return _name;
//    };
//
//    this.setName = function(value){
//        _name = value;
//    };
//
//    this.getValue = function() {
//        return _value;
//    };
//
//    /**
//     * @description Установка значения из источника данных
//     * @param value
//     */
//    this.setValue = function(value){
//        if (_.isEqual(value, _value)) {
//            return;
//        }
//        _value = value;
//        notifyOnValueChanged();
//        notifyParameterBinding();
//    };
//
//    /**
//     *
//     * @param {ParameterBinding} binding
//     */
//    this.addDataBinding = function (binding) {
//        if (typeof binding === 'undefined' || binding === null) {
//            return;
//        }
//        //Подписка на изменение значения в элементе
//        binding.onSetPropertyValue(onSetPropertyValueHandler);
//        //Установка текущего значения
//        binding.propertyValueChanged(this.getValue());
//        _bindings.push(binding);
//    };
//
//    var onValueChangedHandlers = [];
//
//    this.onValueChanged = function(handler) {
//        onValueChangedHandlers.push(handler);
//    };
//
//    /**
//     * @description Обработчик изменения значения в элементе.
//     * Устанавливает значение в параметре
//     * @param context
//     * @param args
//     */
//    var onSetPropertyValueHandler = function (context, args) {
//        var propertyName = args.property;
//        var propertyValue = args.value;
//
//        if (propertyName !== undefined && propertyName !== null) {
//            InfinniUI.ObjectUtils.setPropertyValue(_value, propertyName, propertyValue);
//        } else {
//            _value = propertyValue;
//        }
//
//        //@TODO Сгенерировать событие для уведомления об изменении значения параметра
//    }
//}
<|endoftext|>


<commit_before>var ws281x = require('../index.js');

var NUM_LEDS = parseInt(process.argv[2], 10) || 10,
    pixelData = new Uint32Array(NUM_LEDS);

ws281x.init(NUM_LEDS);

ws281x.setIndexMapping(ws281x.indexMapping.mirrorMatrixX(10,10));

// ---- trap the SIGINT and reset before exit
process.on('SIGINT', function () {
  ws281x.reset();
  process.nextTick(function () { process.exit(0); });
});

// ---- animation-loop
var offset = 0;
setInterval(function () {
  var i=NUM_LEDS;
  while(i--) {
      pixelData[i] = 0;
  }
  pixelData[offset] = 0xffffff;

  offset = (offset + 1) % NUM_LEDS;
  ws281x.render(pixelData);
}, 100);

console.log('Press <ctrl>+C to exit.');
<commit_msg>Remove index mapping in example.<commit_after>var ws281x = require('../index.js');

var NUM_LEDS = parseInt(process.argv[2], 10) || 10,
    pixelData = new Uint32Array(NUM_LEDS);

ws281x.init(NUM_LEDS);

// ---- trap the SIGINT and reset before exit
process.on('SIGINT', function () {
  ws281x.reset();
  process.nextTick(function () { process.exit(0); });
});

// ---- animation-loop
var offset = 0;
setInterval(function () {
  var i=NUM_LEDS;
  while(i--) {
      pixelData[i] = 0;
  }
  pixelData[offset] = 0xffffff;

  offset = (offset + 1) % NUM_LEDS;
  ws281x.render(pixelData);
}, 100);

console.log('Press <ctrl>+C to exit.');
<|endoftext|>


<commit_before>function WalletSendAssetsController($modal, $scope, $http, $q, userService) {
 // [ Form Validation]

  $scope.showErrors = false;

  // [ Template Initialization ]

  $scope.currencyList = userService.getCurrencies(); // [{symbol: 'BTC', addresses:[], name: 'BTC'}, {symbol: 'MSC', addresses:[], name: 'MSC'}, {symbol: 'TMSC', addresses:[], name: 'TMSC'}]
  $scope.selectedCoin = $scope.currencyList[0].symbol;

  // Attach a listener for when the selected
    $scope.$watch( 'selectedCoin', function( newValue, oldValue ) {

    });

  function convertSatoshiToDisplayedValue( satoshi ) {
    if( $scope.selectedCoin == 'BTC' )
      return satoshi / 100000.0;
    else if( $scope.selectedCoin.indexOf( 'SP' ) == 0 )
    {
      for( var i in $scope.currencyList )
      {
        if( $scope.currencyList[i].symbol == $scope.selectedCoin )
        {
          if( $scope.currencyList[ i ].property_type == 1 )
            return satoshi;
          else
            return satoshi / 100000000.0;
        }
      }
      return satoshi / 100000000.0;
    }
    else
    {
      return satoshi / 100000000.0;
    }
  }

  $scope.convertSatoshiToDisplayedValue = convertSatoshiToDisplayedValue;

  function getDisplayedAbbreviation()
  {
    if( $scope.selectedCoin == 'BTC' )
      return 'mBTC';
    else if( $scope.selectedCoin.indexOf( 'SP' ) == 0 )
    {
      for( var i in $scope.currencyList )
      {
        if( $scope.currencyList[i].symbol == $scope.selectedCoin )
          return $scope.currencyList[i].name + ' #' + $scope.selectedCoin.match( /SP([0-9]+)/ )[1];
      }

      return 'Smart Property #' + $scope.selectedCoin.match( /SP([0-9]+)/ )[1];
    }
    else
      return $scope.selectedCoin;
  }
  $scope.getDisplayedAbbreviation = getDisplayedAbbreviation;

  function convertDisplayedValueToSatoshi( value ) {
    if( $scope.selectedCoin == 'BTC' )
    {
      return Math.ceil( value * 100000 );
    }
    else if( $scope.selectedCoin.indexOf( 'SP' ) == 0 )
    {
      for( var i in $scope.currencyList )
      {
        if( $scope.currencyList[i].symbol == $scope.selectedCoin )
        {
          if( $scope.currencyList[ i ].property_type == 1 )
            return Math.ceil( value );
          else
            return Math.ceil( value * 100000000 );
        }
      }
      return Math.ceil( value * 100000000 );
    }
    else
    {
      return Math.ceil( value * 100000000 );
    }
  }

  $scope.addressList = getAddressesWithPrivkey();
  $scope.selectedAddress = $scope.addressList[0];
  $scope.minerFees = formatCurrencyInFundamentalUnit(0.0001, 'wtom');

  function getAddressesWithPrivkey() {
    var addresses = [];
    userService.getAllAddresses().map(
      function(e,i,a) {
        if(e.privkey && e.privkey.length == 58) {
          addresses.push(e.address);
        }
      }
    );
    if( addresses.length == 0)
      addresses = ['Could not find any addresses with attached private keys!'];
    return addresses;
  }

  // [ Retrieve Balances ]
  $scope.balanceData = [ 0 ];
  var addrListBal = [];

  $scope.setBalance = function() {
    $scope.balanceData = [ 0 ];
    var coin = $scope.selectedCoin;
    var address = $scope.selectedAddress;
    if (address || coin) {
      for(var i = 0; i < addrListBal.length; i++) {
        if( addrListBal[i] && addrListBal[i].address == address) {
          for(var k = 0; k < addrListBal[i].balance.length; k++) {
            if(addrListBal[i].balance[k].symbol == coin) {
              $scope.balanceData[0] = addrListBal[i].balance[k].value;
              //console.log($scope.address, coin, $scope.balanceData, addrListBal[i].balance[k], k);
            }
            if(addrListBal[i].balance[k].symbol == 'BTC') {
              $scope.balanceData[1] = addrListBal[i].balance[k].value;
            }
          }
        }
      }
    }
  };

  $scope.addressList.forEach(function(e,i) {
     var promise = getAddressData(e);
     promise.then(function(successData) {
        var successData = successData.data;
        addrListBal[i] = { address: e, balance: successData.balance };
        $scope.setBalance();
     },function(errorData) {
       alert("We have encountered a problem accessing the server ... Please try again in a few minutes")
       //console.log('Error, no balance data found for ' + e + ' setting defaults...');
       var balances = [
          { symbol: 'MSC', value: '0' },
          { symbol: 'TMSC', value: '0' },
          { symbol: 'BTC', value: '0' } ];
       addrListBal[i] = { address: e, balance: balances };
     });
  });

  // [ Helper Functions ]

  function validAddress(addr) {
    try{
      var checkValid = new Bitcoin.Address(addr);
      return true;
    } catch(e) {
      return false;
    }
  }

  function getAddressData(address) {
    console.log( 'Addr request 5' );
    var promise = $http.post( '/v1/address/addr/', { 'addr': address });

    return promise;
  }

  function pushSignedTransaction(signedTransaction) {
    var url = '/v1/transaction/pushtx/';
    var data = { signedTransaction: signedTransaction };
    var promise = $http.post( url, data );
    return promise;
  }

  // [ Send Form Helpers ]

  function getUnsignedSendTransaction(toAddress, pubKey, fromAddress, amount, currency, fee) {
    var url = '/v1/transaction/send/';
    var data = {
      from_address: fromAddress,
      to_address: toAddress,
      amount: amount,
      currency: currency,
      fee: fee,
      marker: $scope.marked,
      pubKey: pubKey
    };
    var promise = $http.post( url, data );

    return promise;
  }

  function prepareSendTransaction(to, from, amt, currency, fee, privkeyphrase, $modalScope) {
    var addressData = userService.getAddress(from);
    var privKey = new Bitcoin.ECKey.decodeEncryptedFormat(addressData.privkey, addressData.address); // Using address as temporary password
    var pubKey = privKey.getPubKeyHex();

    $scope.sendTxPromise = getUnsignedSendTransaction(to, pubKey, from, amt, currency, fee);
    $scope.sendTxPromise.then(function(successData) {

      if( successData.data.error )
      {
        $modalScope.waiting = false;
        $modalScope.sendError = true;
        $modalScope.error = 'Error preparing send transaction: ' + successData.data.error;
      }
      else
      {
        var successData = successData.data;
        var sourceScript = successData.sourceScript;
        var unsignedTransaction = successData.transaction;

        try {
          var bytes = Bitcoin.Util.hexToBytes(unsignedTransaction);
          var transaction = Bitcoin.Transaction.deserialize(bytes);
          var script = parseScript(successData.sourceScript);

          transaction.ins.forEach( function( input ) {
            input.script = script;
          } );

          //DEBUG console.log('before',transaction, Bitcoin.Util.bytesToHex(transaction.serialize()));
          var signedSuccess = transaction.signWithKey(privKey);

          var finalTransaction = Bitcoin.Util.bytesToHex(transaction.serialize());

          //Showing the user the transaction hash doesn't work right now
          //var transactionHash = Bitcoin.Util.bytesToHex(transaction.getHash().reverse());

          pushSignedTransaction(finalTransaction).then(function(successData) {
            var successData = successData.data;
            if( successData.pushed.match(/submitted|success/gi) != null ) {
              $modalScope.waiting = false;
              $modalScope.sendSuccess = true;
              $modalScope.url = 'http://blockchain.info/address/' + from + '?sort=0';
            } else {
              $modalScope.waiting = false;
              $modalScope.sendError = true;
              $modalScope.error = successData.pushed;  //Unspecified error, show user
            }
          },function(errorData) {
            $modalScope.waiting = false;
            $modalScope.sendError = true;
            if( errorData.message )
              $modalScope.error = 'Server error: ' + errorData.message;
            else if( errorData.data )
                $modalScope.error = 'Server error: ' + errorData.data;
            else
              $modalScope.error = 'Unknown Server Error';
              console.error( errorData );
          });

          //DEBUG console.log(addressData, privKey, bytes, transaction, script, signedSuccess, finalTransaction );
          function parseScript (script) {
                var newScript = new Bitcoin.Script();
                var s = script.split(" ");
                for (var i = 0; i < s.length; i++) {
                    if (Bitcoin.Opcode.map.hasOwnProperty(s[i])) {
                        newScript.writeOp(Bitcoin.Opcode.map[s[i]]);
                    } else {
                        newScript.writeBytes(Bitcoin.Util.hexToBytes(s[i]));
                    }
                }
                return newScript;
         }
        } catch(e) {
          $modalScope.sendError = true;
          if( e.message )
            $modalScope.error = 'Error sending transaction: ' + e.message;
          else if( e.data )
            $modalScope.error = 'Error sending transaction: ' + e.data;
          else
            $modalScope.error = 'Unknown error sending transaction';
          console.error( e );
        }
      }
    },function(errorData) {
      $modalScope.sendError = true;
      if( errorData.message )
        $modalScope.error = 'Server error: ' + errorData.message;
      else if( errorData.data )
          $modalScope.error = 'Server error: ' + errorData.data;
      else
        $modalScope.error = 'Unknown Server Error';
      console.error( errorData );
    });
  }

  $scope.validateSendForm = function() {
    var dustValue = 5430;
    var minerMinimum = 10000;
    var nonZeroValue = 1;

    var minerFees = Math.ceil( $scope.minerFees * 100000 );
    var sendAmount = convertDisplayedValueToSatoshi( $scope.sendAmount );

    var balance = +$scope.balanceData[0];
    var btcbalance = +$scope.balanceData[1];

    var coin = $scope.selectedCoin;
    var address = $scope.selectedAddress;
    var sendTo = $scope.sendTo
    var required = [coin,address,sendAmount,sendTo, minerFees,balance, btcbalance, $scope.sendForm.$valid ];

    var error = 'Please ';
    if( $scope.sendForm.$valid == false) {
        error += 'make sure all fields are completely filled, ';
    }
    if( ( sendAmount <= balance ) == false ) {
        error += 'make sure you aren\'t sending more coins than you own, ';
    }
    if( ( minerFees <= btcbalance ) ==  false ) {
        error += 'make sure you have enough Bitcoin to cover your fees, ';
    }
    if( validAddress(sendTo) == false) {
       error += 'make sure you are sending to a valid MSC/BTC address, ';
    }
    if(coin == 'BTC') {
       if( sendAmount < dustValue )
        error += 'make sure your send amount is at least 0.05430 mBTC if sending BTC, ';
       if( minerFees < minerMinimum )
        error += 'make sure your fee entry is at least 0.1 mBTC to cover miner costs, ';
    }
    if( ( (coin == 'MSC') || (coin == 'TMSC') ) ) {
       if( sendAmount < nonZeroValue )
        error += 'make sure your send amount is non-zero, ';
       if( minerFees < minerMinimum )
        error += 'make sure your fee entry is at least 0.1 mBTC, ';
    }
    if( error.length < 8) {
      $scope.showErrors = false;
      // open modal
      var modalInstance = $modal.open({
        template: '\

\

 Confirm send
\

You\'re about to send ' + convertSatoshiToDisplayedValue( sendAmount ) + ' ' + getDisplayedAbbreviation() +
              ' plus ' + $scope.minerFees + ' mBTC in fees to ' + $scope.sendTo + '
\

\
            If the above is correct, please press Send Funds.\
            If you encounter an error, feel free to click away from the dialog and try again.\

\

\

\
              <button ng-disabled="clicked" class="btn btn-primary" ng-click="ok()">Yes, send my funds</button>\
              \

\

\

\

\

 Funds were sent successfully, \
                  check your transaction here.
\

\

\

 Funds could not be sent: \
                   {{error}}
\

\

\

\
        ',
        controller: function($scope,$rootScope, userService,data, prepareSendTransaction, getUnsignedSendTransaction){
          $scope.sendSuccess = false, $scope.sendError = false, $scope.waiting = false, $scope.privKeyPass = {};
          $scope.ok = function() {
            $scope.clicked = true;
            $scope.waiting = true;
            prepareSendTransaction(data.sendTo, data.sendFrom, data.amt, data.coin, data.fee, $scope.privKeyPass, $scope);
          }
        },
        resolve: {
          data:function(){
            return {
              sendTo: sendTo,
              sendFrom: address,
              amt: sendAmount,
              coin: coin,
              fee: minerFees }
          },
          prepareSendTransaction: function() {
            return prepareSendTransaction;
          },
          getUnsignedSendTransaction: function() {
            return getUnsignedSendTransaction;
          },
          pushSignedTransaction: function() {
            return pushSignedTransaction;
          }
        }
      });
    } else {
      error += 'and try again.';
      $scope.error = error;
      $scope.showErrors = true;
    }
  };
}

<commit_msg>Format commit for WalletSendAssetsController.js, no errors found.<commit_after>function WalletSendAssetsController($modal, $scope, $http, $q, userService) {
  // [ Form Validation]

  $scope.showErrors = false;

  // [ Template Initialization ]

  $scope.currencyList = userService.getCurrencies(); // [{symbol: 'BTC', addresses:[], name: 'BTC'}, {symbol: 'MSC', addresses:[], name: 'MSC'}, {symbol: 'TMSC', addresses:[], name: 'TMSC'}]
  $scope.selectedCoin = $scope.currencyList[0].symbol;

  // Attach a listener for when the selected
  $scope.$watch('selectedCoin', function(newValue, oldValue) {});

  function convertSatoshiToDisplayedValue(satoshi) {
    if ($scope.selectedCoin == 'BTC')
      return satoshi / 100000.0;
    else if ($scope.selectedCoin.indexOf('SP') == 0) {
      for (var i in $scope.currencyList) {
        if ($scope.currencyList[i].symbol == $scope.selectedCoin) {
          if ($scope.currencyList[i].property_type == 1)
            return satoshi;
          else
            return satoshi / 100000000.0;
        }
      }
      return satoshi / 100000000.0;
    } else {
      return satoshi / 100000000.0;
    }
  }

  $scope.convertSatoshiToDisplayedValue = convertSatoshiToDisplayedValue;

  function getDisplayedAbbreviation() {
    if ($scope.selectedCoin == 'BTC')
      return 'mBTC';
    else if ($scope.selectedCoin.indexOf('SP') == 0) {
      for (var i in $scope.currencyList) {
        if ($scope.currencyList[i].symbol == $scope.selectedCoin)
          return $scope.currencyList[i].name + ' #' + $scope.selectedCoin.match(/SP([0-9]+)/)[1];
      }

      return 'Smart Property #' + $scope.selectedCoin.match(/SP([0-9]+)/)[1];
    }
    else
      return $scope.selectedCoin;
  }
  $scope.getDisplayedAbbreviation = getDisplayedAbbreviation;

  function convertDisplayedValueToSatoshi(value) {
    if ($scope.selectedCoin == 'BTC') {
      return Math.ceil(value * 100000);
    } else if ($scope.selectedCoin.indexOf('SP') == 0) {
      for (var i in $scope.currencyList) {
        if ($scope.currencyList[i].symbol == $scope.selectedCoin) {
          if ($scope.currencyList[i].property_type == 1)
            return Math.ceil(value);
          else
            return Math.ceil(value * 100000000);
        }
      }
      return Math.ceil(value * 100000000);
    } else {
      return Math.ceil(value * 100000000);
    }
  }

  $scope.addressList = getAddressesWithPrivkey();
  $scope.selectedAddress = $scope.addressList[0];
  $scope.minerFees = formatCurrencyInFundamentalUnit(0.0001, 'wtom');

  function getAddressesWithPrivkey() {
    var addresses = [];
    userService.getAllAddresses().map(function(e, i, a) {
      if (e.privkey && e.privkey.length == 58) {
        addresses.push(e.address);
      }
    }
    );
    if (addresses.length == 0)
      addresses = ['Could not find any addresses with attached private keys!'];
    return addresses;
  }

  // [ Retrieve Balances ]
  $scope.balanceData = [0];
  var addrListBal = [];

  $scope.setBalance = function() {
    $scope.balanceData = [0];
    var coin = $scope.selectedCoin;
    var address = $scope.selectedAddress;
    if (address || coin) {
      for (var i = 0; i < addrListBal.length; i++) {
        if (addrListBal[i] && addrListBal[i].address == address) {
          for (var k = 0; k < addrListBal[i].balance.length; k++) {
            if (addrListBal[i].balance[k].symbol == coin) {
              $scope.balanceData[0] = addrListBal[i].balance[k].value;
              //console.log($scope.address, coin, $scope.balanceData, addrListBal[i].balance[k], k);
            }
            if (addrListBal[i].balance[k].symbol == 'BTC') {
              $scope.balanceData[1] = addrListBal[i].balance[k].value;
            }
          }
        }
      }
    }
  };

  $scope.addressList.forEach(function(e, i) {
    var promise = getAddressData(e);
    promise.then(function(successData) {
      var successData = successData.data;
      addrListBal[i] = {
        address: e,
        balance: successData.balance
      };
      $scope.setBalance();
    }, function(errorData) {
      alert("We have encountered a problem accessing the server ... Please try again in a few minutes")
      //console.log('Error, no balance data found for ' + e + ' setting defaults...');
      var balances = [
        {
          symbol: 'MSC',
          value: '0'
        },
        {
          symbol: 'TMSC',
          value: '0'
        },
        {
          symbol: 'BTC',
          value: '0'
        }];
      addrListBal[i] = {
        address: e,
        balance: balances
      };
    });
  });

  // [ Helper Functions ]

  function validAddress(addr) {
    try {
      var checkValid = new Bitcoin.Address(addr);
      return true;
    } catch (e) {
      return false;
    }
  }

  function getAddressData(address) {
    console.log('Addr request 5');
    var promise = $http.post('/v1/address/addr/', {
      'addr': address
    });

    return promise;
  }

  function pushSignedTransaction(signedTransaction) {
    var url = '/v1/transaction/pushtx/';
    var data = {
      signedTransaction: signedTransaction
    };
    var promise = $http.post(url, data);
    return promise;
  }

  // [ Send Form Helpers ]

  function getUnsignedSendTransaction(toAddress, pubKey, fromAddress, amount, currency, fee) {
    var url = '/v1/transaction/send/';
    var data = {
      from_address: fromAddress,
      to_address: toAddress,
      amount: amount,
      currency: currency,
      fee: fee,
      marker: $scope.marked,
      pubKey: pubKey
    };
    var promise = $http.post(url, data);

    return promise;
  }

  function prepareSendTransaction(to, from, amt, currency, fee, privkeyphrase, $modalScope) {
    var addressData = userService.getAddress(from);
    var privKey = new Bitcoin.ECKey.decodeEncryptedFormat(addressData.privkey, addressData.address); // Using address as temporary password
    var pubKey = privKey.getPubKeyHex();

    $scope.sendTxPromise = getUnsignedSendTransaction(to, pubKey, from, amt, currency, fee);
    $scope.sendTxPromise.then(function(successData) {

      if (successData.data.error) {
        $modalScope.waiting = false;
        $modalScope.sendError = true;
        $modalScope.error = 'Error preparing send transaction: ' + successData.data.error;
      } else {
        var successData = successData.data;
        var sourceScript = successData.sourceScript;
        var unsignedTransaction = successData.transaction;

        try {
          var bytes = Bitcoin.Util.hexToBytes(unsignedTransaction);
          var transaction = Bitcoin.Transaction.deserialize(bytes);
          var script = parseScript(successData.sourceScript);

          transaction.ins.forEach(function(input) {
            input.script = script;
          });

          //DEBUG console.log('before',transaction, Bitcoin.Util.bytesToHex(transaction.serialize()));
          var signedSuccess = transaction.signWithKey(privKey);

          var finalTransaction = Bitcoin.Util.bytesToHex(transaction.serialize());

          //Showing the user the transaction hash doesn't work right now
          //var transactionHash = Bitcoin.Util.bytesToHex(transaction.getHash().reverse());

          pushSignedTransaction(finalTransaction).then(function(successData) {
            var successData = successData.data;
            if (successData.pushed.match(/submitted|success/gi) != null) {
              $modalScope.waiting = false;
              $modalScope.sendSuccess = true;
              $modalScope.url = 'http://blockchain.info/address/' + from + '?sort=0';
            } else {
              $modalScope.waiting = false;
              $modalScope.sendError = true;
              $modalScope.error = successData.pushed; //Unspecified error, show user
            }
          }, function(errorData) {
            $modalScope.waiting = false;
            $modalScope.sendError = true;
            if (errorData.message)
              $modalScope.error = 'Server error: ' + errorData.message;
            else
              if (errorData.data)
                $modalScope.error = 'Server error: ' + errorData.data;
              else
                $modalScope.error = 'Unknown Server Error';
            console.error(errorData);
          });

          //DEBUG console.log(addressData, privKey, bytes, transaction, script, signedSuccess, finalTransaction );
          function parseScript(script) {
            var newScript = new Bitcoin.Script();
            var s = script.split(" ");
            for (var i = 0; i < s.length; i++) {
              if (Bitcoin.Opcode.map.hasOwnProperty(s[i])) {
                newScript.writeOp(Bitcoin.Opcode.map[s[i]]);
              } else {
                newScript.writeBytes(Bitcoin.Util.hexToBytes(s[i]));
              }
            }
            return newScript;
          }
        } catch (e) {
          $modalScope.sendError = true;
          if (e.message)
            $modalScope.error = 'Error sending transaction: ' + e.message;
          else
            if (e.data)
              $modalScope.error = 'Error sending transaction: ' + e.data;
            else
              $modalScope.error = 'Unknown error sending transaction';
          console.error(e);
        }
      }
    }, function(errorData) {
      $modalScope.sendError = true;
      if (errorData.message)
        $modalScope.error = 'Server error: ' + errorData.message;
      else
        if (errorData.data)
          $modalScope.error = 'Server error: ' + errorData.data;
        else
          $modalScope.error = 'Unknown Server Error';
      console.error(errorData);
    });
  }

  $scope.validateSendForm = function() {
    var dustValue = 5430;
    var minerMinimum = 10000;
    var nonZeroValue = 1;

    var minerFees = Math.ceil($scope.minerFees * 100000);
    var sendAmount = convertDisplayedValueToSatoshi($scope.sendAmount);

    var balance = +$scope.balanceData[0];
    var btcbalance = +$scope.balanceData[1];

    var coin = $scope.selectedCoin;
    var address = $scope.selectedAddress;
    var sendTo = $scope.sendTo
    var required = [coin, address, sendAmount, sendTo, minerFees, balance, btcbalance, $scope.sendForm.$valid];

    var error = 'Please ';
    if ($scope.sendForm.$valid == false) {
      error += 'make sure all fields are completely filled, ';
    }
    if ((sendAmount <= balance) == false) {
      error += 'make sure you aren\'t sending more coins than you own, ';
    }
    if ((minerFees <= btcbalance) == false) {
      error += 'make sure you have enough Bitcoin to cover your fees, ';
    }
    if (validAddress(sendTo) == false) {
      error += 'make sure you are sending to a valid MSC/BTC address, ';
    }
    if (coin == 'BTC') {
      if (sendAmount < dustValue)
        error += 'make sure your send amount is at least 0.05430 mBTC if sending BTC, ';
      if (minerFees < minerMinimum)
        error += 'make sure your fee entry is at least 0.1 mBTC to cover miner costs, ';
    }
    if( ((coin == 'MSC') || (coin == 'TMSC')) ) {
      if (sendAmount < nonZeroValue)
        error += 'make sure your send amount is non-zero, ';
      if (minerFees < minerMinimum)
        error += 'make sure your fee entry is at least 0.1 mBTC, ';
    }
    if (error.length < 8) {
      $scope.showErrors = false;
      // open modal
      var modalInstance = $modal.open({
        template: '\

\

 Confirm send
\

You\'re about to send ' + convertSatoshiToDisplayedValue(sendAmount) + ' ' + getDisplayedAbbreviation() +
                ' plus ' + $scope.minerFees + ' mBTC in fees to ' + $scope.sendTo + '
\

\
            If the above is correct, please press Send Funds.\
            If you encounter an error, feel free to click away from the dialog and try again.\

\

\

\
              <button ng-disabled="clicked" class="btn btn-primary" ng-click="ok()">Yes, send my funds</button>\
              \

\

\

\

\

 Funds were sent successfully, \
                  check your transaction here.
\

\

\

 Funds could not be sent: \
                   {{error}}
\

\

\

\
        ',
        controller: function($scope, $rootScope, userService, data, prepareSendTransaction, getUnsignedSendTransaction) {
          $scope.sendSuccess = false, $scope.sendError = false, $scope.waiting = false, $scope.privKeyPass = {};
          $scope.ok = function() {
            $scope.clicked = true;
            $scope.waiting = true;
            prepareSendTransaction(data.sendTo, data.sendFrom, data.amt, data.coin, data.fee, $scope.privKeyPass, $scope);
          }
        },
        resolve: {
          data: function() {
            return {
              sendTo: sendTo,
              sendFrom: address,
              amt: sendAmount,
              coin: coin,
              fee: minerFees
            }
          },
          prepareSendTransaction: function() {
            return prepareSendTransaction;
          },
          getUnsignedSendTransaction: function() {
            return getUnsignedSendTransaction;
          },
          pushSignedTransaction: function() {
            return pushSignedTransaction;
          }
        }
      });
    } else {
      error += 'and try again.';
      $scope.error = error;
      $scope.showErrors = true;
    }
  };
}

<|endoftext|>