<commit_before>(function(){

  angular
       .module('users')
       .controller('UserController', [
          'userService', '$mdSidenav', '$mdBottomSheet', '$log', '$http', '$q',
          UserController
       ]);

  /**
   * Main Controller for the Angular Material Starter App
   * @param $scope
   * @param $mdSidenav
   * @param avatarsService
   * @constructor
   */
  function UserController( userService, $mdSidenav, $mdBottomSheet, $log, $http) {
    var self = this;
//    $http.defaults.headers.common['Access-Control-Allow-Headers'] = 'Content-Type';
//    $http.defaults.headers.common['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS';
//    $http.defaults.headers.common['Access-Control-Allow-Origin'] = '*';

//    console.log($http.defaults.headers);

    var Web3 = require('web3');
    var web3 = new Web3();

    console.log(web3);

    web3.setProvider(new web3.providers.HttpProvider("http://104.154.21.38:8545"));
    web3.eth.defaultAccount = web3.eth.coinbase;

    self.selected     = null;
    self.users        = [ ];
    self.selectUser   = selectUser;
    self.toggleList   = toggleUsersList;
    self.makeContact  = makeContact;
    self.borrowerSubmit = borrowerSubmit;

    // Load all registered users

    userService
          .loadAllUsers()
          .then( function( users ) {
            self.users    = [].concat(users);
            self.selected = users[0];
          });

    // *********************************
    // Internal methods
    // *********************************

    /**
     * Hide or Show the 'left' sideNav area
     */
    function toggleUsersList() {
      $mdSidenav('left').toggle();
    }

    /**
     * Select the current avatars
     * @param menuId
     */
    function selectUser ( user ) {
      self.selected = angular.isNumber(user) ? $scope.users[user] : user;
    }

    /**
     * Show the Contact view in the bottom sheet
     */
    function makeContact(selectedUser) {

        $mdBottomSheet.show({
          controllerAs  : "cp",
          templateUrl   : './src/users/view/contactSheet.html',
          controller    : [ '$mdBottomSheet', ContactSheetController],
          parent        : angular.element(document.getElementById('content'))
        }).then(function(clickedItem) {
          $log.debug( clickedItem.name + ' clicked!');
        });

        /**
         * User ContactSheet controller
         */
        function ContactSheetController( $mdBottomSheet ) {
          this.user = selectedUser;
          this.actions = [
            { name: 'Phone'       , icon: 'phone'       , icon_url: 'assets/svg/phone.svg'},
            { name: 'Twitter'     , icon: 'twitter'     , icon_url: 'assets/svg/twitter.svg'},
            { name: 'Google+'     , icon: 'google_plus' , icon_url: 'assets/svg/google_plus.svg'},
            { name: 'Hangout'     , icon: 'hangouts'    , icon_url: 'assets/svg/hangouts.svg'}
          ];
          this.contactUser = function(action) {
            // The actually contact process has not been implemented...
            // so just hide the bottomSheet

            $mdBottomSheet.hide(action);
          };
        }
    }

    function borrowerSubmit() {
        var borrower = self.selected
        $log.debug('inside borrowerSubmit. borrower=' + borrower.name)

        var _email = borrower.email;
        var _credit_score = borrower.credit_score;
        var _amount = borrower.borrow_amount;
        var borrowerContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"getState","outputs":[{"name":"_state_email","type":"bytes"},{"name":"_state_credit_score","type":"uint8"},{"name":"_state_amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"_email","type":"bytes"},{"name":"_credit_score","type":"uint8"},{"name":"_amount","type":"uint256"}],"type":"constructor"}]);
        var borrower = borrowerContract.new(
          _email,
          _credit_score,
          _amount,
          {
            from: web3.eth.accounts[0],
            data: '60606040526040516102ba3803806102ba833981016040528080518201919060200180519060200190919080519060200190919050505b81600160006101000a81548160ff021916908302179055508260006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061009d57805160ff19168380011785556100ce565b828001600101855582156100ce579182015b828111156100cd5782518260005055916020019190600101906100af565b5b5090506100f991906100db565b808211156100f557600081815060009055506001016100db565b5090565b5050806002600050819055505b5050506101a3806101176000396000f360606040526000357c0100000000000000000000000000000000000000000000000000000000900480631865c57d1461003957610037565b005b61004660048050506100c5565b60405180806020018460ff1681526020018381526020018281038252858181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156100b55780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b60206040519081016040528060008152602001506000600060006000508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101765780601f1061014b57610100808354040283529160200191610176565b820191906000526020600020905b81548152906001019060200180831161015957829003601f168201915b505050505092508250600160009054906101000a900460ff1691508150600260005054905080505b90919256',
            gas: 3000000
          }, function(e, contract){
           console.log(e, contract);
           if (typeof contract.address != 'undefined') {
                console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
           }
        })
    }

  }

})();
<commit_msg>alert 'borrower is created' message<commit_after>(function(){

  angular
       .module('users')
       .controller('UserController', [
          'userService', '$mdSidenav', '$mdBottomSheet', '$log', '$http', '$q',
          UserController
       ]);

  /**
   * Main Controller for the Angular Material Starter App
   * @param $scope
   * @param $mdSidenav
   * @param avatarsService
   * @constructor
   */
  function UserController( userService, $mdSidenav, $mdBottomSheet, $log, $http) {
    var self = this;
//    $http.defaults.headers.common['Access-Control-Allow-Headers'] = 'Content-Type';
//    $http.defaults.headers.common['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS';
//    $http.defaults.headers.common['Access-Control-Allow-Origin'] = '*';

//    console.log($http.defaults.headers);

    var Web3 = require('web3');
    var web3 = new Web3();

    console.log(web3);

    web3.setProvider(new web3.providers.HttpProvider("http://104.154.21.38:8545"));
    web3.eth.defaultAccount = web3.eth.coinbase;

    self.selected     = null;
    self.users        = [ ];
    self.selectUser   = selectUser;
    self.toggleList   = toggleUsersList;
    self.makeContact  = makeContact;
    self.borrowerSubmit = borrowerSubmit;

    // Load all registered users

    userService
          .loadAllUsers()
          .then( function( users ) {
            self.users    = [].concat(users);
            self.selected = users[0];
          });

    // *********************************
    // Internal methods
    // *********************************

    /**
     * Hide or Show the 'left' sideNav area
     */
    function toggleUsersList() {
      $mdSidenav('left').toggle();
    }

    /**
     * Select the current avatars
     * @param menuId
     */
    function selectUser ( user ) {
      self.selected = angular.isNumber(user) ? $scope.users[user] : user;
    }

    /**
     * Show the Contact view in the bottom sheet
     */
    function makeContact(selectedUser) {

        $mdBottomSheet.show({
          controllerAs  : "cp",
          templateUrl   : './src/users/view/contactSheet.html',
          controller    : [ '$mdBottomSheet', ContactSheetController],
          parent        : angular.element(document.getElementById('content'))
        }).then(function(clickedItem) {
          $log.debug( clickedItem.name + ' clicked!');
        });

        /**
         * User ContactSheet controller
         */
        function ContactSheetController( $mdBottomSheet ) {
          this.user = selectedUser;
          this.actions = [
            { name: 'Phone'       , icon: 'phone'       , icon_url: 'assets/svg/phone.svg'},
            { name: 'Twitter'     , icon: 'twitter'     , icon_url: 'assets/svg/twitter.svg'},
            { name: 'Google+'     , icon: 'google_plus' , icon_url: 'assets/svg/google_plus.svg'},
            { name: 'Hangout'     , icon: 'hangouts'    , icon_url: 'assets/svg/hangouts.svg'}
          ];
          this.contactUser = function(action) {
            // The actually contact process has not been implemented...
            // so just hide the bottomSheet

            $mdBottomSheet.hide(action);
          };
        }
    }

    function borrowerSubmit() {
        var borrower = self.selected
        $log.debug('inside borrowerSubmit. borrower=' + borrower.name)

        var _email = borrower.email;
        var _credit_score = borrower.credit_score;
        var _amount = borrower.borrow_amount;
        var borrowerContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"getState","outputs":[{"name":"_state_email","type":"bytes"},{"name":"_state_credit_score","type":"uint8"},{"name":"_state_amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"_email","type":"bytes"},{"name":"_credit_score","type":"uint8"},{"name":"_amount","type":"uint256"}],"type":"constructor"}]);
        var borrower = borrowerContract.new(
          _email,
          _credit_score,
          _amount,
          {
            from: web3.eth.accounts[0],
            data: '60606040526040516102ba3803806102ba833981016040528080518201919060200180519060200190919080519060200190919050505b81600160006101000a81548160ff021916908302179055508260006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061009d57805160ff19168380011785556100ce565b828001600101855582156100ce579182015b828111156100cd5782518260005055916020019190600101906100af565b5b5090506100f991906100db565b808211156100f557600081815060009055506001016100db565b5090565b5050806002600050819055505b5050506101a3806101176000396000f360606040526000357c0100000000000000000000000000000000000000000000000000000000900480631865c57d1461003957610037565b005b61004660048050506100c5565b60405180806020018460ff1681526020018381526020018281038252858181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156100b55780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b60206040519081016040528060008152602001506000600060006000508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101765780601f1061014b57610100808354040283529160200191610176565b820191906000526020600020905b81548152906001019060200180831161015957829003601f168201915b505050505092508250600160009054906101000a900460ff1691508150600260005054905080505b90919256',
            gas: 3000000
          }, function(e, contract){
           console.log(e, contract);
           if (typeof contract.address != 'undefined') {
                console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
                alert('Borrower is successfully created!');
           }
        })
    }

  }

})();
<|endoftext|>


<commit_before>"use strict";

$(function() {

    // set time zone name
    $("input[name='tz_name']").val(jstz.determine().name());

    var start = 0,
        end = 0,
        total = 0,
        canSearch = true,
        searchBtn = $("#search"),
        searchBtnAdv = $("#search-adv"),
        dateReq = $("#date-req"),
        noResultsFound = true,
        generateDocBtn = $("#generate-document"),
        agencySelect = $("#agency_ein"),
        agencyUserDiv = $("#agency-user-div"),
        agencyUserSelect = $("#agency_user"),
        resultsHeader = "resultsHeading";

    //Table head values
    var resultcol = [
            ['Status',''],
            ['ID',''],
            ['Date Submitted', 'sort_date_submitted','desc'],
            ['Title', 'sort_title','none'],
            ['Assigned Agency', ''],
            ['Date Due','sort_date_due','none']
    ];
    var sortSequence = ["none", "desc", "asc"];

    // Date stuff
    function dateInvalid(dateElem, msg, highlightDateRequirement) {
        dateElem
            .addClass("bad-input-text")
            .attr('data-content', msg)
            .popover(msg === null ? 'hide' : 'show');
        if (highlightDateRequirement) {
            dateReq.css("display", "block");
        }
        return false;
    }

    function dateValid(dateElem) {
        dateElem
            .removeClass("bad-input-text")
            .popover('hide');
        return true;
    }

    function valiDate(checkDateElem, compDateElem, isLessThan) {
        /*
        * Check that 'checkDateElem' holds an empty value or
        * that it is not a holiday or weekend and
        * that it 'isLessThan' (or greater than if 'isLessThan' == false)
        * compDateElem and style accordingly.
        * */
        if (checkDateElem.val()) {
            if (checkDateElem.val().length === 10) {
                var compDate = null;
                if (compDateElem.val().length === 10) {
                    try {
                        compDate = new Date(compDateElem.val());
                    }
                    catch (err) {
                        compDate = null;
                    }
                }
                try {
                    var checkDate = new Date(checkDateElem.val());
                    var validComp = compDate !== null ?
                        (isLessThan ? checkDate <= compDate : checkDate >= compDate) : true;
                    if (!notHolidayOrWeekend(checkDate, false)) {
                        return dateInvalid(checkDateElem, "This date does not fall on a business day.");
                    }
                    else if (!validComp) {
                        return dateInvalid(checkDateElem, null, true);
                    }
                    else {
                        return dateValid(checkDateElem);
                    }
                }
                catch (err) {
                    // failure parsing date string
                    return dateInvalid(checkDateElem, "This is not a valid date.");
                }
            }
            else {
                // missing full date string length
                return dateInvalid(checkDateElem, "This is not a valid date.");
            }
        }
        else {
            // empty value is valid (no filtering)
            return dateValid(checkDateElem);
        }
    }

    function valiDates(fromDateElem, toDateElem) {
        /*
        * Check that 'fromDateElem' is less than 'toDateElem'
        * and that both dates are not holidays or weekends.
        * */
        var fromValid = valiDate(fromDateElem, toDateElem, true),
            toValid = valiDate(toDateElem, fromDateElem, false);
        if (!fromValid || !toValid) {
            canSearch = false;
            searchBtn.attr("disabled", true);
            searchBtnAdv.attr("disabled", true);
            generateDocBtn.attr("disabled", true);
        }
        else {
            canSearch = true;
            searchBtn.attr("disabled", false);
            searchBtnAdv.attr("disabled", false);
            dateReq.css("display", "none");
            if (!noResultsFound) {
                generateDocBtn.attr("disabled", false);
            }
        }
    }

    var datepickerOptions = {
        dateFormat: "mm/dd/yy",
        daysOfWeekDisabled: [0, 6],
        beforeShowDay: notHolidayOrWeekend,
    };

    var dateRecFromElem = $("#date-rec-from");
    var dateRecToElem = $("#date-rec-to");
    var dateDueFromElem = $("#date-due-from");
    var dateDueToElem = $("#date-due-to");
    var dateClosedFromElem = $("#date-closed-from");
    var dateClosedToElem = $("#date-closed-to");

    var dates = [dateRecFromElem, dateRecToElem, dateDueFromElem, dateDueToElem, dateClosedFromElem, dateClosedToElem];
    for (var i = 0; i < dates.length; i++) {
        dates[i].datepicker(datepickerOptions);
        dates[i].mask("00/00/0000", {placeholder: "mm/dd/yyyy"});
    }
    dateRecFromElem.on("input change", function () {
        valiDates(dateRecFromElem, dateRecToElem);
    });
    dateRecToElem.on("input change", function () {
        valiDates(dateRecFromElem, dateRecToElem);
    });
    dateDueFromElem.on("input change", function () {
        valiDates(dateDueFromElem, dateDueToElem);
    });
    dateDueToElem.on("input change", function () {
        valiDates(dateDueFromElem, dateDueToElem);
    });
    dateClosedFromElem.on("input change", function () {
        valiDates(dateClosedFromElem, dateClosedToElem);
    });
    dateClosedToElem.on("input change", function () {
        valiDates(dateClosedFromElem, dateClosedToElem);
    });

    // keypress 'Enter' = click search button
    $("#search-section").keyup(function(e){
        if (canSearch && e.keyCode === 13) {
            searchBtn.click();
            searchBtnAdv.click();
        }
    });
    // but don't submit form (it is only used to generate results document)
    $("#search-form").on("keyup, keypress", function(e){
        var keyCode = e.keyCode || e.which;
        if (keyCode === 13) {
            e.preventDefault();
            searchBtn.click();
        }
    });

    // show test info
    // document.onkeypress = function (e) {
    //     var testInfo = $(".test-info");
    //     if (e.keyCode === 92) {
    //         if (testInfo.is(":visible")) {
    //             testInfo.hide();
    //         }
    //         else {
    //             testInfo.show();
    //         }
    //     }
    // };

    function buildResultsTable (theResults, count, total)
    {

        var theTable = "";
        theTable=theTable +'
';
        theTable=theTable + '
Displaying Results ' + (start + 1) + " - " + (start + count) + ' of ' + total + ' Results Found
';
        theTable=theTable + '

Request is:

Open=

Closed=
';
        // Activate for Agency view. A flag is needed to determine if view is active
        // if (agencyView) {
        //     theTable=theTable + '
In-progress=
';
        //     theTable=theTable + '
Soon=
';
        //     theTable=theTable + '
Overdue=
';
        // }
        theTable=theTable + '

';
        theTable=theTable + '

';
        theTable=theTable + buildResultsTableHead (resultcol, sortSequence);
        theTable=theTable + '

' + theResults + '

';
        return(theTable);
    }

    function buildResultsTableHead (col, sort){

        var tableHead = '';

        for (var i=0; i< col.length; i++){

            if (col[i][1] === '')
                {
                tableHead = tableHead + '' + col[i][0] + '	';
                }
            else
                {
                tableHead = tableHead + '<button type="button" class="sort-field" data-sort-order="' + col[i][2] +'" id="' + col[i][1] +'">' + col[i][0];
                var CurrentSort = $("input[name="+ col[i][1]+ "]").val();
                if (CurrentSort !=""){

                }
                tableHead = tableHead + '' +
                                        'Unsorted' +
                                        '' +
                                        'Sorted, Ascending' +
                                        '' +
                                        'Sorted, Descending </button>	';
            }
        }
        return tableHead;
    }

    var next = $("#next");
    var prev = $("#prev");

    function search() {

        // first clear out any "bad" input
        $(".bad-input-text").removeClass("bad-input-text").val("");

        var results = $("#results");
        var pageInfo = $("#page-info");

        $.ajax({
            url: "/search/requests",
            data: $("#search-form").serializeArray(),
            success: function(data) {
                if (data.total !== 0) {
                    noResultsFound = false;
                    results.html(buildResultsTable(data.results, data.count, data.total));
                    flask_moment_render_all();
                    $(".pagination").css("display", "flex");
                    pageInfo.text(
                        (start + 1) + " - " +
                        (start + data.count) +
                        " of " + data.total
                    );
                    total = data.total;
                    end = start + data.count;
                    if (end === total) {
                        next.attr("aria-disabled", true);
                        next.addClass("disabled")
                    }
                    else {
                        next.attr("aria-disabled", false);
                        next.removeClass("disabled")
                    }
                    if (start === 0) {
                        prev.attr("aria-disabled", true);
                        prev.addClass("disabled")
                    }
                    else {
                        prev.attr("aria-disabled", false);
                        prev.removeClass("disabled")
                    }
                    generateDocBtn.attr("disabled", false);

                }
                else {
                    noResultsFound = true;
                    results.html("

" +
                          "
No results found.

");
                    generateDocBtn.attr("disabled", true);
                }
            },
            error: function(e) {
                results.html("

" +
                    "
Hmmmm.... Looks like something's gone wrong.

");
                generateDocBtn.attr("disabled", true);
            }
        });
    }

    // search on load
    $(document).ready(function(){
        search();

    });

    // disable other filters if searching by FOIL-ID
    $("input[name='foil_id']").click(function() {
        var query = $("#query");
        var names = ["title", "description", "agency_request_summary", "requester_name"];
        var i;
        if ($(this).prop("checked")) {
            query.attr("placeholder", "0000-000-00000");
            for (i = 0; i < names.length; i++) {
                $("input[name='" + names[i] + "']").prop("disabled", true);
            }
        }
        else {
            query.attr("placeholder", "Enter keywords");
            for (i = 0; i < names.length; i++) {
                $("input[name='" + names[i] + "']").prop("disabled", false);
            }
        }
    });

    function setStart(val) {
        start = val;
        $("input[name='start']").val(val);
    }

    // Sorting
    function updateSorting(theHeadingId,sequence){

        for (var i=0; i< resultcol.length; i++){

            if (resultcol[i][1] === theHeadingId){
                resultcol[i][2] = sequence;
                console.log (resultcol[i][2] + "--" + resultcol[i][1]);
            }
        }
    }

    function cycleSort(elem) {
        /*
        * Cycle through sortSequence and 'style' elem with arrows
        * glyphicons representing sort direction.
        * */

        elem.attr(
            "data-sort-order",
            sortSequence[
                (sortSequence.indexOf(elem.attr("data-sort-order")) + 1 + sortSequence.length)
                % sortSequence.length]);

    }

    function resetAndSearch() {
        if (canSearch) {
            setStart(0);
            search();
        }
    }

    generateDocBtn.click(function () {
        if (canSearch) {
            search();
        }
    });
    $(".status").click(function () {
        resetAndSearch();
    });
    searchBtn.click(function () {
        resetAndSearch();
        scrollToElement(resultsHeader);

    });
    searchBtnAdv.click(function () {
        resetAndSearch();
        scrollToElement(resultsHeader);

    });
    $("#size").change(function () {
        resetAndSearch();
    });

    agencySelect.change(function () {
        agencyUserSelect.empty();

        if (agencySelect.val()) {
            $.ajax({
                url: "/agency/api/v1.0/active_users/" + agencySelect.val(),
                statusCode: {
                    404: function () {
                        agencyUserDiv.hide();
                    }
                },
                success: function (data) {
                    // Populate users
                    $.each(data.active_users ,function() {
                        agencyUserSelect.append($("<option />").val(this[0]).text(this[1]));
                    });

                    // Set selected value for standard agency users
                    if (!data.is_admin) {
                        agencyUserSelect.val(data.active_users[1][0]);
                    }

                    agencyUserDiv.show();
                },
                // search after ajax call is complete so default value for standard user is selected
                complete: function () {
                    resetAndSearch();
                }
            });
        }
        else {
            agencyUserDiv.is(":visible") && agencyUserDiv.hide();
            resetAndSearch();
        }
    });
    agencyUserSelect.change(function () {
        resetAndSearch();
    });
    next.click(function () {
        event.preventDefault();
        if (canSearch && end < total) {
            setStart(start + parseInt($("#size").val()));
            $('html, body').stop();
            search();
            scrollToElement(resultsHeader);
        }

    });
    prev.click(function () {
        event.preventDefault();
        if (canSearch && start > 0) {
            setStart(start - parseInt($("#size").val()));
            $('html, body').stop();
            search();
            scrollToElement(resultsHeader);
        }

    });

    $('body').on('click', '.sort-field', function() {
        if (canSearch) {
            setStart(0);
            cycleSort($(this));

            // fill hidden inputs
            $("input[name='" + $(this).attr("id") + "']").val($(this).attr("data-sort-order"));

            //Update Array to reflect column status
            updateSorting($(this).attr("id"),$(this).attr("data-sort-order"));

           search();
        }
    });

    function scrollToElement(theId){
        $("#"+theId).focus();
        $('html, body').animate({
            scrollTop: $("#"+theId).offset().top
        }, 500);
    }

});
<commit_msg>Changed search results text<commit_after>"use strict";

$(function() {

    // set time zone name
    $("input[name='tz_name']").val(jstz.determine().name());

    var start = 0,
        end = 0,
        total = 0,
        canSearch = true,
        searchBtn = $("#search"),
        searchBtnAdv = $("#search-adv"),
        dateReq = $("#date-req"),
        noResultsFound = true,
        generateDocBtn = $("#generate-document"),
        agencySelect = $("#agency_ein"),
        agencyUserDiv = $("#agency-user-div"),
        agencyUserSelect = $("#agency_user"),
        resultsHeader = "resultsHeading";

    //Table head values
    var resultcol = [
            ['Status',''],
            ['ID',''],
            ['Date Submitted', 'sort_date_submitted','desc'],
            ['Title', 'sort_title','none'],
            ['Assigned Agency', ''],
            ['Date Due','sort_date_due','none']
    ];
    var sortSequence = ["none", "desc", "asc"];

    // Date stuff
    function dateInvalid(dateElem, msg, highlightDateRequirement) {
        dateElem
            .addClass("bad-input-text")
            .attr('data-content', msg)
            .popover(msg === null ? 'hide' : 'show');
        if (highlightDateRequirement) {
            dateReq.css("display", "block");
        }
        return false;
    }

    function dateValid(dateElem) {
        dateElem
            .removeClass("bad-input-text")
            .popover('hide');
        return true;
    }

    function valiDate(checkDateElem, compDateElem, isLessThan) {
        /*
        * Check that 'checkDateElem' holds an empty value or
        * that it is not a holiday or weekend and
        * that it 'isLessThan' (or greater than if 'isLessThan' == false)
        * compDateElem and style accordingly.
        * */
        if (checkDateElem.val()) {
            if (checkDateElem.val().length === 10) {
                var compDate = null;
                if (compDateElem.val().length === 10) {
                    try {
                        compDate = new Date(compDateElem.val());
                    }
                    catch (err) {
                        compDate = null;
                    }
                }
                try {
                    var checkDate = new Date(checkDateElem.val());
                    var validComp = compDate !== null ?
                        (isLessThan ? checkDate <= compDate : checkDate >= compDate) : true;
                    if (!notHolidayOrWeekend(checkDate, false)) {
                        return dateInvalid(checkDateElem, "This date does not fall on a business day.");
                    }
                    else if (!validComp) {
                        return dateInvalid(checkDateElem, null, true);
                    }
                    else {
                        return dateValid(checkDateElem);
                    }
                }
                catch (err) {
                    // failure parsing date string
                    return dateInvalid(checkDateElem, "This is not a valid date.");
                }
            }
            else {
                // missing full date string length
                return dateInvalid(checkDateElem, "This is not a valid date.");
            }
        }
        else {
            // empty value is valid (no filtering)
            return dateValid(checkDateElem);
        }
    }

    function valiDates(fromDateElem, toDateElem) {
        /*
        * Check that 'fromDateElem' is less than 'toDateElem'
        * and that both dates are not holidays or weekends.
        * */
        var fromValid = valiDate(fromDateElem, toDateElem, true),
            toValid = valiDate(toDateElem, fromDateElem, false);
        if (!fromValid || !toValid) {
            canSearch = false;
            searchBtn.attr("disabled", true);
            searchBtnAdv.attr("disabled", true);
            generateDocBtn.attr("disabled", true);
        }
        else {
            canSearch = true;
            searchBtn.attr("disabled", false);
            searchBtnAdv.attr("disabled", false);
            dateReq.css("display", "none");
            if (!noResultsFound) {
                generateDocBtn.attr("disabled", false);
            }
        }
    }

    var datepickerOptions = {
        dateFormat: "mm/dd/yy",
        daysOfWeekDisabled: [0, 6],
        beforeShowDay: notHolidayOrWeekend,
    };

    var dateRecFromElem = $("#date-rec-from");
    var dateRecToElem = $("#date-rec-to");
    var dateDueFromElem = $("#date-due-from");
    var dateDueToElem = $("#date-due-to");
    var dateClosedFromElem = $("#date-closed-from");
    var dateClosedToElem = $("#date-closed-to");

    var dates = [dateRecFromElem, dateRecToElem, dateDueFromElem, dateDueToElem, dateClosedFromElem, dateClosedToElem];
    for (var i = 0; i < dates.length; i++) {
        dates[i].datepicker(datepickerOptions);
        dates[i].mask("00/00/0000", {placeholder: "mm/dd/yyyy"});
    }
    dateRecFromElem.on("input change", function () {
        valiDates(dateRecFromElem, dateRecToElem);
    });
    dateRecToElem.on("input change", function () {
        valiDates(dateRecFromElem, dateRecToElem);
    });
    dateDueFromElem.on("input change", function () {
        valiDates(dateDueFromElem, dateDueToElem);
    });
    dateDueToElem.on("input change", function () {
        valiDates(dateDueFromElem, dateDueToElem);
    });
    dateClosedFromElem.on("input change", function () {
        valiDates(dateClosedFromElem, dateClosedToElem);
    });
    dateClosedToElem.on("input change", function () {
        valiDates(dateClosedFromElem, dateClosedToElem);
    });

    // keypress 'Enter' = click search button
    $("#search-section").keyup(function(e){
        if (canSearch && e.keyCode === 13) {
            searchBtn.click();
            searchBtnAdv.click();
        }
    });
    // but don't submit form (it is only used to generate results document)
    $("#search-form").on("keyup, keypress", function(e){
        var keyCode = e.keyCode || e.which;
        if (keyCode === 13) {
            e.preventDefault();
            searchBtn.click();
        }
    });

    // show test info
    // document.onkeypress = function (e) {
    //     var testInfo = $(".test-info");
    //     if (e.keyCode === 92) {
    //         if (testInfo.is(":visible")) {
    //             testInfo.hide();
    //         }
    //         else {
    //             testInfo.show();
    //         }
    //     }
    // };

    function buildResultsTable (theResults, count, total)
    {

        var theTable = "";
        theTable=theTable +'
';
        theTable=theTable + '
Displaying ' + (start + 1) + " - " + (start + count) + ' of ' + total + ' Results Found
';
        theTable=theTable + '

Request is:

Open=

Closed=
';
        // Activate for Agency view. A flag is needed to determine if view is active
        // if (agencyView) {
        //     theTable=theTable + '
In-progress=
';
        //     theTable=theTable + '
Soon=
';
        //     theTable=theTable + '
Overdue=
';
        // }
        theTable=theTable + '

';
        theTable=theTable + '

';
        theTable=theTable + buildResultsTableHead (resultcol, sortSequence);
        theTable=theTable + '

' + theResults + '

';
        return(theTable);
    }

    function buildResultsTableHead (col, sort){

        var tableHead = '';

        for (var i=0; i< col.length; i++){

            if (col[i][1] === '')
                {
                tableHead = tableHead + '' + col[i][0] + '	';
                }
            else
                {
                tableHead = tableHead + '<button type="button" class="sort-field" data-sort-order="' + col[i][2] +'" id="' + col[i][1] +'">' + col[i][0];
                var CurrentSort = $("input[name="+ col[i][1]+ "]").val();
                if (CurrentSort !=""){

                }
                tableHead = tableHead + '' +
                                        'Unsorted' +
                                        '' +
                                        'Sorted, Ascending' +
                                        '' +
                                        'Sorted, Descending </button>	';
            }
        }
        return tableHead;
    }

    var next = $("#next");
    var prev = $("#prev");

    function search() {

        // first clear out any "bad" input
        $(".bad-input-text").removeClass("bad-input-text").val("");

        var results = $("#results");
        var pageInfo = $("#page-info");

        $.ajax({
            url: "/search/requests",
            data: $("#search-form").serializeArray(),
            success: function(data) {
                if (data.total !== 0) {
                    noResultsFound = false;
                    results.html(buildResultsTable(data.results, data.count, data.total));
                    flask_moment_render_all();
                    $(".pagination").css("display", "flex");
                    pageInfo.text(
                        (start + 1) + " - " +
                        (start + data.count) +
                        " of " + data.total
                    );
                    total = data.total;
                    end = start + data.count;
                    if (end === total) {
                        next.attr("aria-disabled", true);
                        next.addClass("disabled")
                    }
                    else {
                        next.attr("aria-disabled", false);
                        next.removeClass("disabled")
                    }
                    if (start === 0) {
                        prev.attr("aria-disabled", true);
                        prev.addClass("disabled")
                    }
                    else {
                        prev.attr("aria-disabled", false);
                        prev.removeClass("disabled")
                    }
                    generateDocBtn.attr("disabled", false);

                }
                else {
                    noResultsFound = true;
                    results.html("

" +
                          "
No results found.

");
                    generateDocBtn.attr("disabled", true);
                }
            },
            error: function(e) {
                results.html("

" +
                    "
Hmmmm.... Looks like something's gone wrong.

");
                generateDocBtn.attr("disabled", true);
            }
        });
    }

    // search on load
    $(document).ready(function(){
        search();

    });

    // disable other filters if searching by FOIL-ID
    $("input[name='foil_id']").click(function() {
        var query = $("#query");
        var names = ["title", "description", "agency_request_summary", "requester_name"];
        var i;
        if ($(this).prop("checked")) {
            query.attr("placeholder", "0000-000-00000");
            for (i = 0; i < names.length; i++) {
                $("input[name='" + names[i] + "']").prop("disabled", true);
            }
        }
        else {
            query.attr("placeholder", "Enter keywords");
            for (i = 0; i < names.length; i++) {
                $("input[name='" + names[i] + "']").prop("disabled", false);
            }
        }
    });

    function setStart(val) {
        start = val;
        $("input[name='start']").val(val);
    }

    // Sorting
    function updateSorting(theHeadingId,sequence){

        for (var i=0; i< resultcol.length; i++){

            if (resultcol[i][1] === theHeadingId){
                resultcol[i][2] = sequence;
                console.log (resultcol[i][2] + "--" + resultcol[i][1]);
            }
        }
    }

    function cycleSort(elem) {
        /*
        * Cycle through sortSequence and 'style' elem with arrows
        * glyphicons representing sort direction.
        * */

        elem.attr(
            "data-sort-order",
            sortSequence[
                (sortSequence.indexOf(elem.attr("data-sort-order")) + 1 + sortSequence.length)
                % sortSequence.length]);

    }

    function resetAndSearch() {
        if (canSearch) {
            setStart(0);
            search();
        }
    }

    generateDocBtn.click(function () {
        if (canSearch) {
            search();
        }
    });
    $(".status").click(function () {
        resetAndSearch();
    });
    searchBtn.click(function () {
        resetAndSearch();
        scrollToElement(resultsHeader);

    });
    searchBtnAdv.click(function () {
        resetAndSearch();
        scrollToElement(resultsHeader);

    });
    $("#size").change(function () {
        resetAndSearch();
    });

    agencySelect.change(function () {
        agencyUserSelect.empty();

        if (agencySelect.val()) {
            $.ajax({
                url: "/agency/api/v1.0/active_users/" + agencySelect.val(),
                statusCode: {
                    404: function () {
                        agencyUserDiv.hide();
                    }
                },
                success: function (data) {
                    // Populate users
                    $.each(data.active_users ,function() {
                        agencyUserSelect.append($("<option />").val(this[0]).text(this[1]));
                    });

                    // Set selected value for standard agency users
                    if (!data.is_admin) {
                        agencyUserSelect.val(data.active_users[1][0]);
                    }

                    agencyUserDiv.show();
                },
                // search after ajax call is complete so default value for standard user is selected
                complete: function () {
                    resetAndSearch();
                }
            });
        }
        else {
            agencyUserDiv.is(":visible") && agencyUserDiv.hide();
            resetAndSearch();
        }
    });
    agencyUserSelect.change(function () {
        resetAndSearch();
    });
    next.click(function () {
        event.preventDefault();
        if (canSearch && end < total) {
            setStart(start + parseInt($("#size").val()));
            $('html, body').stop();
            search();
            scrollToElement(resultsHeader);
        }

    });
    prev.click(function () {
        event.preventDefault();
        if (canSearch && start > 0) {
            setStart(start - parseInt($("#size").val()));
            $('html, body').stop();
            search();
            scrollToElement(resultsHeader);
        }

    });

    $('body').on('click', '.sort-field', function() {
        if (canSearch) {
            setStart(0);
            cycleSort($(this));

            // fill hidden inputs
            $("input[name='" + $(this).attr("id") + "']").val($(this).attr("data-sort-order"));

            //Update Array to reflect column status
            updateSorting($(this).attr("id"),$(this).attr("data-sort-order"));

           search();
        }
    });

    function scrollToElement(theId){
        $("#"+theId).focus();
        $('html, body').animate({
            scrollTop: $("#"+theId).offset().top
        }, 500);
    }

});
<|endoftext|>


<commit_before>/**
 * superagentCache constructor
 * @constructor
 * @param {superagent instance} agent (optional)
 * @param {cache module} cache (optional)
 */
module.exports = function(agent, cache, defaults){

  var superagent = (agent) ? agent : require('superagent');

  if(!superagent.patchedBySuperagentCache){
    superagent.cache = (cache) ? cache : new (require('cache-service-cache-module'))();
    superagent.defaults = defaults || {};
    var Request = superagent.Request;
    var props = resetProps(superagent.defaults);
    var supportedMethods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE'];
    var cacheableMethods = ['GET', 'HEAD'];
    superagent.patchedBySuperagentCache = true;

    /**
     * Whether to execute an http query if the cache does not have the generated key
     * @param {boolean} doQuery
     */
    Request.prototype.doQuery = function(doQuery){
      props.doQuery = doQuery;
      return this;
    }

    /**
     * Remove the given params from the query object after executing an http query and before generating a cache key
     * @param {array of strings} pruneParams
     */
    Request.prototype.pruneParams = function(pruneParams){
      props.pruneParams = pruneParams;
      return this;
    }

    /**
     * Remove the given options from the headers object after executing an http query and before generating a cache key
     * @param {boolean} pruneOptions
     */
    Request.prototype.pruneOptions = function(pruneOptions){
      props.pruneOptions = pruneOptions;
      return this;
    }

    /**
     * Execute some logic on superagent's http response object before caching and returning it
     * @param {function} prune
     */
    Request.prototype.prune = function(prune){
      props.prune = prune;
      return this;
    }

    /**
     * Retrieve a top-level property from superagent's http response object before to cache and return
     * @param {string} responseProp
     */
    Request.prototype.responseProp = function(responseProp){
      props.responseProp = responseProp;
      return this;
    }

    /**
     * Set an expiration for this key that will override the configured cache's default expiration
     * @param {integer} expiration (seconds)
     */
    Request.prototype.expiration = function(expiration){
      props.expiration = expiration;
      return this;
    }

    /**
     * Whether to cache superagent's http response object when it "empty"--especially useful with .prune and .pruneParams
     * @param {string} responseProp
     */
    Request.prototype.cacheWhenEmpty = function(cacheWhenEmpty){
      props.cacheWhenEmpty = cacheWhenEmpty;
      return this;
    }

    /**
     * Initialize a background refresh for the generated key and value
     * @param {boolean | function} backgroundRefresh
     */
    Request.prototype.backgroundRefresh = function(backgroundRefresh){
      props.backgroundRefresh = (typeof backgroundRefresh !== 'undefined') ? backgroundRefresh : true;
      return this;
    }

    /**
     * An alias for the .end function because I use ._end and .end for other things
     */
    Request.prototype.execute = Request.prototype.end;

    /**
     * Wraps the .end function so that .resetProps gets called--callable so that no caching logic takes place
     */
    Request.prototype._end = function(cb){
      props = resetProps(superagent.defaults);
      this.execute(cb);
    }

    /**
     * Execute all caching and http logic
     * @param {function} cb
     */
    Request.prototype.end = function(cb){
      var curProps = props;
      props = resetProps(superagent.defaults);
      if(~supportedMethods.indexOf(this.method)){
        var _this = this;
        var key = keygen(this, curProps);
        if(~cacheableMethods.indexOf(this.method)){
          superagent.cache.get(key, function (err, response){
            if(!err && response){
              _this.abort();
              callbackExecutor(cb, err, response, key);
            }
            else{
              if(curProps.doQuery){
                _this._end(function (err, response){
                  if(err) {
                    return callbackExecutor(cb, err, response, key);
                  }
                  else if(!err && response){
                    if(curProps.prune){
                      response = curProps.prune(response);
                    }
                    else if(curProps.responseProp){
                      response = response[curProps.responseProp] || null;
                    }
                    else{
                      response = gutResponse(response);
                    }
                    if(!isEmpty(response) || curProps.cacheWhenEmpty){
                      var refresh = curProps.backgroundRefresh || null;
                      if(typeof refresh == 'boolean'){
                        refresh = getBackgroundRefreshFunction(curProps);
                      }
                      superagent.cache.set(key, response, curProps.expiration, refresh, function (){
                        callbackExecutor(cb, err, response, key);
                      });
                    }
                    else{
                      callbackExecutor(cb, err, response, key);
                    }
                  }
                });
              }
              else{
                callbackExecutor(cb, null, null, key);
              }
            }
          });
        }
        else{
          this._end(function (err, response){
            if (err) {
              return callbackExecutor(cb, err, response, key);
            }

            if(!err && response){
              var keyGet = key.replace('"method":"' + _this.method + '"', '"method":"GET"');
              var keyHead = key.replace('"method":"' + _this.method + '"', '"method":"HEAD"');
              superagent.cache.del([keyGet, keyHead], function (){
                callbackExecutor(cb, err, response, key);
              });
            }
          });
        }
      }
      else{
        this._end(function (err, response){
          callbackExecutor(cb, err, response, undefined);
        });
      }
    }

    /**
     * Set this.req to null so that future http calls get a branc new req object
     */
    Request.prototype.reset = function(){
      this.req = null;
    }

    /**
     * Generate a cache key unique to this query
     * @param {object} reg
     * @param {object} cProps
     */
    function keygen(req, cProps){
      var cleanParams = null;
      var cleanOptions = null;
      var params = !isEmpty(req.qs) ? req.qs : arrayToObj(req.qsRaw);
      if(!params && req.req){
        params = stringToObj(req.req.path);
      }
      var options = (req.req && req.req._headers) ? req.req._headers : null;
      if(cProps.pruneParams || cProps.pruneOptions){
        cleanParams = (cProps.pruneParams) ? pruneObj(cloneObject(params), cProps.pruneParams) : params;
        cleanOptions = (cProps.pruneOptions) ? pruneObj(cloneObject(options), cProps.pruneOptions, true) : options;
      }
      return JSON.stringify({
        nameSpace: superagent.cache.nameSpace,
        method: req.method,
        uri: req.url,
        params: cleanParams || params || null,
        options: cleanOptions || options || null
      });
    }

    /**
     * Convert an array to an object
     * @param {array} arr
     */
    function arrayToObj(arr){
      if(arr && arr.length){
        var obj = {};
        for(var i = 0; i < arr.length; i++){
          var str = arr[i];
          var kvArray = str.split('&');
          for(var j = 0; j < kvArray.length; j++){
            var kvString = kvArray[j].split('=');
            obj[kvString[0]] = kvString[1];
          }
        }
        return obj;
      }
      return null;
    }

    /**
     * Convert a string to an object
     * @param {string} str
     */
    function stringToObj(str){
      if(str){
        var obj = {};
        if(~str.indexOf('?')){
          var strs = str.split('?');
          str = strs[1];
        }
        var kvArray = str.split('&');
        for(var i = 0; i < kvArray.length; i++){
          var kvString = kvArray[i].split('=');
          obj[kvString[0]] = kvString[1];
        }
        return obj;
      }
      return null;
    }

    /**
     * Remove properties from an object
     * @param {object} obj
     * @param {array} props
     * @param {boolean} isOptions
     */
    function pruneObj(obj, props, isOptions){
      for(var i = 0; i < props.length; i++){
        var prop = props[i];
        if(isOptions){
          prop = prop.toLowerCase();
        }
        delete obj[prop]
      }
      return obj;
    }

    /**
     * Simplify superagent's http response object
     * @param {object} r
     */
    function gutResponse(r){
      var newResponse = {};
      newResponse.body = r.body;
      newResponse.text = r.text;
      newResponse.headers = r.headers;
      newResponse.statusCode = r.statusCode;
      newResponse.status = r.status;
      newResponse.ok = r.ok;
      return newResponse;
    }

    /**
     * Determine whether a value is considered empty
     * @param {*} val
     */
    function isEmpty(val){
      return (val === false || val === null || (typeof val == 'object' && Object.keys(val).length == 0));
    }

    /**
     * Return a cloneof an object
     * @param {object} obj
     */
    function cloneObject(obj){
      var newObj = {};
      for(var attr in obj) {
        if (obj.hasOwnProperty(attr)){
          newObj[attr] = obj[attr];
        }
      }
      return newObj;
    }

    /**
     * Reset superagent-cache's default query properties
     */
    function resetProps(d){
      return {
        doQuery: (typeof d.doQuery === 'boolean') ? d.doQuery : true,
        cacheWhenEmpty: (typeof d.cacheWhenEmpty === 'boolean') ? d.cacheWhenEmpty : true,
        prune: d.prune,
        pruneParams: d.pruneParams,
        pruneOptions: d.pruneOptions,
        responseProp: d.responseProp,
        expiration: d.expiration,
        backgroundRefresh: d.backgroundRefresh
      };
    }

    /**
     * Generate a background refresh query identical to the current query
     * @param {object} curProps
     */
    function getBackgroundRefreshFunction(curProps){
      return function(key, cb){
        key = JSON.parse(key);
        var method = key.method.toLowerCase();
        var request = superagent
          [method](key.uri)
          .doQuery(curProps.doQuery)
          .pruneParams(curProps.pruneParams)
          .pruneOptions(curProps.pruneOptions)
          .prune(curProps.prune)
          .responseProp(curProps.responseProp)
          .expiration(curProps.expiration)
          .cacheWhenEmpty(curProps.cacheWhenEmpty);
        if(key.params){
          request.query(key.params)
        }
        if(key.options){
          request.set(key.options);
        }
        request.end(cb);
      }
    }

    /**
     * Handle the varying number of callback output params
     * @param {function} cb
     * @param {object} err
     * @param {object} response
     * @param {string} key
     */
    function callbackExecutor(cb, err, response, key){
      if(cb.length === 1){
        cb(response);
      }
      else if(cb.length > 1){
        cb(err, response, key);
      }
      else{
        throw new Error('UnsupportedCallbackException: Your .end() callback must pass at least one argument.');
      }
    }
  }

  if(!agent){
    return superagent;
  }

}
<commit_msg>Attempting to fix evaluations of query params and header options when superagent is used on the client.<commit_after>/**
 * superagentCache constructor
 * @constructor
 * @param {superagent instance} agent (optional)
 * @param {cache module} cache (optional)
 */
module.exports = function(agent, cache, defaults){

  var superagent = (agent) ? agent : require('superagent');

  if(!superagent.patchedBySuperagentCache){
    superagent.cache = (cache) ? cache : new (require('cache-service-cache-module'))();
    superagent.defaults = defaults || {};
    var Request = superagent.Request;
    var props = resetProps(superagent.defaults);
    var supportedMethods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE'];
    var cacheableMethods = ['GET', 'HEAD'];
    superagent.patchedBySuperagentCache = true;

    /**
     * Whether to execute an http query if the cache does not have the generated key
     * @param {boolean} doQuery
     */
    Request.prototype.doQuery = function(doQuery){
      props.doQuery = doQuery;
      return this;
    }

    /**
     * Remove the given params from the query object after executing an http query and before generating a cache key
     * @param {array of strings} pruneParams
     */
    Request.prototype.pruneParams = function(pruneParams){
      props.pruneParams = pruneParams;
      return this;
    }

    /**
     * Remove the given options from the headers object after executing an http query and before generating a cache key
     * @param {boolean} pruneOptions
     */
    Request.prototype.pruneOptions = function(pruneOptions){
      props.pruneOptions = pruneOptions;
      return this;
    }

    /**
     * Execute some logic on superagent's http response object before caching and returning it
     * @param {function} prune
     */
    Request.prototype.prune = function(prune){
      props.prune = prune;
      return this;
    }

    /**
     * Retrieve a top-level property from superagent's http response object before to cache and return
     * @param {string} responseProp
     */
    Request.prototype.responseProp = function(responseProp){
      props.responseProp = responseProp;
      return this;
    }

    /**
     * Set an expiration for this key that will override the configured cache's default expiration
     * @param {integer} expiration (seconds)
     */
    Request.prototype.expiration = function(expiration){
      props.expiration = expiration;
      return this;
    }

    /**
     * Whether to cache superagent's http response object when it "empty"--especially useful with .prune and .pruneParams
     * @param {string} responseProp
     */
    Request.prototype.cacheWhenEmpty = function(cacheWhenEmpty){
      props.cacheWhenEmpty = cacheWhenEmpty;
      return this;
    }

    /**
     * Initialize a background refresh for the generated key and value
     * @param {boolean | function} backgroundRefresh
     */
    Request.prototype.backgroundRefresh = function(backgroundRefresh){
      props.backgroundRefresh = (typeof backgroundRefresh !== 'undefined') ? backgroundRefresh : true;
      return this;
    }

    /**
     * An alias for the .end function because I use ._end and .end for other things
     */
    Request.prototype.execute = Request.prototype.end;

    /**
     * Wraps the .end function so that .resetProps gets called--callable so that no caching logic takes place
     */
    Request.prototype._end = function(cb){
      props = resetProps(superagent.defaults);
      this.execute(cb);
    }

    /**
     * Execute all caching and http logic
     * @param {function} cb
     */
    Request.prototype.end = function(cb){
      var curProps = props;
      props = resetProps(superagent.defaults);
      if(~supportedMethods.indexOf(this.method)){
        var _this = this;
        var key = keygen(this, curProps);
        if(~cacheableMethods.indexOf(this.method)){
          superagent.cache.get(key, function (err, response){
            if(!err && response){
              _this.abort();
              callbackExecutor(cb, err, response, key);
            }
            else{
              if(curProps.doQuery){
                _this._end(function (err, response){
                  if(err) {
                    return callbackExecutor(cb, err, response, key);
                  }
                  else if(!err && response){
                    if(curProps.prune){
                      response = curProps.prune(response);
                    }
                    else if(curProps.responseProp){
                      response = response[curProps.responseProp] || null;
                    }
                    else{
                      response = gutResponse(response);
                    }
                    if(!isEmpty(response) || curProps.cacheWhenEmpty){
                      var refresh = curProps.backgroundRefresh || null;
                      if(typeof refresh == 'boolean'){
                        refresh = getBackgroundRefreshFunction(curProps);
                      }
                      superagent.cache.set(key, response, curProps.expiration, refresh, function (){
                        callbackExecutor(cb, err, response, key);
                      });
                    }
                    else{
                      callbackExecutor(cb, err, response, key);
                    }
                  }
                });
              }
              else{
                callbackExecutor(cb, null, null, key);
              }
            }
          });
        }
        else{
          this._end(function (err, response){
            if (err) {
              return callbackExecutor(cb, err, response, key);
            }

            if(!err && response){
              var keyGet = key.replace('"method":"' + _this.method + '"', '"method":"GET"');
              var keyHead = key.replace('"method":"' + _this.method + '"', '"method":"HEAD"');
              superagent.cache.del([keyGet, keyHead], function (){
                callbackExecutor(cb, err, response, key);
              });
            }
          });
        }
      }
      else{
        this._end(function (err, response){
          callbackExecutor(cb, err, response, undefined);
        });
      }
    }

    /**
     * Set this.req to null so that future http calls get a branc new req object
     */
    Request.prototype.reset = function(){
      this.req = null;
    }

    /**
     * Generate a cache key unique to this query
     * @param {object} reg
     * @param {object} cProps
     */
    function keygen(req, cProps){
      var cleanParams = null;
      var cleanOptions = null;
      var params = getQueryParams(req);
      var options = getHeaderOptions(req);
      if(cProps.pruneParams || cProps.pruneOptions){
        cleanParams = (cProps.pruneParams) ? pruneObj(cloneObject(params), cProps.pruneParams) : params;
        cleanOptions = (cProps.pruneOptions) ? pruneObj(cloneObject(options), cProps.pruneOptions, true) : options;
      }
      return JSON.stringify({
        nameSpace: superagent.cache.nameSpace,
        method: req.method,
        uri: req.url,
        params: cleanParams || params || null,
        options: cleanOptions || options || null
      });
    }

    function getQueryParams(req){
      if(req.qs && !isEmpty(req.qs)){
        return req.qs;
      }
      else if(req.qsRaw){
        return arrayToObj(req.qsRaw);
      }
      else if(req.req){
        return stringToObj(req.req.path);
      }
      else if(req._query){
        return stringToObj(req._query.join('&'));
      }
      return null;
    }

    function getHeaderOptions(req){
      if(req.req && req.req._headers){
        return req.req._headers;
      }
      else if(req._header){
        return req._header;
      }
      return null;
    }

    /**
     * Convert an array to an object
     * @param {array} arr
     */
    function arrayToObj(arr){
      if(arr && arr.length){
        var obj = {};
        for(var i = 0; i < arr.length; i++){
          var str = arr[i];
          var kvArray = str.split('&');
          for(var j = 0; j < kvArray.length; j++){
            var kvString = kvArray[j].split('=');
            obj[kvString[0]] = kvString[1];
          }
        }
        return obj;
      }
      return null;
    }

    /**
     * Convert a string to an object
     * @param {string} str
     */
    function stringToObj(str){
      if(str){
        var obj = {};
        if(~str.indexOf('?')){
          var strs = str.split('?');
          str = strs[1];
        }
        var kvArray = str.split('&');
        for(var i = 0; i < kvArray.length; i++){
          var kvString = kvArray[i].split('=');
          obj[kvString[0]] = kvString[1];
        }
        return obj;
      }
      return null;
    }

    /**
     * Remove properties from an object
     * @param {object} obj
     * @param {array} props
     * @param {boolean} isOptions
     */
    function pruneObj(obj, props, isOptions){
      for(var i = 0; i < props.length; i++){
        var prop = props[i];
        if(isOptions){
          prop = prop.toLowerCase();
        }
        delete obj[prop]
      }
      return obj;
    }

    /**
     * Simplify superagent's http response object
     * @param {object} r
     */
    function gutResponse(r){
      var newResponse = {};
      newResponse.body = r.body;
      newResponse.text = r.text;
      newResponse.headers = r.headers;
      newResponse.statusCode = r.statusCode;
      newResponse.status = r.status;
      newResponse.ok = r.ok;
      return newResponse;
    }

    /**
     * Determine whether a value is considered empty
     * @param {*} val
     */
    function isEmpty(val){
      return (val === false || val === null || (typeof val == 'object' && Object.keys(val).length == 0));
    }

    /**
     * Return a cloneof an object
     * @param {object} obj
     */
    function cloneObject(obj){
      var newObj = {};
      for(var attr in obj) {
        if (obj.hasOwnProperty(attr)){
          newObj[attr] = obj[attr];
        }
      }
      return newObj;
    }

    /**
     * Reset superagent-cache's default query properties using the options defaults object
     * @param {object} d
     */
    function resetProps(d){
      return {
        doQuery: (typeof d.doQuery === 'boolean') ? d.doQuery : true,
        cacheWhenEmpty: (typeof d.cacheWhenEmpty === 'boolean') ? d.cacheWhenEmpty : true,
        prune: d.prune,
        pruneParams: d.pruneParams,
        pruneOptions: d.pruneOptions,
        responseProp: d.responseProp,
        expiration: d.expiration,
        backgroundRefresh: d.backgroundRefresh
      };
    }

    /**
     * Generate a background refresh query identical to the current query
     * @param {object} curProps
     */
    function getBackgroundRefreshFunction(curProps){
      return function(key, cb){
        key = JSON.parse(key);
        var method = key.method.toLowerCase();
        var request = superagent
          [method](key.uri)
          .doQuery(curProps.doQuery)
          .pruneParams(curProps.pruneParams)
          .pruneOptions(curProps.pruneOptions)
          .prune(curProps.prune)
          .responseProp(curProps.responseProp)
          .expiration(curProps.expiration)
          .cacheWhenEmpty(curProps.cacheWhenEmpty);
        if(key.params){
          request.query(key.params)
        }
        if(key.options){
          request.set(key.options);
        }
        request.end(cb);
      }
    }

    /**
     * Handle the varying number of callback output params
     * @param {function} cb
     * @param {object} err
     * @param {object} response
     * @param {string} key
     */
    function callbackExecutor(cb, err, response, key){
      if(cb.length === 1){
        cb(response);
      }
      else if(cb.length > 1){
        cb(err, response, key);
      }
      else{
        throw new Error('UnsupportedCallbackException: Your .end() callback must pass at least one argument.');
      }
    }
  }

  if(!agent){
    return superagent;
  }

}
<|endoftext|>


<commit_before>(function($){
	$.fn.tzCheckbox = function(options){

		// Default On / Off labels:

		options = $.extend({
			labels : ['ON','OFF']
		},options);

		return this.each(function(){
			var originalCheckBox = $(this),
				labels = [];

			// Checking for the data-on / data-off HTML5 data attributes:
			if(originalCheckBox.data('on')){
				labels[0] = originalCheckBox.data('on');
				labels[1] = originalCheckBox.data('off');
			}
			else labels = options.labels;

			// Creating the new checkbox markup:
			var checkBox = $('',{
				class	: 'tzCheckBox '+(this.checked?'checked':''),
				html:	''+labels[this.checked?0:1]+
						''
			});

			// Inserting the new checkbox, and hiding the original:
			checkBox.insertAfter(originalCheckBox.hide());

			checkBox.click(function(){
				checkBox.toggleClass('checked');

				var isChecked = checkBox.hasClass('checked');

				// Synchronizing the original checkbox:
				originalCheckBox.attr('checked',isChecked);
				checkBox.find('.tzCBContent').html(labels[isChecked?0:1]);
			});

			// Listening for changes on the original and affecting the new one:
			originalCheckBox.bind('change',function(){
				checkBox.click();
			});
		});
	};
})(jQuery);<commit_msg>updated the tz checkbox plugin so the original element's click is triggered (for full support) and custom script changes should now trigger the 'checked' function on the original checkbox, though these will be rare<commit_after>(function ($) {
    $.fn.tzCheckbox = function (options) {

        // Default On / Off labels:

        options = $.extend({
            labels: ['ON', 'OFF']
        }, options);

        return this.each(function () {
            var originalCheckBox = $(this),
				labels = [];

            // Checking for the data-on / data-off HTML5 data attributes:
            if (originalCheckBox.data('on')) {
                labels[0] = originalCheckBox.data('on');
                labels[1] = originalCheckBox.data('off');
            }
            else labels = options.labels;

            // Creating the new checkbox markup:
            var checkBox = $('', {
                class: 'tzCheckBox ' + (this.checked ? 'checked' : ''),
                html: '' + labels[this.checked ? 0 : 1] +
						''
            });

            // Inserting the new checkbox, and hiding the original:
            checkBox.insertAfter(originalCheckBox.hide());

            checkBox.click(function () {
                checkBox.toggleClass('checked');

                var isChecked = checkBox.hasClass('checked');

                // Synchronizing the original checkbox:
                originalCheckBox.attr('checked', isChecked);
                checkBox.find('.tzCBContent').html(labels[isChecked ? 0 : 1]);

                originalCheckBox.trigger('click');
            });

            // Trigger 'checked' if the original changes & the new one will be updated
            originalCheckBox.bind('checked', function () {
                checkBox.click();
            });
        });
    };
})(jQuery);<|endoftext|>


<commit_before>import loggerCreator from '../utils/logger'
var moduleLogger = loggerCreator("player_page");

import React, { Component } from 'react';
import { StyleSheet, View, TouchableHighlight, Image, ActivityIndicator, DeviceEventEmitter, BackAndroid, AppState } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';

import playerProxy from '../native_proxy/player_proxy'

import { colors, fontSizes } from '../styles/styles'
import RectangleButton from '../components/rectangle_button'
import CircleButton from '../components/circle_button'
import Text from '../components/text'

import Navigator from '../stores/navigator'
import { getArtistImage } from '../utils/backend_lastfm_api'

export default class PlayerPage extends Component {

  PLAYLIST_PLAYER_STATUS_EVENT = "PLAYLIST_PLAYER_STATUS_EVENT";

  resolveWhenPlayerAvailable() {
    let logger = loggerCreator("resolveWhenPlayerAvailable", moduleLogger);
    logger.info(`start`);

    return playerProxy.isPlayerAvailable().then(isAvailable => {
      if (!isAvailable) {
        logger.info(`not available - retrying`);
        return this.resolveWhenPlayerAvailable();
      }
    });
  }

  refreshStatus() {
    let logger = loggerCreator("refreshStatus", moduleLogger);
    logger.info(`start`);

    logger.info(`waiting for player to be available`);
    this.resolveWhenPlayerAvailable().then(() => {
      logger.info(`player available`);
      return playerProxy.getPlayerStatus();
    }).then(status => {
      logger.info(`got status: ${JSON.stringify(status)}`);
      logger.info(`this.playlistChosen: ${this.playlistChosen}`);

      var playlistPlayer = status.playlistPlayer;

      if (!playlistPlayer && this.playlistChosen) {
        logger.info(`player service restarted`);
        this.props.navigator.navigateToPlaylistCollection();
      } else if (playlistPlayer && playlistPlayer.isPlaying && playlistPlayer.playlist.name == this.props.playlistName) {
        logger.info(`playing existing playlist`);
        this.onPlaylistPlayerStatus(playlistPlayer);
      } else {
        logger.info(`changing playlist to: ${this.props.playlistName}`);
        playerProxy.changePlaylist(this.props.playlistName);
        playerProxy.play();

        this.playlistChosen = true;
      }
    });
  }

  componentWillMount() {
    let logger = loggerCreator("componentWillMount", moduleLogger);
    logger.info(`start playlist: ${this.props.playlistName}`);

    this.playlistChosen = false;

    this.state = {
      isLoading: true,
      loadingError: null,

      isPlaying: false,

      playlistName: this.props.playlistName,
      song: {
        artist: null,
        title: null,
        album: null,
        albumArtUri: null
      }
    };

    DeviceEventEmitter.addListener(this.PLAYLIST_PLAYER_STATUS_EVENT, event => this.onPlaylistPlayerStatus(event));
    BackAndroid.addEventListener('hardwareBackPress', () => this.onPressHardwareBack());
    AppState.addEventListener('change', currentAppState => this.onHandleAppStateChange(currentAppState));

    this.refreshStatus();
  }

  componentWillUnmount() {
    DeviceEventEmitter.removeAllListeners(this.PLAYLIST_PLAYER_STATUS_EVENT);
    AppState.removeEventListener('change', this.onHandleAppStateChange());
  }

  onHandleAppStateChange(currentAppState) {
    let logger = loggerCreator("onHandleAppStateChange", moduleLogger);
    logger.info(`start: ${currentAppState}`);

    if (currentAppState === 'active') {
      this.refreshStatus();
    }
  }

  onPressPlayPause() {
    playerProxy.playPause();
  }

  onPressNext() {
    playerProxy.playNext();
  }

  onPressHardwareBack() {
    let logger = loggerCreator("hardwareBackPress", moduleLogger);
    logger.info(`start`);
    playerProxy.pause();
    this.props.navigator.navigateToPlaylistCollection();
    return true;
  }

  onPlaylistPlayerStatus(status) {
    let logger = loggerCreator("onPlaylistPlayerStatus", moduleLogger);
    logger.info(`got event: ${JSON.stringify(status)}`);
    status.song = status.song || {};

    // sample status: {"song":{"title":"Strangelove","album":"Music For the Masses","artist":"Depeche Mode"},
    //                "playlist":{"name":"Peaceful"},"isPlaying":false,"isLoading":true}

    if (status.song.artist && status.song.artist !== this.state.song.artist) {
      logger.info(`artist changed from '${this.state.song.artist}' to '${status.song.artist}' - reloading album cover`);

      this.setState({song: {...this.state.song, albumArtUri: null}});
      getArtistImage(status.song.artist).then(imageUri => {
        logger.info(`got album art uri: ${imageUri}`);
        this.setState({song: {...this.state.song, albumArtUri: imageUri}});
      })
    }

    this.setState({
      isLoading: status.isLoading,
      loadingError: status.loadingError,
      isPlaying: status.isPlaying,
      song: {
        ...this.state.song,
        artist: status.song.artist,
        title: status.song.title,
        album: status.song.album,
      }
    });
  }

  render() {
    let logger = loggerCreator("render", moduleLogger);
    logger.info(`start`);

    let albumArt = require("../images/no-album2.png");
    logger.info(`uri: ${this.state.song.albumArtUri}`);
    if (this.state.song.albumArtUri) {
      albumArt = {uri: this.state.song.albumArtUri};
    }

    let loadingStatus = "Loading";
    if (this.state.song.title) {
      loadingStatus = `${loadingStatus}: ${this.state.song.artist} - ${this.state.song.title}`
    }

    let loadingError = "";
    if (this.state.loadingError) {
      loadingError = `Error occured, retrying: ${this.state.loadingError}`
    }

    return (
      <View style={styles.container}>
        <View style={styles.playlistNameView}>
          <Icon name="music" style={styles.playlistIcon}/>
          <Text>{this.props.playlistName}</Text>
        </View>
        <Choose>
          <When condition={!this.state.isLoading}>
            {/* Album art */}
            <View style={styles.albumArtView}>
              <Image style={styles.albumArt} source={albumArt}/>
            </View>
            {/* Controls */}
            <View style={styles.namesView}>
              <Text style={[styles.nameText, styles.titleText]}>{`${this.state.song.title}`}</Text>
              <Text style={[styles.nameText, styles.artistText]}>{`${this.state.song.artist}`}</Text>
              <Text style={[styles.nameText, styles.albumText]}>{`${this.state.song.album}`}</Text>
            </View>
            {/* Controls */}
            <View style={styles.controlsView}>
              <CircleButton size={100} onPress={() => this.onPressPlayPause()}
                            style={[styles.controlButtonPlay]}>
                <Icon name={this.state.isPlaying ? "pause" : "play"}
                      style={[styles.controlButtonText, this.state.isPlaying ? styles.controlTextPause : styles.controlTextPlay]}/>
              </CircleButton>
              <CircleButton size={60} onPress={() => this.onPressNext()}>
                <Icon name="step-forward"
                      style={styles.controlButtonText}/>
              </CircleButton>
            </View>
          </When>
          <Otherwise>
            <View style={styles.progressView}>
              <View style={styles.progressSpinner}>
                <ActivityIndicator size="large"/>
              </View>
              <View style={styles.progressStatus}>
                <Text>{loadingStatus}</Text>
                <Text style={styles.progressStatusError}>{loadingError}</Text>
              </View>
            </View>
          </Otherwise>
        </Choose>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    // remove width and height to override fixed static size
    width: null,
    height: null,
    alignItems: "center",
    alignSelf: "stretch"
  },
  // Playlist name
  playlistNameView: {
    flexDirection: "row",
    alignItems: "center",
    alignSelf: "stretch",
    marginBottom: 10,
    paddingTop: 5,
    paddingLeft: 5,
  },
  playlistIcon: {
    color: colors.SEMI_WHITE.rgbString(),
    marginRight: 5,
  },
  // Album
  albumArtView: {
    backgroundColor: "black",
    borderColor: colors.CYAN_DARK.rgbString(),
    borderWidth: 2,

    justifyContent: "center",
    alignItems: "center",

    marginBottom: 20
  },
  // Names (artist, title, album)
  namesView: {
    alignItems: "center",
    marginBottom: 10
  },
  nameText: {
    fontSize: fontSizes.LARGE,
    marginBottom: 10
  },
  artistText: {
    color: colors.CYAN_BRIGHT.rgbString()
  },
  albumArt: {
    width: 200,
    height: 200,
    resizeMode: "contain"
  },
  // Controls
  controlsView: {
    position: "absolute",
    bottom: 10,
    left: 0,
    right: 0,

    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
    paddingLeft: 80, // Causes the play button to be in the center
  },
  controlButtonText: {
    color: colors.SEMI_WHITE.rgbString(),
    fontSize: 40
  },
  controlTextPlay: {
    paddingLeft: 10
  },
  controlTextPause: {
    paddingLeft: 0
  },
  controlButtonPlay: {
    marginRight: 20
  },
  // Progress
  progressSpinner: {
    justifyContent: "flex-end",
    paddingBottom: 10,
    flex: 1,
  },
  progressStatus: {
    justifyContent: "flex-start",
    alignItems: "center",
    flex: 1,
  },
  progressStatusError: {
    color: "red"
  }
});

PlayerPage.propTypes = {
  navigator: React.PropTypes.instanceOf(Navigator).isRequired,
  playlistName: React.PropTypes.string.isRequired,
};
<commit_msg>prettify<commit_after>import loggerCreator from '../utils/logger'
var moduleLogger = loggerCreator("player_page");

import React, { Component } from 'react';
import { StyleSheet, View, TouchableHighlight, Image, ActivityIndicator, DeviceEventEmitter, BackAndroid, AppState } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';

import playerProxy from '../native_proxy/player_proxy'

import { colors, fontSizes } from '../styles/styles'
import RectangleButton from '../components/rectangle_button'
import CircleButton from '../components/circle_button'
import Text from '../components/text'

import Navigator from '../stores/navigator'
import { getArtistImage } from '../utils/backend_lastfm_api'

export default class PlayerPage extends Component {

  PLAYLIST_PLAYER_STATUS_EVENT = "PLAYLIST_PLAYER_STATUS_EVENT";

  componentWillMount() {
    let logger = loggerCreator("componentWillMount", moduleLogger);
    logger.info(`start playlist: ${this.props.playlistName}`);

    this.playlistChosen = false;

    this.state = {
      isLoading: true,
      loadingError: null,

      isPlaying: false,

      playlistName: this.props.playlistName,
      song: {
        artist: null,
        title: null,
        album: null,
        albumArtUri: null
      }
    };

    DeviceEventEmitter.addListener(this.PLAYLIST_PLAYER_STATUS_EVENT, event => this.onPlaylistPlayerStatus(event));
    BackAndroid.addEventListener('hardwareBackPress', () => this.onPressHardwareBack());
    AppState.addEventListener('change', currentAppState => this.onHandleAppStateChange(currentAppState));

    this.refreshStatus();
  }

  componentWillUnmount() {
    DeviceEventEmitter.removeAllListeners(this.PLAYLIST_PLAYER_STATUS_EVENT);
    AppState.removeEventListener('change', this.onHandleAppStateChange());
  }

  resolveWhenPlayerAvailable() {
    let logger = loggerCreator("resolveWhenPlayerAvailable", moduleLogger);
    logger.info(`start`);

    return playerProxy.isPlayerAvailable().then(isAvailable => {
      if (!isAvailable) {
        logger.info(`not available - retrying`);
        return this.resolveWhenPlayerAvailable();
      }
    });
  }

  refreshStatus() {
    let logger = loggerCreator("refreshStatus", moduleLogger);
    logger.info(`start`);

    logger.info(`waiting for player to be available`);
    this.resolveWhenPlayerAvailable().then(() => {
      logger.info(`player available`);
      return playerProxy.getPlayerStatus();
    }).then(status => {
      logger.info(`got status: ${JSON.stringify(status)}`);
      logger.info(`this.playlistChosen: ${this.playlistChosen}`);

      var playlistPlayer = status.playlistPlayer;

      if (!playlistPlayer && this.playlistChosen) {
        logger.info(`player service restarted`);
        this.props.navigator.navigateToPlaylistCollection();
      } else if (playlistPlayer && playlistPlayer.isPlaying && playlistPlayer.playlist.name == this.props.playlistName) {
        logger.info(`playing existing playlist`);
        this.onPlaylistPlayerStatus(playlistPlayer);
      } else {
        logger.info(`changing playlist to: ${this.props.playlistName}`);
        playerProxy.changePlaylist(this.props.playlistName);
        playerProxy.play();

        this.playlistChosen = true;
      }
    });
  }

  onHandleAppStateChange(currentAppState) {
    let logger = loggerCreator("onHandleAppStateChange", moduleLogger);
    logger.info(`start: ${currentAppState}`);

    if (currentAppState === 'active') {
      this.refreshStatus();
    }
  }

  onPressPlayPause() {
    playerProxy.playPause();
  }

  onPressNext() {
    playerProxy.playNext();
  }

  onPressHardwareBack() {
    let logger = loggerCreator("hardwareBackPress", moduleLogger);
    logger.info(`start`);
    playerProxy.pause();
    this.props.navigator.navigateToPlaylistCollection();
    return true;
  }

  onPlaylistPlayerStatus(status) {
    let logger = loggerCreator("onPlaylistPlayerStatus", moduleLogger);
    logger.info(`got event: ${JSON.stringify(status)}`);
    status.song = status.song || {};

    // sample status: {"song":{"title":"Strangelove","album":"Music For the Masses","artist":"Depeche Mode"},
    //                "playlist":{"name":"Peaceful"},"isPlaying":false,"isLoading":true}

    if (status.song.artist && status.song.artist !== this.state.song.artist) {
      logger.info(`artist changed from '${this.state.song.artist}' to '${status.song.artist}' - reloading album cover`);

      this.setState({song: {...this.state.song, albumArtUri: null}});
      getArtistImage(status.song.artist).then(imageUri => {
        logger.info(`got album art uri: ${imageUri}`);
        this.setState({song: {...this.state.song, albumArtUri: imageUri}});
      })
    }

    this.setState({
      isLoading: status.isLoading,
      loadingError: status.loadingError,
      isPlaying: status.isPlaying,
      song: {
        ...this.state.song,
        artist: status.song.artist,
        title: status.song.title,
        album: status.song.album,
      }
    });
  }

  render() {
    let logger = loggerCreator("render", moduleLogger);
    logger.info(`start`);

    let albumArt = require("../images/no-album2.png");
    logger.info(`uri: ${this.state.song.albumArtUri}`);
    if (this.state.song.albumArtUri) {
      albumArt = {uri: this.state.song.albumArtUri};
    }

    let loadingStatus = "Loading";
    if (this.state.song.title) {
      loadingStatus = `${loadingStatus}: ${this.state.song.artist} - ${this.state.song.title}`
    }

    let loadingError = "";
    if (this.state.loadingError) {
      loadingError = `Error occured, retrying: ${this.state.loadingError}`
    }

    return (
      <View style={styles.container}>
        <View style={styles.playlistNameView}>
          <Icon name="music" style={styles.playlistIcon}/>
          <Text>{this.props.playlistName}</Text>
        </View>
        <Choose>
          <When condition={!this.state.isLoading}>
            {/* Album art */}
            <View style={styles.albumArtView}>
              <Image style={styles.albumArt} source={albumArt}/>
            </View>
            {/* Controls */}
            <View style={styles.namesView}>
              <Text style={[styles.nameText, styles.titleText]}>{`${this.state.song.title}`}</Text>
              <Text style={[styles.nameText, styles.artistText]}>{`${this.state.song.artist}`}</Text>
              <Text style={[styles.nameText, styles.albumText]}>{`${this.state.song.album}`}</Text>
            </View>
            {/* Controls */}
            <View style={styles.controlsView}>
              <CircleButton size={100} onPress={() => this.onPressPlayPause()}
                            style={[styles.controlButtonPlay]}>
                <Icon name={this.state.isPlaying ? "pause" : "play"}
                      style={[styles.controlButtonText, this.state.isPlaying ? styles.controlTextPause : styles.controlTextPlay]}/>
              </CircleButton>
              <CircleButton size={60} onPress={() => this.onPressNext()}>
                <Icon name="step-forward"
                      style={styles.controlButtonText}/>
              </CircleButton>
            </View>
          </When>
          <Otherwise>
            <View style={styles.progressView}>
              <View style={styles.progressSpinner}>
                <ActivityIndicator size="large"/>
              </View>
              <View style={styles.progressStatus}>
                <Text>{loadingStatus}</Text>
                <Text style={styles.progressStatusError}>{loadingError}</Text>
              </View>
            </View>
          </Otherwise>
        </Choose>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    // remove width and height to override fixed static size
    width: null,
    height: null,
    alignItems: "center",
    alignSelf: "stretch"
  },
  // Playlist name
  playlistNameView: {
    flexDirection: "row",
    alignItems: "center",
    alignSelf: "stretch",
    marginBottom: 10,
    paddingTop: 5,
    paddingLeft: 5,
  },
  playlistIcon: {
    color: colors.SEMI_WHITE.rgbString(),
    marginRight: 5,
  },
  // Album
  albumArtView: {
    backgroundColor: "black",
    borderColor: colors.CYAN_DARK.rgbString(),
    borderWidth: 2,

    justifyContent: "center",
    alignItems: "center",

    marginBottom: 20
  },
  // Names (artist, title, album)
  namesView: {
    alignItems: "center",
    marginBottom: 10
  },
  nameText: {
    fontSize: fontSizes.LARGE,
    marginBottom: 10
  },
  artistText: {
    color: colors.CYAN_BRIGHT.rgbString()
  },
  albumArt: {
    width: 200,
    height: 200,
    resizeMode: "contain"
  },
  // Controls
  controlsView: {
    position: "absolute",
    bottom: 10,
    left: 0,
    right: 0,

    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
    paddingLeft: 80, // Causes the play button to be in the center
  },
  controlButtonText: {
    color: colors.SEMI_WHITE.rgbString(),
    fontSize: 40
  },
  controlTextPlay: {
    paddingLeft: 10
  },
  controlTextPause: {
    paddingLeft: 0
  },
  controlButtonPlay: {
    marginRight: 20
  },
  // Progress
  progressSpinner: {
    justifyContent: "flex-end",
    paddingBottom: 10,
    flex: 1,
  },
  progressStatus: {
    justifyContent: "flex-start",
    alignItems: "center",
    flex: 1,
  },
  progressStatusError: {
    color: "red"
  }
});

PlayerPage.propTypes = {
  navigator: React.PropTypes.instanceOf(Navigator).isRequired,
  playlistName: React.PropTypes.string.isRequired,
};
<|endoftext|>


<commit_before>
/**
 * Test dependencies.
 */

var mouth = require('..');
var assert = require('assert');

describe("compiler", function() {

	it('should return a compiled function', function() {
		var result = mouth('${ beep }').text;
		assert.equal(result({
			beep: 'boop'
		}), 'boop');
	});

	it('should return a compiled function from an advanced expresion', function() {
		var result = mouth('${ beep + boop }').text;
		assert.equal(result({
			beep: 'boop',
			boop: 'hello'
		}), 'boophello');
	});

	it('should return the expression properties', function() {
		var props = mouth('${beep} and ${boop}').props;
		assert.deepEqual(props, ['beep', 'boop']);
	})

	it('should compile complex expressions', function() {
		var result = mouth('${beep + " " + cb()}').text;
		assert.equal(result({
			beep: 'hello',
			cb: function() {
				return 'world!';
			}
		}), 'hello world!');
	});

});

//
// /\$([^{}]*)\{([^{}]*)\}/g

// describe("mixins", function() {

// 	var tmpl;
// 	beforeEach(function() {
// 		tmpl = mouth({
// 			link: 'home'
// 		});
// 	});

// 	it("should add middlware", function() {
// 		tmpl.use('path', function(str) {
// 			return '/path/' + this[str.trim()];
// 		});
// 		var result = tmpl('$path{link}');
// 		assert.equal(result, '/path/home');
// 	});

// });

describe("filters", function() {

});

<commit_msg>refactor basic test<commit_after>
/**
 * Test dependencies.
 */

var mouth = require('..');
var assert = require('assert');

describe('basic', function() {

	var interpolate =  mouth('${name}');

	it('should return a function', function() {
		assert.equal(typeof interpolate[0]);
	});

	it('should return a list of variable to interpolate', function() {
		assert.deepEqual(mouth[1], ['name']);
	});

	it('should interpolate variable', function() {
		assert.equal(interpolate[0]({
			name: 'olivier'
		}), 'olivier';)
	});

});
<|endoftext|>


<commit_before><commit_msg>Updated climate_model.js<commit_after>///@file climate_model.js
/// Climate model<|endoftext|>


<commit_before>// Load in dependencies
var expect = require('chai').expect;
var scriptUtils = require('./utils/script');

// Run our tests
// Anything with the `Identifier` that isn't a variable reference
// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
describe('ecma-variable-scope', function () {
  describe('marking up an AST with a MemberExpression', function () {
    scriptUtils.interpretFnAst(function () {
      var logger = {
        info: function () {}
      };
      logger.info('hello');
    });

    it('does not mark the `info` property with a `scope`', function () {
      // {Program} (ast) -> {logger.info} (body[1]) -> info (expression.callee.property)
      var identifier = this.ast.body[1].expression.callee.property;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });
  });

  describe('marking up an AST with an object Property', function () {
    scriptUtils.interpretFnAst(function () {
      var logger = {
        info: function () {}
      };
    });

    it('does not mark the `info` property with a `scope`', function () {
      // {Program} (ast) -> {var} (body[0]) -> {logger} (declarations[0].init) -> info (properties[0].key)
      var identifier = this.ast.body[0].declarations[0].init.properties[0].key;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });
  });

  describe('marking up an AST with a Label, Break, and Continue', function () {
    scriptUtils.interpretFnAst(function () {
      loop1:
      for (var i = 0; i < 10; i++) {
        if (true) {
          break loop1;
        } else {
          continue loop1;
        }
      }
    });

    it.only('does not mark the `label` identifier with a `scope`', function () {
      // {Program} (ast) -> {labeled statement} (body[0]) -> loop1 (label)
      var identifier = this.ast.body[0].label;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });

    it('does not mark the `break` identifier with a `scope`', function () {
      // {Program} (ast) -> {var} (body[0]) -> {logger} (declarations[0].init) -> info (properties[0].key)
      var identifier = this.ast.body[0].declarations[0].init.properties[0].key;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });

    it('does not mark the `continue` identifier with a `scope`', function () {
      // {Program} (ast) -> {var} (body[0]) -> {logger} (declarations[0].init) -> info (properties[0].key)
      var identifier = this.ast.body[0].declarations[0].init.properties[0].key;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });
  });

  // Double check all of these
  // label
  // break
  // continue
  // objectpattern key
});

// Edge cases
describe('ecma-variable-scope', function () {
  describe('marking up an AST with an ES5 get/set Property', function () {
    scriptUtils.interpretFnAst(function () {
      var logger = {
        get info() {
          // Code goes here
        }
      };
    });

    it('does not mark the `info` property with a `scope`', function () {
      // {Program} (ast) -> {var} (body[0]) -> {logger} (declarations[0].init) -> info (properties[0].key)
      var identifier = this.ast.body[0].declarations[0].init.properties[0].key;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });
  });
});
<commit_msg>Added assertions for breaks<commit_after>// Load in dependencies
var expect = require('chai').expect;
var scriptUtils = require('./utils/script');

// Run our tests
// Anything with the `Identifier` that isn't a variable reference
// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
describe('ecma-variable-scope', function () {
  describe('marking up an AST with a MemberExpression', function () {
    scriptUtils.interpretFnAst(function () {
      var logger = {
        info: function () {}
      };
      logger.info('hello');
    });

    it('does not mark the `info` property with a `scope`', function () {
      // {Program} (ast) -> {logger.info} (body[1]) -> info (expression.callee.property)
      var identifier = this.ast.body[1].expression.callee.property;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });
  });

  describe('marking up an AST with an object Property', function () {
    scriptUtils.interpretFnAst(function () {
      var logger = {
        info: function () {}
      };
    });

    it('does not mark the `info` property with a `scope`', function () {
      // {Program} (ast) -> {var} (body[0]) -> {logger} (declarations[0].init) -> info (properties[0].key)
      var identifier = this.ast.body[0].declarations[0].init.properties[0].key;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });
  });

  describe('marking up an AST with a Label, Break, and Continue', function () {
    scriptUtils.interpretFnAst(function () {
      loop1:
      for (var i = 0; i < 10; i++) {
        if (true) {
          break loop1;
        } else {
          continue loop1;
        }
      }
    });

    it('does not mark the `label` identifier with a `scope`', function () {
      // {Program} (ast) -> {labeled statement} (body[0]) -> loop1 (label)
      var identifier = this.ast.body[0].label;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });

    it.only('does not mark the `break` identifier with a `scope`', function () {
      // {Program} (ast) -> {labeled statement} (body[0]) -> {for} (body)
      //  -> {if} (body.body[0]) -> {break} (consequent.body[0]) -> loop1 {label}
      var identifier = this.ast.body[0].body.body.body[0].consequent.body[0].label;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });

    it('does not mark the `continue` identifier with a `scope`', function () {
      // {Program} (ast) -> {var} (body[0]) -> {logger} (declarations[0].init) -> info (properties[0].key)
      var identifier = this.ast.body[0].declarations[0].init.properties[0].key;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });
  });

  // Double check all of these
  // label
  // break
  // continue
  // objectpattern key
});

// Edge cases
describe('ecma-variable-scope', function () {
  describe('marking up an AST with an ES5 get/set Property', function () {
    scriptUtils.interpretFnAst(function () {
      var logger = {
        get info() {
          // Code goes here
        }
      };
    });

    it('does not mark the `info` property with a `scope`', function () {
      // {Program} (ast) -> {var} (body[0]) -> {logger} (declarations[0].init) -> info (properties[0].key)
      var identifier = this.ast.body[0].declarations[0].init.properties[0].key;
      expect(identifier).to.not.have.property('scope');
      expect(identifier).to.not.have.property('scopeInfo');
    });
  });
});
<|endoftext|>