<commit_before>import MediumEditor from 'medium-editor';
import AutoList from 'medium-editor-autolist';

export class NewPostCtrl {
    constructor($scope, $log, Upload, Cache, ToolbarService, PostService, ALL_CITIES) {
        angular.extend(this, {
            '$scope': $scope, 'Upload': Upload, 'Cache': Cache, 'ToolbarService': ToolbarService,
            'PostService': PostService, '$log': $log, 'ALL_CITIES': ALL_CITIES
        });
    }

    $onInit() {
        //todo: show a progressbar or loading icon while we setup and fetch data

        this.ALL_CITIES = [
            {
                name: "Lagos",
                country: "NG",
                lat: 12345,
                lon: 54332
            },
            {
                name: "Philadelphia",
                country: "US",
                lat: 342342,
                lon: 74534
            }
        ];
        this.ALL_CITIES = ["Lagos", "Abuja", "london", "austy"];

        this.$log.log("NewPost: Initializing...");
        this.PostService.ready().then(
            () => {
                this.initState();
                this.initBody();
                this.addToolbarButtons();
            },
            (err) => {
                // show a toaster with the error
                console.log("error: ", err);
            }
        )
    }

    progress(percent) {
        console.log("progress: ", percent);
    }

    categorySearch(query) {
        return query ? this.chips.allCategories.filter(this.createFilterFor(query)) : [];;
    }

    tagSearch(query) {
        return query ? this.chips.allTags.filter(this.createFilterFor(query)) : [];
    }

    citySearch(query) {
        return query ? this.ALL_CITIES.filter(city => {
            return city.name.toLowerCase().indexOf(query.toLowerCase()) !== -1
        }) : [];
    }

    /**
     * Create filter function for a query string
     */
    createFilterFor(query) {
        var lowercaseQuery = angular.lowercase(query);

        return function filterFn(taxonomy) {
            return (taxonomy.name.indexOf(lowercaseQuery) !== -1) ||
                (taxonomy.slug.indexOf(lowercaseQuery) !== -1);
        };

    }

    initState() {
        this.state = {
            categories: [],
            tags: []
        };
        this.chips = {
            categories: [],
            tags: [],
            allCategories: [],
            allTags: []
        }; // holds data for md-chips
        if(this.postId) {
            this.PostService.$restApi.posts().id(postId).get({embed: true}).then(
                post => {
                    angular.extend(this.state, post.rawVal());
                    this.featuredImage = this.state._embedded['wp:featuredmedia'][0].link;
                    this.authorName = this.state._embedded.author.name;
                    this.chips.categories = this.state._embedded['wp:term'].filter(t => t.taxonomy === 'category');
                    this.chips.tags = this.state._embedded['wp:term'].filter(t => t.taxonomy === 'post_tags');
                });
        }

        this.PostService.$restApi.categories().get().then((c) => {
            this.chips.allCategories = c.rawVal();
            this.list = c.rawVal().map(c => c.slug);
        });
        this.PostService.$restApi.tags().get().then(t => this.chips.allTags = t.rawVal());
    }

    initBody() {
        // for full editor options see https://github.com/yabwe/medium-editor/blob/master/OPTIONS.md
        let contentEditorOptions = {
            buttonLabels: 'fontawesome',
            targetBlank: true,
            placeholder: {
                text: 'Write your story here',
                hideOnClick: false
            },
            extensions: {
                'auotlist':  new AutoList()
            },
            autoLink: true,
            targetBlank: true,
            imageDragging: true,
            toolbar: {
                buttons: ['h2', 'h3', 'bold', 'italic', 'quote', 'anchor', 'image', 'outdent', 'indent'],
                sticky: true,
                static: true,
                align: 'center',
                updateOnEmptySelection: false
            }

        };

        this.contentEditor = new MediumEditor('.post-body', contentEditorOptions);
        this.contentEditor.subscribe('editableInput', () => this.state.content = this.contentEditor.getContent())

    }

    addToolbarButtons() {
        let cancelButton = {
            id: 'angularize_editor_cancel',
            title: 'Discard',
            icon: 'action-undo',
            position: 1,
            handler: () => this.discard()
        };
        let saveButton = {
            id: 'angularize_editor_save',
            title: 'Save Changes',
            icon: 'check',
            position: 2,
            handler: () => this.save()
        };
        let publishButton = {
            id: 'angularize_editor_publish',
            title: 'Save & Publish',
            icon: 'cursor',
            position: 3,
            handler: () => this.publish()
        };
        // todo: add a ToolbarService.create("id", "title", "icon", 1) function
        this.ToolbarService.add(cancelButton);
        this.ToolbarService.add(saveButton);
        // todo: only add if post is not published
        this.ToolbarService.add(publishButton);
    }

    /**
     * No changes are post to the server, but do we restore previous changes?
     * Is this like a delete function?
     * Will do both, if there are changes then discard otherwise delete
     */
    discard() {
        var confirm = this.$mdDialog.confirm()
            .title('Irreparable Damage Ahead')
            .textContent('Are you positively absolutely certain you want to discard all changes?')
            .ariaLabel('Confirm discard')
            .ok('Please do it!')
            .cancel('No, I changed my mind');
        this.$mdDialog.show(confirm).then(
            () => { // user agreed
                console.log("content: ", this.titleEditor.getContent(), this.titleEditor.serialize())
                this.titleEditor.resetContent();
                this.excerptEditor.resetContent();
                this.contentEditor.resetContent();
            }, () => { // user changed their mind
                // do nothing
            });
        // todo: later: if there are no changes to discard, replace with delete button
    }

    save() {
        if(this.state.id !== null && this.state.id !== undefined) {
            // todo: bind categories and tags
            // todo: extract and upload all embed resources
            this.state.categories = this.chips.categories.map(c => c.id);
            this.state.tags = this.chips.tags.map(t => t.id);
            this.PostService.$restApi.posts().id(this.state.id).post(this.state);
        }
        else {
            this.PostService.$restApi.posts().add(this.state).post().then(
                (post) => {
                    angular.extend(this.state, post.rawVal());
                    angular.extend(this.state, {title: this.state.title.rendered, excerpt: this.state.excerpt.rendered, content: this.state.content.rendered})
                    console.log("after save state: ", this.state)
                    this.postId = this.state.id;
                }
            )
        }
    }

    publish() {
        this.state.status = 'publish';
        this.save();
    }

    transformChip(chip) {
        // If it is an object, it's already a known chip
        if (angular.isObject(chip)) {
            return chip;
        }

        // Otherwise, create a new one
        // todo: ensure new chips have ids upon save
        return { name: chip, slug: chip.toLowerCase() }
    }
}

let NewPost = {
    controller: NewPostCtrl,
    template: require('./new-post.html'),
    bindings: {
        postId: '@'
    }
}

export default NewPost;<commit_msg>more todos<commit_after>import MediumEditor from 'medium-editor';
import AutoList from 'medium-editor-autolist';

export class NewPostCtrl {
    constructor($scope, $log, Upload, Cache, ToolbarService, PostService, ALL_CITIES) {
        angular.extend(this, {
            '$scope': $scope, 'Upload': Upload, 'Cache': Cache, 'ToolbarService': ToolbarService,
            'PostService': PostService, '$log': $log, 'ALL_CITIES': ALL_CITIES
        });
    }

    $onInit() {
        //todo: show a progressbar or loading icon while we setup and fetch data

        this.ALL_CITIES = [
            {
                name: "Lagos",
                country: "NG",
                lat: 12345,
                lon: 54332
            },
            {
                name: "Philadelphia",
                country: "US",
                lat: 342342,
                lon: 74534
            }
        ];
        this.ALL_CITIES = ["Lagos", "Abuja", "london", "austy"];

        this.$log.log("NewPost: Initializing...");
        this.PostService.ready().then(
            () => {
                this.initState();
                this.initBody();
                this.addToolbarButtons();
            },
            (err) => {
                // show a toaster with the error
                console.log("error: ", err);
            }
        )
    }

    progress(percent) {
        console.log("progress: ", percent);
    }

    categorySearch(query) {
        return query ? this.chips.allCategories.filter(this.createFilterFor(query)) : [];;
    }

    tagSearch(query) {
        return query ? this.chips.allTags.filter(this.createFilterFor(query)) : [];
    }

    citySearch(query) {
        return query ? this.ALL_CITIES.filter(city => {
            return city.name.toLowerCase().indexOf(query.toLowerCase()) !== -1
        }) : [];
    }

    /**
     * Create filter function for a query string
     */
    createFilterFor(query) {
        var lowercaseQuery = angular.lowercase(query);

        return function filterFn(taxonomy) {
            return (taxonomy.name.indexOf(lowercaseQuery) !== -1) ||
                (taxonomy.slug.indexOf(lowercaseQuery) !== -1);
        };

    }

    initState() {
        this.state = {
            categories: [],
            tags: []
        };
        this.chips = {
            categories: [],
            tags: [],
            allCategories: [],
            allTags: []
        }; // holds data for md-chips
        if(this.postId) {
            this.PostService.$restApi.posts().id(postId).get({embed: true}).then(
                post => {
                    angular.extend(this.state, post.rawVal());
                    this.featuredImage = this.state._embedded['wp:featuredmedia'][0].link;
                    this.authorName = this.state._embedded.author.name;
                    this.chips.categories = this.state._embedded['wp:term'].filter(t => t.taxonomy === 'category');
                    this.chips.tags = this.state._embedded['wp:term'].filter(t => t.taxonomy === 'post_tags');
                });
        }

        this.PostService.$restApi.categories().get().then((c) => {
            this.chips.allCategories = c.rawVal();
            this.list = c.rawVal().map(c => c.slug);
        });
        this.PostService.$restApi.tags().get().then(t => this.chips.allTags = t.rawVal());
    }

    initBody() {
        // for full editor options see https://github.com/yabwe/medium-editor/blob/master/OPTIONS.md
        let contentEditorOptions = {
            buttonLabels: 'fontawesome',
            targetBlank: true,
            placeholder: {
                text: 'Write your story here',
                hideOnClick: false
            },
            extensions: {
                // todo: inline AutoList please
                'auotlist':  new AutoList()
            },
            autoLink: true,
            targetBlank: true,
            imageDragging: true,
            toolbar: {
                buttons: ['h2', 'h3', 'bold', 'italic', 'quote', 'anchor', 'image', 'outdent', 'indent'],
                sticky: true,
                static: true,
                align: 'center',
                updateOnEmptySelection: false
            }

        };

        this.contentEditor = new MediumEditor('.post-body', contentEditorOptions);
        this.contentEditor.subscribe('editableInput', () => this.state.content = this.contentEditor.getContent())

    }

    addToolbarButtons() {
        let cancelButton = {
            id: 'angularize_editor_cancel',
            title: 'Discard',
            icon: 'action-undo',
            position: 1,
            handler: () => this.discard()
        };
        let saveButton = {
            id: 'angularize_editor_save',
            title: 'Save Changes',
            icon: 'check',
            position: 2,
            handler: () => this.save()
        };
        let publishButton = {
            id: 'angularize_editor_publish',
            title: 'Save & Publish',
            icon: 'cursor',
            position: 3,
            handler: () => this.publish()
        };
        // todo: add a ToolbarService.create("id", "title", "icon", 1) function
        this.ToolbarService.add(cancelButton);
        this.ToolbarService.add(saveButton);
        // todo: only add if post is not published
        this.ToolbarService.add(publishButton);
    }

    /**
     * No changes are post to the server, but do we restore previous changes?
     * Is this like a delete function?
     * Will do both, if there are changes then discard otherwise delete
     */
    discard() {
        var confirm = this.$mdDialog.confirm()
            .title('Irreparable Damage Ahead')
            .textContent('Are you positively absolutely certain you want to discard all changes?')
            .ariaLabel('Confirm discard')
            .ok('Please do it!')
            .cancel('No, I changed my mind');
        this.$mdDialog.show(confirm).then(
            () => { // user agreed
                console.log("content: ", this.titleEditor.getContent(), this.titleEditor.serialize())
                this.titleEditor.resetContent();
                this.excerptEditor.resetContent();
                this.contentEditor.resetContent();
            }, () => { // user changed their mind
                // do nothing
            });
        // todo: later: if there are no changes to discard, replace with delete button
    }

    save() {
        if(this.state.id !== null && this.state.id !== undefined) {
            // todo: bind categories and tags
            // todo: extract and upload all embed resources
            this.state.categories = this.chips.categories.map(c => c.id);
            this.state.tags = this.chips.tags.map(t => t.id);
            this.PostService.$restApi.posts().id(this.state.id).post(this.state);
        }
        else {
            this.PostService.$restApi.posts().add(this.state).post().then(
                (post) => {
                    angular.extend(this.state, post.rawVal());
                    angular.extend(this.state, {title: this.state.title.rendered, excerpt: this.state.excerpt.rendered, content: this.state.content.rendered})
                    console.log("after save state: ", this.state)
                    this.postId = this.state.id;
                }
            )
        }
    }

    publish() {
        this.state.status = 'publish';
        this.save();
    }

    transformChip(chip) {
        // If it is an object, it's already a known chip
        if (angular.isObject(chip)) {
            return chip;
        }

        // Otherwise, create a new one
        // todo: ensure new chips have ids upon save
        return { name: chip, slug: chip.toLowerCase() }
    }
}

let NewPost = {
    controller: NewPostCtrl,
    template: require('./new-post.html'),
    bindings: {
        postId: '@'
    }
}

export default NewPost;<|endoftext|>


<commit_before>angular.module('moped.library', [
  'moped.mopidy',
  'moped.util',
  'ngRoute'
])

.config(function config($routeProvider) {
  $routeProvider
    .when('/library/:uri/:name?', {
      templateUrl: 'library/directory.tpl.html',
      controller: 'DirectoryCtrl',
      title: 'Directories'
    });
})

.controller('LibraryMenuCtrl', function LibraryMenuController($scope, mopidyservice) {
  $scope.libraryDirectories = [];

  function loadLibraryDirectories() {
    mopidyservice.getLibrary().then(function(data) {
      $scope.libraryDirectories = data;
    }, function(data) {
      throw data;
    });
  }

  $scope.$on('mopidy:state:online', function() {
    loadLibraryDirectories();
  });
})

.controller('DirectoryCtrl', function DirectoryController($scope, $routeParams, mopidyservice, util) {
  $scope.directory = { name: util.urlDecode($routeParams.name), uri: util.urlDecode($routeParams.uri) };
  $scope.directories = [];
  $scope.playlists = [];
  $scope.tracks = [];

  mopidyservice.getDirectoryItems($scope.directory.uri).then(function(data) {
    var currentTrackIndex = 0;
    _.forEach(data, function (item) {
      if (item.type === 'directory') {
        item.fullName = $scope.directory.name + '/' + item.name;
        $scope.directories.push(item);
      }
      else if (item.type === 'playlist') {
        $scope.playlists.push(item);
      }
      else if (item.type === 'track') {
        (
          function(trackIndex) {
            mopidyservice.getTrack(item.uri).then(function (data) {
              if (data.length == 1) {
                $scope.tracks[trackIndex] = data[0];
              }
              else {
                throw new Error('Expected exactly one track in result.');
              }
            });
          }(currentTrackIndex++)
        );
      }
    });
  }, console.error.bind(console));

  $scope.$on('moped:playtrackrequest', function(event, track) {
    mopidyservice.playTrack(track, $scope.tracks);
  });
})

.directive("subDirectory", function () {
  return {
    restrict: "E",
    scope: { directory: '=' },
    templateUrl: 'library/subDirectory.tpl.html',
    replace:true
  };
});<commit_msg>Use library interface when browsing playlists via 'browse', see #25.<commit_after>angular.module('moped.library', [
  'moped.mopidy',
  'moped.util',
  'ngRoute'
])

.config(function config($routeProvider) {
  $routeProvider
    .when('/library/:uri/:name?', {
      templateUrl: 'library/directory.tpl.html',
      controller: 'DirectoryCtrl',
      title: 'Directories'
    });
})

.controller('LibraryMenuCtrl', function LibraryMenuController($scope, mopidyservice) {
  $scope.libraryDirectories = [];

  function loadLibraryDirectories() {
    mopidyservice.getLibrary().then(function(data) {
      $scope.libraryDirectories = data;
    }, function(data) {
      throw data;
    });
  }

  $scope.$on('mopidy:state:online', function() {
    loadLibraryDirectories();
  });
})

.controller('DirectoryCtrl', function DirectoryController($scope, $routeParams, mopidyservice, util) {
  $scope.directory = { name: util.urlDecode($routeParams.name), uri: util.urlDecode($routeParams.uri) };
  $scope.directories = [];
  $scope.playlists = [];
  $scope.tracks = [];

  mopidyservice.getDirectoryItems($scope.directory.uri).then(function(data) {
    var currentTrackIndex = 0;
    _.forEach(data, function (item) {
      if (item.type === 'directory' || item.type === 'playlist') {
        item.fullName = $scope.directory.name + '/' + item.name;
        $scope.directories.push(item);
      }
      // else if (item.type === 'playlist') {
      //   $scope.playlists.push(item);
      // }
      else if (item.type === 'track') {
        (
          function(trackIndex) {
            mopidyservice.getTrack(item.uri).then(function (data) {
              if (data.length == 1) {
                $scope.tracks[trackIndex] = data[0];
              }
              else {
                throw new Error('Expected exactly one track in result.');
              }
            });
          }(currentTrackIndex++)
        );
      }
    });
  }, console.error.bind(console));

  $scope.$on('moped:playtrackrequest', function(event, track) {
    mopidyservice.playTrack(track, $scope.tracks);
  });
})

.directive("subDirectory", function () {
  return {
    restrict: "E",
    scope: { directory: '=' },
    templateUrl: 'library/subDirectory.tpl.html',
    replace:true
  };
});<|endoftext|>


<commit_before>const {DModel, Gio} = imports.gi;

const ArticleHTMLRenderer = imports.framework.articleHTMLRenderer;
const Utils = imports.tests.utils;
const AppUtils = imports.framework.utils;
const SetMap = imports.framework.setMap;

describe('Article HTML Renderer', function () {
    let wikihow_model, wikibooks_model, wikipedia_model, wikisource_model;
    let all_models;
    let renderer;

    beforeEach(function () {
        Utils.register_gresource();
        let engine = DModel.Engine.get_default();
        const html = AppUtils.string_to_bytes('
dummy html
');
        spyOn(engine, 'get_domain').and.returnValue({
            read_uri: () => [true, html, 'text/html']
        });
        spyOn(Gio.Application, 'get_default').and.returnValue({
            get_web_overrides_css: function () { return []; },
        });

        renderer = new ArticleHTMLRenderer.ArticleHTMLRenderer();
        wikipedia_model = new DModel.Article({
            source_uri: 'http://en.wikipedia.org/wiki/When_It_Hits_the_Fan',
            original_uri: 'http://en.wikipedia.org/wiki/When_It_Hits_the_Fan',
            content_type: 'text/html',
            source: 'wikipedia',
            source_name: 'Wikipedia',
            license: 'CC-BY-SA 3.0',
            title: 'Wikipedia title',
            is_server_templated: false,
        });
        wikisource_model = new DModel.Article({
            source_uri: 'http://en.wikisource.org/wiki/When_It_Hits_the_Fan',
            original_uri: 'http://en.wikisource.org/wiki/When_It_Hits_the_Fan',
            content_type: 'text/html',
            source: 'wikisource',
            source_name: 'Wikibooks',
            license: 'CC-BY-SA 3.0',
            title: 'Wikibooks title',
            is_server_templated: false,
        });
        wikihow_model = new DModel.Article({
            source_uri: 'http://www.wikihow.com/Give-Passive-Aggressive-Gifts-for-Christmas',
            original_uri: 'http://www.wikihow.com/Give-Passive-Aggressive-Gifts-for-Christmas',
            content_type: 'text/html',
            source: 'wikihow',
            source_name: 'wikiHow',
            license: 'Owner permission',
            title: 'Wikihow & title',
            is_server_templated: false,
        });
        wikibooks_model = new DModel.Article({
            source_uri: 'http://en.wikibooks.org/wiki/When_It_Hits_the_Fan',
            original_uri: 'http://en.wikibooks.org/wiki/When_It_Hits_the_Fan',
            content_type: 'text/html',
            source: 'wikibooks',
            source_name: 'Wikibooks',
            license: 'CC-BY-SA 3.0',
            title: 'Wikibooks title',
            is_server_templated: false,
        });

        all_models = [
            wikipedia_model,
            wikisource_model,
            wikihow_model,
            wikibooks_model,
        ];
    });

    it('can render an article', function () {
        expect(renderer.render(wikihow_model)).toBeDefined();
    });

    it('does not render double html and body tags', function () {
        let html = renderer.render(wikibooks_model);
        expect(html.match(//g).length).toBe(1);
        expect(html.match(//g).length).toBe(1);
    });

    it('shows a title only when told to', function () {
        let html_no_title = renderer.render(wikibooks_model);
        renderer.show_title = true;
        let html_with_title = renderer.render(wikibooks_model);
        expect(html_with_title).toMatch('
Wikibooks title
');
        expect(html_no_title).not.toMatch('
Wikibooks title
');
    });

    it('links to creative commons license on wikimedia pages', function () {
        let html = renderer.render(wikibooks_model);
        expect(html).toMatch('license://CC-BY-SA%203.0');
    });

    it('links to original wikihow articles', function () {
        let html = renderer.render(wikihow_model);
        expect(html).toMatch('http://www.wikihow.com/Give-Passive-Aggressive-Gifts-for-Christmas');
    });

    it('includes correct css for article type', function () {
        expect(renderer.render(wikihow_model)).toMatch('wikihow.css');
        expect(renderer.render(wikibooks_model)).toMatch('wikimedia.css');
    });

    it('includes correct auxillary css on any model type', function () {
        all_models.forEach(m => {
            expect(renderer.render(m)).toMatch('clipboard.css');
            expect(renderer.render(m)).toMatch('share-actions.css');
        });
    });

    it('includes correct auxillary js on any model type', function () {
        all_models.forEach(m => {
            expect(renderer.render(m)).toMatch('jquery-min.js');
            expect(renderer.render(m)).toMatch('clipboard-manager.js');
            expect(renderer.render(m)).toMatch('crosslink.js');
            expect(renderer.render(m)).toMatch('chunk.js');
            expect(renderer.render(m)).toMatch('share-actions.js');
        });
    });

    it('includes custom css on any model type', function () {
        renderer.set_custom_css_files(['custom.css'])
        all_models.forEach(m =>
            expect(renderer.render(m)).toMatch('custom.css')
        );
    });

    ['facebook', 'twitter', 'whatsapp'].forEach(function (network) {
        it(`includes a share button for ${network}`, function () {
            expect(renderer.render(wikipedia_model))
                .toMatch(`messageHandlers.share_on_${network}.postMessage\\(0\\)`);
        });
    });

    it('escapes html special characters in title', function () {
        let html = renderer.render(wikihow_model);
        expect(html).toMatch('Wikihow & title');
    });

    it('includes article html unescaped', function () {
        let html = renderer.render(wikihow_model);
        expect(html).toMatch('
dummy html
');
    });

    it('includes scroll_manager.js only when told to', function () {
        let html_without_scroll_manager = renderer.render(wikibooks_model);
        renderer.enable_scroll_manager = true;
        let html_with_scroll_manager = renderer.render(wikibooks_model);

        expect(html_with_scroll_manager).toMatch('scroll-manager.js');
        expect(html_without_scroll_manager).not.toMatch('scroll-manager.js');
    });

    it('includes MathJax in rendered Wikipedia, Wikibooks, and Wikisource articles', function () {
        let html = renderer.render(wikibooks_model);
        expect(html).toMatch('


<commit_before>import Immutable from 'immutable';
const initialState = new Immutable.List();

module.exports = function(state = initialState, action) {
  if (action.type === 'SET_SAMPLES') {
    return Immutable.fromJS(action.samples);

  } else if (action.type === 'SET_IND_VAR_OPTION_ON_SAMPLE') {
    //needs to be hooked up properly, action is fired..
    var a = state.updateIn([action.sampleId, 'indVarStates'], function(map){
      return map.set(action.indVarId, action.optionIndex);
    });
    console.log('%c--> look here' , 'font-size:15px; padding-right:20px; color:white; background-color: black');
    console.dir(a.toJS);
    return a;

  } else if (action.type === 'CREATE_SAMPLE') {
     return state.set(action.sampleId, new Immutable.Map({
        indVarStates: new Immutable.Map()
      }));
  }
  return state;
};
<commit_msg>deleted console logs<commit_after>import Immutable from 'immutable';
const initialState = new Immutable.List();

module.exports = function(state = initialState, action) {
  if (action.type === 'SET_SAMPLES') {
    return Immutable.fromJS(action.samples);

  } else if (action.type === 'SET_IND_VAR_OPTION_ON_SAMPLE') {
    return state.updateIn([action.sampleId, 'indVarStates'], function(map){
      return map.set(action.indVarId, action.optionIndex);
    });

  } else if (action.type === 'CREATE_SAMPLE') {
     return state.set(action.sampleId, new Immutable.Map({
        indVarStates: new Immutable.Map()
      }));
  }
  return state;
};
<|endoftext|>


<commit_before>'use strict';

// Test specific configuration
// ===========================
module.exports = {
  // MongoDB connection options
  mongo: {
    uri: 'mongodb://localhost/ictsapp-test'
  }
};<commit_msg>Made a few changes to test environment<commit_after>'use strict';

// Test specific configuration
// ===========================
module.exports = {

  // Server IP
  ip:       undefined,

  // Server port
  port:     8080,

  // MongoDB connection options
  // example connection string: 'mongodb://username:password@host:port/database'
  mongo: {
    uri: 	'mongodb://localhost/ictsapp-test'
  },

  // fill database with sample user
  seedDB: true

};<|endoftext|>


<commit_before>'use strict';

// #####################################################################################################################
// #IMPORTS#
var autoprefixer = require('gulp-autoprefixer');
var gulp = require('gulp');
var gutil = require('gulp-util');
var gulpif = require('gulp-if');
var iconfont = require('gulp-iconfont');
var iconfontCss = require('gulp-iconfont-css');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var minifyCss = require('gulp-minify-css');
var jshint = require('gulp-jshint');
var jscs = require('gulp-jscs');

var argv = require('minimist')(process.argv.slice(2));

// #####################################################################################################################
// #SETTINGS#
var options = {
    debug: argv.debug
};
var PROJECT_ROOT = __dirname;
var PROJECT_PATH = {
    js: PROJECT_ROOT + '/js',
    sass: PROJECT_ROOT + '/sass',
    css: PROJECT_ROOT + '/css',
    icons: PROJECT_ROOT + '/fonts'
};

var PROJECT_PATTERNS = {
    js: [
        PROJECT_PATH.js + '/modules/*.js',
        '!' + PROJECT_PATH.js + '/modules/jquery.ui.*.js',
        '/gulpfile.js',
    ],
    sass: [
        PROJECT_PATH.sass + '/**/*.{scss,sass}'
    ],
    icons: [
        PROJECT_PATH.icons + '/src/*.svg'
    ]
};

// #####################################################################################################################
// #TASKS#
gulp.task('sass', function () {
    gulp.src(PROJECT_PATTERNS.sass)
        .pipe(gulpif(options.debug, sourcemaps.init()))
        .pipe(sass())
        .on('error', function (error) {
            gutil.log(gutil.colors.red('Error (' + error.plugin + '): ' + error.messageFormatted));
        })
        .pipe(autoprefixer({
            browsers: ['last 3 versions'],
            cascade: false
        }))
        .pipe(minifyCss())
        .pipe(gulpif(options.debug, sourcemaps.write()))
        .pipe(gulp.dest(PROJECT_PATH.css));
});

gulp.task('icons', function () {
    gulp.src(PROJECT_PATTERNS.icons)
    .pipe(iconfontCss({
        fontName: 'django-cms-iconfont',
        fontPath: '../fonts/',
        path: PROJECT_PATH.sass + '/libs/_iconfont.scss',
        targetPath: '../sass/components/_iconography.scss'
    }))
    .pipe(iconfont({
        fontName: 'django-cms-iconfont',
        normalize: true
    }))
    .on('glyphs', function(glyphs, options) {
        gutil.log.bind(glyphs, options);
    })
    .pipe(gulp.dest(PROJECT_PATH.icons));
});

gulp.task('lint', ['lint:javascript']);
gulp.task('lint:javascript', function () {
    // DOCS: http://jshint.com/docs/
    return gulp.src(PROJECT_PATTERNS.js)
        .pipe(jshint())
        .pipe(jscs())
        .on('error', function (error) {
            gutil.log('\n' + error.message);
            if (process.env.CI) {
                // Force the process to exit with error code
                process.exit(1);
            }
        })
        .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('watch', function () {
    gulp.watch(PROJECT_PATTERNS.sass, ['sass']);
    gulp.watch(PROJECT_PATTERNS.js, ['lint']);
});

gulp.task('default', ['sass', 'lint', 'watch']);
<commit_msg>lint gulpfile as well<commit_after>'use strict';

// #####################################################################################################################
// #IMPORTS#
var autoprefixer = require('gulp-autoprefixer');
var gulp = require('gulp');
var gutil = require('gulp-util');
var gulpif = require('gulp-if');
var iconfont = require('gulp-iconfont');
var iconfontCss = require('gulp-iconfont-css');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var minifyCss = require('gulp-minify-css');
var jshint = require('gulp-jshint');
var jscs = require('gulp-jscs');

var argv = require('minimist')(process.argv.slice(2));

// #####################################################################################################################
// #SETTINGS#
var options = {
    debug: argv.debug
};
var PROJECT_ROOT = __dirname;
var PROJECT_PATH = {
    js: PROJECT_ROOT + '/js',
    sass: PROJECT_ROOT + '/sass',
    css: PROJECT_ROOT + '/css',
    icons: PROJECT_ROOT + '/fonts'
};

var PROJECT_PATTERNS = {
    js: [
        PROJECT_PATH.js + '/modules/*.js',
        PROJECT_PATH.js + '/gulpfile.js',
        '!' + PROJECT_PATH.js + '/modules/jquery.ui.*.js'
    ],
    sass: [
        PROJECT_PATH.sass + '/**/*.{scss,sass}'
    ],
    icons: [
        PROJECT_PATH.icons + '/src/*.svg'
    ]
};

// #####################################################################################################################
// #TASKS#
gulp.task('sass', function () {
    gulp.src(PROJECT_PATTERNS.sass)
        .pipe(gulpif(options.debug, sourcemaps.init()))
        .pipe(sass())
        .on('error', function (error) {
            gutil.log(gutil.colors.red('Error (' + error.plugin + '): ' + error.messageFormatted));
        })
        .pipe(autoprefixer({
            browsers: ['last 3 versions'],
            cascade: false
        }))
        .pipe(minifyCss())
        .pipe(gulpif(options.debug, sourcemaps.write()))
        .pipe(gulp.dest(PROJECT_PATH.css));
});

gulp.task('icons', function () {
    gulp.src(PROJECT_PATTERNS.icons)
    .pipe(iconfontCss({
        fontName: 'django-cms-iconfont',
        fontPath: '../fonts/',
        path: PROJECT_PATH.sass + '/libs/_iconfont.scss',
        targetPath: '../sass/components/_iconography.scss'
    }))
    .pipe(iconfont({
        fontName: 'django-cms-iconfont',
        normalize: true
    }))
    .on('glyphs', function (glyphs, options) {
        gutil.log.bind(glyphs, options);
    })
    .pipe(gulp.dest(PROJECT_PATH.icons));
});

gulp.task('lint', ['lint:javascript']);
gulp.task('lint:javascript', function () {
    // DOCS: http://jshint.com/docs/
    return gulp.src(PROJECT_PATTERNS.js)
        .pipe(jshint())
        .pipe(jscs())
        .on('error', function (error) {
            gutil.log('\n' + error.message);
            if (process.env.CI) {
                // Force the process to exit with error code
                process.exit(1);
            }
        })
        .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('watch', function () {
    gulp.watch(PROJECT_PATTERNS.sass, ['sass']);
    gulp.watch(PROJECT_PATTERNS.js, ['lint']);
});

gulp.task('default', ['sass', 'lint', 'watch']);
<|endoftext|>


<commit_before>/*
 *  Copyright 2016 Hugo Mater
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

function PickLevelScene(engine)
{
    Scene.call(this);

    this.amountOfLevels = 9;
    this.level = 1;

    var centerLocation = new Vector(200,160);

    var arrow = new Sprite(Engine.currentGame[engine.gameTitle].gameAssets["Arrow"]);

    PickLevelScene.prototype.Update = function(input, dt)
    {
        Engine.PlayAudio("LayeRGB", "MenuMusic", 0.5);
        if(input.keyboard.keyPressed(KEY_CODE.SPACE))
        {
            Engine.StopAllGameAudio("LayeRGB");
            var scene = new GameScene(engine, this.level, centerLocation, new Vector(32,32));
            engine.switchScene(scene, false);
        }
        if(input.keyboard.keyPressed(KEY_CODE.ESCAPE))
        {
            var scene = new MenuScene(engine);
            engine.switchScene(scene, false);
        }

        if(input.keyboard.keyPressed(KEY_CODE.LEFT) || input.keyboard.keyPressed(KEY_CODE.a))
        {
            --this.level; if(this.level <= 0) this.level = 9;
        }else if(input.keyboard.keyPressed(KEY_CODE.RIGHT) || input.keyboard.keyPressed(KEY_CODE.d))
        {
            ++this.level; if(this.level > 9) this.level = 1;
        }
        Scene.prototype.Update.call(this, input, dt);
    };

    PickLevelScene.prototype.Draw = function(context)
    {
        context.save();
        context.fillStyle = "black";
        context.fillRect(0,0, Engine.currentGame[engine.gameTitle].originalResolution.x, Engine.currentGame[engine.gameTitle].originalResolution.y);
        context.restore();
        var level = LevelLoadingManager.getLevel(this.level);
        var layers = level.getLayers().length;
        var size = new Vector(16,16);
        var layersOffsetx = 0;
        var previewOffsetx = ((level.rowLength + 1) * size.x);

        if(layers > 1)
        {

            if(layers % 2 === 0)
            {
                layersOffsetx = (((level.rowLength / 2) + 1) * size.x);
            }else if(layers === 3)
            {
                layersOffsetx = previewOffsetx;
            }
        }

        for(var i = 0; i < layers; ++i)
        {
            context.save();
            context.shadowBlur = 10;
            context.shadowColor = "white";
            context.strokeStyle = "white";
            context.strokeRect(centerLocation.x - ((level.rowLength / 2) * size.x) - layersOffsetx + (i * previewOffsetx), centerLocation.y - ((level.columnLength / 2) * size.y), level.rowLength * size.x, level.columnLength * size.y);
            context.restore();

            var layer = level.getLayer(i);
            for(var j = 0; j < layer.length; ++j)
            {
                if(layer[j] instanceof Wall)
                {
                    var offsetx = ((layer[j].position.x - centerLocation.x)/ layer[j].sprite.size.x) * (size.x * 2) - layersOffsetx + (i * previewOffsetx);
                    var offsety = ((layer[j].position.y - centerLocation.y)/ layer[j].sprite.size.y) * (size.y * 2);

                    context.save();
                    layer[j].sprite.Draw(context, new Vector(centerLocation.x + offsetx, centerLocation.y + offsety), 0, new Vector(size.x/layer[j].sprite.size.x, size.y/layer[j].sprite.size.y));
                    context.restore();
                }
            }
        }

        arrow.Draw(context, new Vector(332, 240), 0, new Vector(0.6,0.6));

        context.save();
        context.font = "20px Tahoma";
        context.fillStyle = "white";
        context.fillText("Level " + this.level, 170, 245);
        context.restore();

        arrow.Draw(context, new Vector(68, 240), 180, new Vector(0.6,0.6));

        Scene.prototype.Draw.call(this, context);
    };

    LevelLoadingManager.LoadLevels(LevelLoadingManager.LoadLevelData(), centerLocation, new Vector(32, 32));
}

PickLevelScene.prototype = Object.create(Scene.prototype);

<commit_msg>Clean up<commit_after>/*
 *  Copyright 2016 Hugo Mater
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

function PickLevelScene(engine)
{
    Scene.call(this);

    this.amountOfLevels = 9;
    this.level = 1;

    var centerLocation = new Vector(200,160);

    var arrow = new Sprite(Engine.currentGame[engine.gameTitle].gameAssets["Arrow"]);

    PickLevelScene.prototype.Update = function(input, dt)
    {
        Engine.PlayAudio("LayeRGB", "MenuMusic", 0.5);
        if(input.keyboard.keyPressed(KEY_CODE.SPACE))
        {
            Engine.StopAllGameAudio("LayeRGB");
            var scene = new GameScene(engine, this.level, centerLocation, new Vector(32,32));
            engine.switchScene(scene, false);
        }
        if(input.keyboard.keyPressed(KEY_CODE.ESCAPE))
        {
            var scene = new MenuScene(engine);
            engine.switchScene(scene, false);
        }

        if(input.keyboard.keyPressed(KEY_CODE.LEFT) || input.keyboard.keyPressed(KEY_CODE.a))
        {
            --this.level; if(this.level <= 0) this.level = 9;
        }else if(input.keyboard.keyPressed(KEY_CODE.RIGHT) || input.keyboard.keyPressed(KEY_CODE.d))
        {
            ++this.level; if(this.level > 9) this.level = 1;
        }
        Scene.prototype.Update.call(this, input, dt);
    };

    PickLevelScene.prototype.Draw = function(context)
    {
        context.save();
        context.fillStyle = "black";
        context.fillRect(0,0, Engine.currentGame[engine.gameTitle].originalResolution.x, Engine.currentGame[engine.gameTitle].originalResolution.y);
        context.restore();
        var level = LevelLoadingManager.getLevel(this.level);
        var layers = level.getLayers().length;
        var size = new Vector(16,16);
        var layersOffsetx = 0;
        var previewOffsetx = ((level.rowLength + 1) * size.x);

        if(layers > 1)
        {
            if(layers % 2 === 0)
            {
                layersOffsetx = (((level.rowLength / 2) + 1) * size.x);
            }else if(layers === 3)
            {
                layersOffsetx = previewOffsetx;
            }
        }

        for(var i = 0; i < layers; ++i)
        {
            context.save();
            context.shadowBlur = 10;
            context.shadowColor = "white";
            context.strokeStyle = "white";
            context.strokeRect(centerLocation.x - ((level.rowLength / 2) * size.x) - layersOffsetx + (i * previewOffsetx), centerLocation.y - ((level.columnLength / 2) * size.y), level.rowLength * size.x, level.columnLength * size.y);
            context.restore();

            var layer = level.getLayer(i);
            for(var j = 0; j < layer.length; ++j)
            {
                if(layer[j] instanceof Wall)
                {
                    var offsetx = ((layer[j].position.x - centerLocation.x)/ layer[j].sprite.size.x) * (size.x * 2) - layersOffsetx + (i * previewOffsetx);
                    var offsety = ((layer[j].position.y - centerLocation.y)/ layer[j].sprite.size.y) * (size.y * 2);

                    context.save();
                    layer[j].sprite.Draw(context, new Vector(centerLocation.x + offsetx, centerLocation.y + offsety), 0, new Vector(size.x/layer[j].sprite.size.x, size.y/layer[j].sprite.size.y));
                    context.restore();
                }
            }
        }

        arrow.Draw(context, new Vector(332, 240), 0, new Vector(0.6,0.6));

        context.save();
        context.font = "20px Tahoma";
        context.fillStyle = "white";
        context.fillText("Level " + this.level, 170, 245);
        context.restore();

        arrow.Draw(context, new Vector(68, 240), 180, new Vector(0.6,0.6));

        Scene.prototype.Draw.call(this, context);
    };

    LevelLoadingManager.LoadLevels(LevelLoadingManager.LoadLevelData(), centerLocation, new Vector(32, 32));
}

PickLevelScene.prototype = Object.create(Scene.prototype);

<|endoftext|>


<commit_before>import {
  IdentityActions, IdentityReducer
} from '../../../../app/js/profiles/store/identity'

const initialState = {
  current: {
    domainName: null,
    profile: null,
    verifications: null
  },
  localIdentities: {},
  namesOwned: [],
  createProfileError: null
}

const DEFAULT_PROFILE = {
  '@type': 'Person',
  '@context': 'http://schema.org'
}

describe('Identity Store: IdentityReducer', () => {
  it('should return the proper initial state', () => {
    assert.deepEqual(
      IdentityReducer(undefined, {}),
      initialState)
  })

  it('should update the current identity with the proper values', () => {
    const profile = {
      key: 'value'
    }
    const verifications = {
      verified: true
    }
    const action = IdentityActions.updateCurrentIdentity('satoshi.id', profile, verifications)
    const expectedState = {
      current: {
        domainName: 'satoshi.id',
        profile: { key: 'value' },
        verifications: { verified: true }
      },
      localIdentities: {},
      namesOwned: [],
      createProfileError: null
    }
    const actualState = IdentityReducer(undefined, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should create a new identity that is unregistered & unverified', () => {
    const action = IdentityActions.createNewIdentity('satoshi.id', '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC')
    const expectedState = {
      current: {
        domainName: null,
        profile: null,
        verifications: null
      },
      localIdentities: {
        'satoshi.id': {
          domainName: 'satoshi.id',
          profile: DEFAULT_PROFILE,
          verifications: [],
          registered: false,
          ownerAddress: '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC'
        }
      },
      namesOwned: [],
      createProfileError: null
    }
    const actualState = IdentityReducer(undefined, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should update the collection of local identites and list of names owned', () => {
    const namesOwned = ['satoshi.id']
    const localIdentities = {
      'satoshi.id': {
        domainName: 'satoshi.id',
        profile: DEFAULT_PROFILE,
        verifications: [],
        registered: false
      }
    }
    const action = IdentityActions.updateOwnedIdentities(localIdentities, namesOwned)
    const expectedState = {
      current: {
        domainName: null,
        profile: null,
        verifications: null
      },
      localIdentities: {
        'satoshi.id': {
          domainName: 'satoshi.id',
          profile: DEFAULT_PROFILE,
          verifications: [],
          registered: false
        }
      },
      namesOwned: ['satoshi.id'],
      createProfileError: null
    }
    const actualState = IdentityReducer(undefined, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should update the profile of the specified name', () => {
    const profile = {
      key: 'value'
    }
    const action = IdentityActions.updateProfile('satoshi.id', profile)
    const expectedState = {
      current: {
        domainName: null,
        profile: null,
        verifications: null
      },
      localIdentities: {
        'satoshi.id': {
          profile: {
            key: 'value'
          }
        }
      },
      namesOwned: [],
      createProfileError: null
    }
    const actualState = IdentityReducer(undefined, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should move the identity from owner address key to domain key', () => {
    const initialState = {
      localIdentities: {
        '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC': {
          profile: {
            key: 'value'
          },
          ownerAddress: '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC'
        }
      },
      createProfileError: null
    }

    const expectedState = {
      localIdentities: {
        'satoshi.id': {
          profile: {
            key: 'value'
          },
          ownerAddress: '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC',
          domainName: 'satoshi.id'
        }
      },
      createProfileError: null
    }
    const action = IdentityActions.addUsername('satoshi.id', '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC')

    const actualState = IdentityReducer(initialState, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should create a create new profile error', () => {
    const expectedState = {
      current: {
        domainName: null,
        profile: null,
        verifications: null
      },
      localIdentities: {},
      namesOwned: [],
      createProfileError: 'error'
    }
    const action = IdentityActions.createNewProfileError('error')

    const actualState = IdentityReducer(initialState, action)
    assert.deepEqual(actualState, expectedState)
  })
})
<commit_msg>Update tests for the fix of issue #670<commit_after>import {
  IdentityActions, IdentityReducer
} from '../../../../app/js/profiles/store/identity'

const initialState = {
  current: {
    domainName: null,
    profile: null,
    verifications: null
  },
  localIdentities: {},
  namesOwned: [],
  createProfileError: null
}

const DEFAULT_PROFILE = {
  '@type': 'Person',
  '@context': 'http://schema.org'
}

describe('Identity Store: IdentityReducer', () => {
  it('should return the proper initial state', () => {
    assert.deepEqual(
      IdentityReducer(undefined, {}),
      initialState)
  })

  it('should update the current identity with the proper values', () => {
    const profile = {
      key: 'value'
    }
    const verifications = {
      verified: true
    }
    const action = IdentityActions.updateCurrentIdentity('satoshi.id', profile, verifications)
    const expectedState = {
      current: {
        domainName: 'satoshi.id',
        profile: { key: 'value' },
        verifications: { verified: true }
      },
      localIdentities: {},
      namesOwned: [],
      createProfileError: null
    }
    const actualState = IdentityReducer(undefined, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should create a new identity that is unregistered & unverified', () => {
    const action = IdentityActions.createNewIdentity('satoshi.id', '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC')
    const expectedState = {
      current: {
        domainName: null,
        profile: null,
        verifications: null
      },
      localIdentities: {
        'satoshi.id': {
          domainName: 'satoshi.id',
          profile: DEFAULT_PROFILE,
          verifications: [],
          registered: false,
          ownerAddress: '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC'
        }
      },
      namesOwned: [],
      createProfileError: null
    }
    const actualState = IdentityReducer(undefined, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should update the collection of local identites and list of names owned', () => {
    const namesOwned = ['satoshi.id']
    const localIdentities = {
      'satoshi.id': {
        domainName: 'satoshi.id',
        profile: DEFAULT_PROFILE,
        verifications: [],
        registered: false
      }
    }
    const action = IdentityActions.updateOwnedIdentities(localIdentities, namesOwned)
    const expectedState = {
      current: {
        domainName: null,
        profile: null,
        verifications: null
      },
      localIdentities: {
        'satoshi.id': {
          domainName: 'satoshi.id',
          profile: DEFAULT_PROFILE,
          verifications: [],
          registered: false
        }
      },
      namesOwned: ['satoshi.id'],
      createProfileError: null
    }
    const actualState = IdentityReducer(undefined, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should update the profile of the specified name', () => {
    const profile = {
      key: 'value'
    }
    const action = IdentityActions.updateProfile('satoshi.id', profile)
    const expectedState = {
      current: {
        domainName: null,
        profile: null,
        verifications: null
      },
      localIdentities: {
        'satoshi.id': {
          profile: {
            key: 'value'
          }
        }
      },
      namesOwned: [],
      createProfileError: null
    }
    const actualState = IdentityReducer(undefined, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should move the identity from owner address key to domain key', () => {
    const initialState = {
      localIdentities: {
        '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC': {
          profile: {
            key: 'value'
          },
          ownerAddress: '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC'
        }
      },
      createProfileError: null
    }

    const expectedState = {
      localIdentities: {
        'satoshi.id': {
          profile: {
            key: 'value'
          },
          ownerAddress: '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC',
          domainName: 'satoshi.id'
        }
      },
      createProfileError: null
    }
    const action = IdentityActions.addUsername('satoshi.id', '17jxDTPDx51CTga1Sw3ezGQKYcJysPNeQC')

    const actualState = IdentityReducer(initialState, action)
    assert.deepEqual(actualState, expectedState)
  })

  it('should create a create new profile error', () => {
    const error = new String('error')
    const expectedState = {
      current: {
        domainName: null,
        profile: null,
        verifications: null
      },
      localIdentities: {},
      namesOwned: [],
      createProfileError: error
    }
    const action = IdentityActions.createNewProfileError(error)

    const actualState = IdentityReducer(initialState, action)
    assert.deepEqual(actualState, expectedState)
  })
})
<|endoftext|>


<commit_before>/*global window*/
"use strict";

(function() {
  /**
   * Represents a single color
   *
   * @param {string} color - A representation of a color as RGB(A),HSL(A),Hexadecimal(with/without hash)
   *
   * @returns {void|false} Returns false on parsing error
   */
  var Color = function(color) {
    var red = null,
         green = null,
         blue = null,
         alpha = null,
         valid = false;

    /**
     * Parse out what we've been given coming in
     */
    var parseColor = function(color) {
      if ( color.match(/^#?[0-9a-f]{6}$/i) ) {
        if ( color.length == 7 ) {
          color = color.substr(1);
        }
        red = parseInt(color.substr(0,2), 16).toString(10);
        green = parseInt(color.substr(2,2), 16).toString(10);
        blue = parseInt(color.substr(4,2), 16).toString(10);
        alpha = 1;

        // successful parsing, continue
        valid = true;
        return true;
      } else {
        valid = false;
        return false;
      }
    };

    if ( !parseColor(color) ) {
      valid = false;
    }

    this.isValid = function() {
      return valid;
    };

    /**
     * Gets the RGB(A) representation of this color
     *
     * @param {boolean} withAlpha - Whether or not to include alpha in the outputted string
     *
     * @returns {string} the RGB(A) representation of this color
     */
    this.getRGB = function(withAlpha) {
      if ( withAlpha === true ) {
        return "rgba(" + red + "," + green + "," + blue + "," + alpha.toFixed(2) + ")";
      } else {
        return "rgb(" + red + "," + green + "," + blue + ")";
      }
    };

    this.getRed = function() {
      return red;
    };

    this.getGreen = function() {
      return green;
    };

    this.getBlue = function() {
      return blue;
    };

    /**
     * Gets the HSL representation of this color
     *
     * @param {boolean} withAlpha - Whether or not to include alpha in the outputted string
     *
     * @returns {string} the HSL(A) representation of this color
     */
    this.getHSL = function(withAlpha) {
    };

    /**
     * Gets the Hexadecimal representation of this color
     *
     * @param {boolean} withHash - Whether or not to include the hash mark at the front of the code
     *
     * @returns {string} the Hexadecimal representation of this color
     */
    this.getHex = function(withHash) {
    };

    /**
     * Retuns a new Colors.Color object that is the complement color of this one
     *
     * @returns {Colors.Color} the complement of this color
     */
    this.getComplement = function() {
    };

    /**
     * Retuns a new Colors.Color object that is the greyscale of this one
     *
     * @returns {Colors.Color} the greyscale color of this one
     */
    this.getGreyscal = function() {
    };

    /**
     * mix another color into this one
     *
     * @param {Colors.Color} mixin - The color you want to mix in
     * @param {double} amount - Between 0 and 1, how much you want to mix it in (defaults to 0.5)
     *
     * @returns {void}
     */
    this.mix = function(mixin, amount) {
    };

    /**
     * lighten this color
     *
     * @param {double} amount - Between 0 and 1, how much lighter do you want this? (defaults to 0.05 or 1/20th of a step)
     *
     * @returns {void}
     */
    this.lighten = function(amount) {
    };

    /**
     * darken this color
     *
     * @param {double} amount - Between 0 and 1, how much darker do you want this? (defaults to 0.05 or 1/20th of a step)
     *
     * @returns {void}
     */
    this.darken = function(amount) {
    };

    /**
     * is this a "dark" color?
     *
     * @returns {boolean} Whether or not this is a "dark" color
     */
    this.isDark = function() {
    };

    /**
     * is this a "light" color?
     *
     * @returns {boolean} Whether or not this is a "light" color
     */
    this.isLight = function() {
    };

    /**
     * is this a "warm" color?
     *
     * @returns {boolean} Whether or not this is a "warm" color
     */
    this.isWarm = function() {
    };

    /**
     * is this a "cold" color?
     *
     * @returns {boolean} Whether or not this is a "cold" color
     */
    this.isCold = function() {
    };

    /**
     * randomizes the color
     *
     * @returns {void}
     */
    this.randomize = function() {
    };
  };

  var Colors = function() {
    // Assign our internal color class
    this.Color = Color;

    return this;
  };

  if ( !window.Colors ) {
    window.Colors = new Colors();
  }
})();
<commit_msg>this toString ain't needed<commit_after>/*global window*/
"use strict";

(function() {
  /**
   * Represents a single color
   *
   * @param {string} color - A representation of a color as RGB(A),HSL(A),Hexadecimal(with/without hash)
   *
   * @returns {void|false} Returns false on parsing error
   */
  var Color = function(color) {
    var red = null,
         green = null,
         blue = null,
         alpha = null,
         valid = false;

    /**
     * Parse out what we've been given coming in
     */
    var parseColor = function(color) {
      if ( color.match(/^#?[0-9a-f]{6}$/i) ) {
        if ( color.length == 7 ) {
          color = color.substr(1);
        }
        red = parseInt(color.substr(0,2), 16);
        green = parseInt(color.substr(2,2), 16);
        blue = parseInt(color.substr(4,2), 16);
        alpha = 1;

        // successful parsing, continue
        valid = true;
        return true;
      } else {
        valid = false;
        return false;
      }
    };

    if ( !parseColor(color) ) {
      valid = false;
    }

    this.isValid = function() {
      return valid;
    };

    /**
     * Gets the RGB(A) representation of this color
     *
     * @param {boolean} withAlpha - Whether or not to include alpha in the outputted string
     *
     * @returns {string} the RGB(A) representation of this color
     */
    this.getRGB = function(withAlpha) {
      if ( withAlpha === true ) {
        return "rgba(" + red + "," + green + "," + blue + "," + alpha.toFixed(2) + ")";
      } else {
        return "rgb(" + red + "," + green + "," + blue + ")";
      }
    };

    this.getRed = function() {
      return red;
    };

    this.getGreen = function() {
      return green;
    };

    this.getBlue = function() {
      return blue;
    };

    /**
     * Gets the HSL representation of this color
     *
     * @param {boolean} withAlpha - Whether or not to include alpha in the outputted string
     *
     * @returns {string} the HSL(A) representation of this color
     */
    this.getHSL = function(withAlpha) {
    };

    /**
     * Gets the Hexadecimal representation of this color
     *
     * @param {boolean} withHash - Whether or not to include the hash mark at the front of the code
     *
     * @returns {string} the Hexadecimal representation of this color
     */
    this.getHex = function(withHash) {
    };

    /**
     * Retuns a new Colors.Color object that is the complement color of this one
     *
     * @returns {Colors.Color} the complement of this color
     */
    this.getComplement = function() {
    };

    /**
     * Retuns a new Colors.Color object that is the greyscale of this one
     *
     * @returns {Colors.Color} the greyscale color of this one
     */
    this.getGreyscal = function() {
    };

    /**
     * mix another color into this one
     *
     * @param {Colors.Color} mixin - The color you want to mix in
     * @param {double} amount - Between 0 and 1, how much you want to mix it in (defaults to 0.5)
     *
     * @returns {void}
     */
    this.mix = function(mixin, amount) {
    };

    /**
     * lighten this color
     *
     * @param {double} amount - Between 0 and 1, how much lighter do you want this? (defaults to 0.05 or 1/20th of a step)
     *
     * @returns {void}
     */
    this.lighten = function(amount) {
    };

    /**
     * darken this color
     *
     * @param {double} amount - Between 0 and 1, how much darker do you want this? (defaults to 0.05 or 1/20th of a step)
     *
     * @returns {void}
     */
    this.darken = function(amount) {
    };

    /**
     * is this a "dark" color?
     *
     * @returns {boolean} Whether or not this is a "dark" color
     */
    this.isDark = function() {
    };

    /**
     * is this a "light" color?
     *
     * @returns {boolean} Whether or not this is a "light" color
     */
    this.isLight = function() {
    };

    /**
     * is this a "warm" color?
     *
     * @returns {boolean} Whether or not this is a "warm" color
     */
    this.isWarm = function() {
    };

    /**
     * is this a "cold" color?
     *
     * @returns {boolean} Whether or not this is a "cold" color
     */
    this.isCold = function() {
    };

    /**
     * randomizes the color
     *
     * @returns {void}
     */
    this.randomize = function() {
    };
  };

  var Colors = function() {
    // Assign our internal color class
    this.Color = Color;

    return this;
  };

  if ( !window.Colors ) {
    window.Colors = new Colors();
  }
})();
<|endoftext|>


<commit_before>import { blizzardApiResponseLatencyHistogram } from 'helpers/metrics';
import RequestTimeoutError from 'helpers/request/RequestTimeoutError';
import RequestSocketTimeoutError from 'helpers/request/RequestSocketTimeoutError';
import RequestConnectionResetError from 'helpers/request/RequestConnectionResetError';
import RequestUnknownError from 'helpers/request/RequestUnknownError';
import retryingRequest from './retryingRequest';

const availableRegions = {
  eu: 'ru_RU',
  us: 'en_US',
  tw: 'zh_TW',
  kr: 'ko_KR',
};

const USER_AGENT = process.env.USER_AGENT;
const clientToken = {};

const get = (url, metricLabels, region, accessToken) => {
  let end;
  return retryingRequest({
    url,
    headers: {
      'User-Agent': USER_AGENT,
    },
    gzip: true,
    // we'll be making several requests, so pool connections
    forever: true,
    timeout: 4000, // ms after which to abort the request, when a character is uncached it's not uncommon to take ~2sec
    shouldRetry: error => {
      const { statusCode } = error;
      //generally 404 should probably just not be retried
      return statusCode !== 404;
    },
    onBeforeAttempt: () => {
      end = blizzardApiResponseLatencyHistogram.startTimer(metricLabels);
    },
    onFailure: async err => {
      if (err.statusCode === 401) {
        // if the request in unauthorized, try renewing
        // the battle net creds
        delete clientToken[region];
        getAccessToken(region);
        end({
          statusCode: 401,
        });
      } else if (err instanceof RequestTimeoutError) {
        end({
          statusCode: 'timeout',
        });
      } else if (err instanceof RequestSocketTimeoutError) {
        end({
          statusCode: 'socket timeout',
        });
      } else if (err instanceof RequestConnectionResetError) {
        end({
          statusCode: 'connection reset',
        });
      } else if (err instanceof RequestUnknownError) {
        end({
          statusCode: 'unknown',
        });
      } else {
        end({
          statusCode: err.statusCode,
        });
      }
      return null;
    },
    onSuccess: () => {
      end({
        statusCode: 200,
      });
    },
  });
};
const makeBaseUrl = region => `https://${region}.api.blizzard.com`;

const getAccessToken = async region => {
  let end;
  const now = new Date();
  if (clientToken[region] && clientToken[region].accessToken && clientToken[region].expires > now) {
    return clientToken[region].accessToken;
  }

  const url = `https://${region}.battle.net/oauth/token?grant_type=client_credentials&client_id=${process.env.BATTLE_NET_API_CLIENT_ID}&client_secret=${
    process.env.BATTLE_NET_API_CLIENT_SECRET
  }`;

  const tokenRequest = await retryingRequest({
    url,
    headers: {
      'User-Agent': USER_AGENT,
    },
    gzip: true,
    // we'll be making several requests, so pool connections
    forever: true,
    timeout: 4000,
    shouldRetry: error => {
      return error.statusCode !== 404;
    },
    onBeforeAttempt: () => {
      end = blizzardApiResponseLatencyHistogram.startTimer({
        category: 'token',
        region,
      });
    },
    onFailure: err => {
      if (err instanceof RequestTimeoutError) {
        end({
          statusCode: 'timeout',
        });
      } else if (err instanceof RequestSocketTimeoutError) {
        end({
          statusCode: 'socket timeout',
        });
      } else if (err instanceof RequestConnectionResetError) {
        end({
          statusCode: 'connection reset',
        });
      } else if (err instanceof RequestUnknownError) {
        end({
          statusCode: 'unknown',
        });
      } else {
        end({
          statusCode: err.statusCode,
        });
      }
    },
    onSuccess: () => {
      end({
        statusCode: 200,
      });
    },
  });

  const tokenData = JSON.parse(tokenRequst);
  const expireDate = now.setSeconds(now.getSeconds() + tokenData.expires_in);

  clientToken[region] = {
    accessToken: tokenData.access_token,
    expires: expireDate,
  };

  return clientToken[region].accessToken;
};

export async function fetchCharacter(region, realm, name, fields = '') {
  region = region.toLowerCase();
  if (!availableRegions[region]) {
    throw new Error('Region not recognized.');
  }
  const accessToken = await getAccessToken(region);
  const url = `${makeBaseUrl(region)}/wow/character/${encodeURIComponent(realm)}/${encodeURIComponent(name)}?locale=${availableRegions[region]}&fields=${fields}`;

  return get(
    url,
    {
      category: 'character',
      region,
    },
    region,
    accessToken,
  );
}

export async function fetchItem(region, itemId) {
  region = region.toLowerCase();
  if (!availableRegions[region]) {
    throw new Error('Region not recognized.');
  }
  const accessToken = await getAccessToken(region);
  const url = `${makeBaseUrl(region)}/wow/item/${encodeURIComponent(itemId)}?locale=${availableRegions[region]}`;

  return get(
    url,
    {
      category: 'item',
      region,
    },
    region,
    accessToken,
  );
}

export async function fetchSpell(region, spellId) {
  region = region.toLowerCase();
  if (!availableRegions[region]) {
    throw new Error('Region not recognized.');
  }
  const accessToken = await getAccessToken(region);
  const url = `${makeBaseUrl(region)}/wow/spell/${encodeURIComponent(spellId)}?locale=${availableRegions[region]}`;

  return get(
    url,
    {
      category: 'spell',
      region,
    },
    region,
    accessToken,
  );
}
<commit_msg>fix build<commit_after>import { blizzardApiResponseLatencyHistogram } from 'helpers/metrics';
import RequestTimeoutError from 'helpers/request/RequestTimeoutError';
import RequestSocketTimeoutError from 'helpers/request/RequestSocketTimeoutError';
import RequestConnectionResetError from 'helpers/request/RequestConnectionResetError';
import RequestUnknownError from 'helpers/request/RequestUnknownError';
import retryingRequest from './retryingRequest';

const availableRegions = {
  eu: 'ru_RU',
  us: 'en_US',
  tw: 'zh_TW',
  kr: 'ko_KR',
};

const USER_AGENT = process.env.USER_AGENT;
const clientToken = {};

const get = (url, metricLabels, region, accessToken) => {
  let end;
  return retryingRequest({
    url,
    headers: {
      'User-Agent': USER_AGENT,
    },
    gzip: true,
    // we'll be making several requests, so pool connections
    forever: true,
    timeout: 4000, // ms after which to abort the request, when a character is uncached it's not uncommon to take ~2sec
    shouldRetry: error => {
      const { statusCode } = error;
      //generally 404 should probably just not be retried
      return statusCode !== 404;
    },
    onBeforeAttempt: () => {
      end = blizzardApiResponseLatencyHistogram.startTimer(metricLabels);
    },
    onFailure: async err => {
      if (err.statusCode === 401) {
        // if the request in unauthorized, try renewing
        // the battle net creds
        delete clientToken[region];
        getAccessToken(region);
        end({
          statusCode: 401,
        });
      } else if (err instanceof RequestTimeoutError) {
        end({
          statusCode: 'timeout',
        });
      } else if (err instanceof RequestSocketTimeoutError) {
        end({
          statusCode: 'socket timeout',
        });
      } else if (err instanceof RequestConnectionResetError) {
        end({
          statusCode: 'connection reset',
        });
      } else if (err instanceof RequestUnknownError) {
        end({
          statusCode: 'unknown',
        });
      } else {
        end({
          statusCode: err.statusCode,
        });
      }
      return null;
    },
    onSuccess: () => {
      end({
        statusCode: 200,
      });
    },
  });
};
const makeBaseUrl = region => `https://${region}.api.blizzard.com`;

const getAccessToken = async region => {
  let end;
  const now = new Date();
  if (clientToken[region] && clientToken[region].accessToken && clientToken[region].expires > now) {
    return clientToken[region].accessToken;
  }

  const url = `https://${region}.battle.net/oauth/token?grant_type=client_credentials&client_id=${process.env.BATTLE_NET_API_CLIENT_ID}&client_secret=${
    process.env.BATTLE_NET_API_CLIENT_SECRET
  }`;

  const tokenRequest = await retryingRequest({
    url,
    headers: {
      'User-Agent': USER_AGENT,
    },
    gzip: true,
    // we'll be making several requests, so pool connections
    forever: true,
    timeout: 4000,
    shouldRetry: error => {
      return error.statusCode !== 404;
    },
    onBeforeAttempt: () => {
      end = blizzardApiResponseLatencyHistogram.startTimer({
        category: 'token',
        region,
      });
    },
    onFailure: err => {
      if (err instanceof RequestTimeoutError) {
        end({
          statusCode: 'timeout',
        });
      } else if (err instanceof RequestSocketTimeoutError) {
        end({
          statusCode: 'socket timeout',
        });
      } else if (err instanceof RequestConnectionResetError) {
        end({
          statusCode: 'connection reset',
        });
      } else if (err instanceof RequestUnknownError) {
        end({
          statusCode: 'unknown',
        });
      } else {
        end({
          statusCode: err.statusCode,
        });
      }
    },
    onSuccess: () => {
      end({
        statusCode: 200,
      });
    },
  });

  const tokenData = JSON.parse(tokenRequest);
  const expireDate = now.setSeconds(now.getSeconds() + tokenData.expires_in);

  clientToken[region] = {
    accessToken: tokenData.access_token,
    expires: expireDate,
  };

  return clientToken[region].accessToken;
};

export async function fetchCharacter(region, realm, name, fields = '') {
  region = region.toLowerCase();
  if (!availableRegions[region]) {
    throw new Error('Region not recognized.');
  }
  const accessToken = await getAccessToken(region);
  const url = `${makeBaseUrl(region)}/wow/character/${encodeURIComponent(realm)}/${encodeURIComponent(name)}?locale=${availableRegions[region]}&fields=${fields}`;

  return get(
    url,
    {
      category: 'character',
      region,
    },
    region,
    accessToken,
  );
}

export async function fetchItem(region, itemId) {
  region = region.toLowerCase();
  if (!availableRegions[region]) {
    throw new Error('Region not recognized.');
  }
  const accessToken = await getAccessToken(region);
  const url = `${makeBaseUrl(region)}/wow/item/${encodeURIComponent(itemId)}?locale=${availableRegions[region]}`;

  return get(
    url,
    {
      category: 'item',
      region,
    },
    region,
    accessToken,
  );
}

export async function fetchSpell(region, spellId) {
  region = region.toLowerCase();
  if (!availableRegions[region]) {
    throw new Error('Region not recognized.');
  }
  const accessToken = await getAccessToken(region);
  const url = `${makeBaseUrl(region)}/wow/spell/${encodeURIComponent(spellId)}?locale=${availableRegions[region]}`;

  return get(
    url,
    {
      category: 'spell',
      region,
    },
    region,
    accessToken,
  );
}
<|endoftext|>


<commit_before>//battery JSON object into graph
//INPUT: JSON Object
//		ex) '[{"datetime":String, "battery":float, clientID":String},*(__n)]'
//			where __n is the total number of data points
//OUTPUT: battery percentage graph
function batteryDisplay(data){
	// console.log(data);
	var margin = {
		top: 20,
		right: 50,
		bottom: 30,
		left: 50
		};
	var width = 1000 - margin.left - margin.right;
	var height = 300 - margin.top - margin.bottom;

	if(isJSON(data)){
		var data = JSON.parse(data);
		// var data = data.hits.hits;
		console.log(data);

		//earliest date
		// var xMin = new Date(d3.min(rDateTime,function(d, i){
		// var xMin = new Date(parseInt(d3.min(data,function(d, i){
		// 		return d.fields.datetime;
		// 		})));
		 // console.log(xMin);
		//latest date
		// var xMax = new Date(d3.max(rDateTime,function(d, i){
		// var xMax = new Date(parseInt(d3.max(data,function(d, i){
		// 		return d.fields.datetime;
		// 		})));
		// console.log(xMax);

		//x axis (dateTime)
		var x = d3.time.scale()
			// .domain([xMin, xMax])
			.domain(d3.extent(data,function(d){
				return d.fields.datetime;
			}))
			.range([0, width]);

		//y axis (percentage)
		var y = d3.scale.linear()
			.domain([0,1])
			// .domain(d3.extent(data,function(d){
			// 	return d.battery;
			// }))
			.range([height, 0]);

		//Axis
		var xAxis = d3.svg.axis()
			.scale(x)
			.orient('bottom')
			.ticks(3)
			.tickFormat(d3.time.format("%x %X"));
		var yAxis = d3.svg.axis()
			.scale(y)
			.orient('left')
			.ticks(3);

		var line = d3.svg.line()
			.x(function(d){
				// console.log(x(new Date(parseInt(d.datetime))));
				return x(new Date(parseInt(d.fields.datetime)));
			})
			.y(function(d){
				// console.log(y(d.battery));
				return y(d.fields.battery);
			})
			.interpolate("line");

		var svg = d3.select('#batt_graph')
			.append('svg')
			.attr('width', width + margin.left + margin.right)
			.attr('height', height + margin.top + margin.bottom)
			.attr('transform','translate('+margin.left+','+margin.top+')');

			svg.append('g')
			.attr('class', 'y axis')
			.attr('transform','translate(50,20)')
			.call(yAxis);
			// .append("text")
			// .attr("transform", "rotate(-90)")
			// .style("text-anchor", "end")
			// .text("Battery Precetage");

			svg.append('g')
			.attr('class', 'x axis')
			.attr('transform','translate(50,'+(height+20)+')')
			.call(xAxis);
			// .append("text")
			// .style("text-anchor", "end")
			// .text("Date");

			svg.append('path')
			.attr("class", "line")
			.attr("d", line(data))
			.attr("stroke", "blue")
			.attr("stroke-width", 1)
			.attr("fill", "none")
			.attr('transform','translate(50,20)');

//UPDATE GRAPH INSTEAD OF REDRAWING.
// if(document.getElementById("user_dis").childNodes.length == 1){
// 		userButtonCreation(data);
// 	}

	} else{
		console.log("batteryDisplay JSON incorrect");
		console.log(data);
	}
};<commit_msg>fixed battery.js to work on server<commit_after>//battery JSON object into graph
//INPUT: JSON Object
//		ex) '[{"datetime":String, "battery":float, clientID":String},*(__n)]'
//			where __n is the total number of data points
//OUTPUT: battery percentage graph
function batteryDisplay(data){
	// console.log(data);
	var margin = {
		top: 20,
		right: 50,
		bottom: 30,
		left: 50
		};
	var width = 1000 - margin.left - margin.right;
	var height = 300 - margin.top - margin.bottom;

	if(isJSON(data)){
		var data = JSON.parse(data);
		var data = data.hits.hits;
		// console.log(data);

		//earliest date
		var xMin = new Date(parseInt(d3.min(data,function(d, i){
				return d.fields.datetime;
				})));
		 console.log(xMin);
		//latest date
		var xMax = new Date(parseInt(d3.max(data,function(d, i){
				return d.fields.datetime;
				})));
		console.log(xMax);

		//x axis (dateTime)
		var x = d3.time.scale()
			// .domain([xMin, xMax])
			.domain(d3.extent(data,function(d){
				return d.fields.datetime;
			}))
			.range([0, width]);

		//y axis (percentage)
		var y = d3.scale.linear()
			.domain([0,1])
			// .domain(d3.extent(data,function(d){
			// 	return d.battery;
			// }))
			.range([height, 0]);

		//Axis
		var xAxis = d3.svg.axis()
			.scale(x)
			.orient('bottom')
			.ticks(3)
			.tickFormat(d3.time.format("%x %X"));
		var yAxis = d3.svg.axis()
			.scale(y)
			.orient('left')
			.ticks(3);

		var line = d3.svg.line()
			.x(function(d){
				// console.log(x(new Date(parseInt(d.datetime))));
				return x(new Date(parseInt(d.fields.datetime)));
			})
			.y(function(d){
				// console.log(y(d.battery));
				return y(d.fields.battery);
			})
			.interpolate("line");

		var svg = d3.select('#batt_graph')
			.append('svg')
			.attr('width', width + margin.left + margin.right)
			.attr('height', height + margin.top + margin.bottom)
			.attr('transform','translate('+margin.left+','+margin.top+')');

			svg.append('g')
			.attr('class', 'y axis')
			.attr('transform','translate(50,20)')
			.call(yAxis);
			// .append("text")
			// .attr("transform", "rotate(-90)")
			// .style("text-anchor", "end")
			// .text("Battery Precetage");

			svg.append('g')
			.attr('class', 'x axis')
			.attr('transform','translate(50,'+(height+20)+')')
			.call(xAxis);
			// .append("text")
			// .style("text-anchor", "end")
			// .text("Date");

			svg.append('path')
			.attr("class", "line")
			.attr("d", line(data))
			.attr("stroke", "blue")
			.attr("stroke-width", 1)
			.attr("fill", "none")
			.attr('transform','translate(50,20)');

//UPDATE GRAPH INSTEAD OF REDRAWING.
// if(document.getElementById("user_dis").childNodes.length == 1){
// 		userButtonCreation(data);
// 	}

	} else{
		console.log("batteryDisplay JSON incorrect");
		console.log(data);
	}
};<|endoftext|>


<commit_before>'use strict'

const coll = 'contracts'
const { cached, execute, hashData, insert, mapResult, parseResponse, retrieve, validate } = require('../../../lib/contract')

const jackal = (req, res, next) => {
  const contracts = req.body

  if (contracts.length === undefined || contracts.length === 0) {
    res.status(400).send({ message: 'No contracts received' })

    return next()
  }

  const json = JSON.stringify(contracts)
  const hash = hashData(json)

  if (!cached(coll, hash)) {
    const validations = contracts.map(validate)

    if (!validations.every(v => v.valid)) {
      res.status(400).send({
        message: "One or more contracts are invalid",
        validations: validations.map((v, i) => {
          const contract = contracts[i]

          return {
            contract: `${contract.name} <- ${contract.consumer}`,
            valid: v.valid,
            errors: v.errors
          }
        })
      })

      return next()
    }

    const parsedContracts = contracts.map(contract => {
      const parsedResponse = parseResponse(contract.response)

      return {
        name: contract.name,
        consumer: contract.consumer,
        request: contract.request,
        response: parsedResponse.valid ? parsedResponse.response : parsedResponse.error
      }
    })

    const invalidContract = parsedContracts.find(pc => isCompilationError(pc.response.body))
    if (invalidContract) {
      res.status(400).send(invalidContract.response)

      return next()
    }

    if (!insert(coll, hash, parsedContracts)) {
      res.status(500).send({ message: 'Cache failed on contracts insertion' })

      return next()
    }
  }

  const cacheObject = retrieve(coll, hash)

  if (cacheObject.hash !== hash) {
    res.status(500).send({ message: 'Cache failed on contracts retrieval' })

    return next()
  }

  execute(cacheObject.contracts, (err, results) => {
    res.status(201).send(results.map(mapResult))

    return next()
  })
}

module.exports = jackal

const isCompilationError = value => {
  const name = value.name && value.name === 'DSL Error'
  const msg = value.message && value.message === 'Response could not be compiled. Please see the DSL documentation: https://github.com/findmypast-oss/jackal/blob/master/dsl.md'

  return name && msg
}
<commit_msg>Fixed middleware to check for response body before checking for compilation errors<commit_after>'use strict'

const coll = 'contracts'
const { cached, execute, hashData, insert, mapResult, parseResponse, retrieve, validate } = require('../../../lib/contract')

const jackal = (req, res, next) => {
  const contracts = req.body

  if (contracts.length === undefined || contracts.length === 0) {
    res.status(400).send({ message: 'No contracts received' })

    return next()
  }

  const json = JSON.stringify(contracts)
  const hash = hashData(json)

  if (!cached(coll, hash)) {
    const validations = contracts.map(validate)

    if (!validations.every(v => v.valid)) {
      res.status(400).send({
        message: "One or more contracts are invalid",
        validations: validations.map((v, i) => {
          const contract = contracts[i]

          return {
            contract: `${contract.name} <- ${contract.consumer}`,
            valid: v.valid,
            errors: v.errors
          }
        })
      })

      return next()
    }

    const parsedContracts = contracts.map(contract => {
      const parsedResponse = parseResponse(contract.response)

      return {
        name: contract.name,
        consumer: contract.consumer,
        request: contract.request,
        response: parsedResponse.valid ? parsedResponse.response : parsedResponse.error
      }
    })

    const invalidContract = parsedContracts.find(pc => isCompilationError(pc.response.body))
    if (invalidContract) {
      res.status(400).send(invalidContract.response)

      return next()
    }

    if (!insert(coll, hash, parsedContracts)) {
      res.status(500).send({ message: 'Cache failed on contracts insertion' })

      return next()
    }
  }

  const cacheObject = retrieve(coll, hash)

  if (cacheObject.hash !== hash) {
    res.status(500).send({ message: 'Cache failed on contracts retrieval' })

    return next()
  }

  execute(cacheObject.contracts, (err, results) => {
    res.status(201).send(results.map(mapResult))

    return next()
  })
}

module.exports = jackal

const isCompilationError = value => {
  if (value) {
    const name = value.name && value.name === 'DSL Error'
    const msg = value.message && value.message === 'Response could not be compiled. Please see the DSL documentation: https://github.com/findmypast-oss/jackal/blob/master/dsl.md'

    return name && msg
  }

  return false
}
<|endoftext|>


<commit_before>/**
 * Created by wayne on 2/13/15.
 */

var mongodb = require('../database/mongoDb');

var CourseSchema = new mongodb.Schema({
  name: String,
  description: String,
  location: {
    type: "Point",
    coordinates: [Number]
  },
  address: String
});

CourseSchema.index({location: '2dsphere'});

var Course = mongodb.model('Courses', CourseSchema);

// CourseSchema.methods.geoNear = function(loc){
//   console.log('in GeoNear');
//   return this.runCommand({
//     goeNear: "Courses",
//     //near: [37.783682, -122.409021]
//     near: loc,
//     spherical: true,
//     limit: 3
//   })
// };

module.exports = Course;<commit_msg>fix: missing unstaged file from previous commit<commit_after>/**
 * Created by wayne on 2/13/15.
 */

var mongodb = require('../database/mongoDb');

var CourseSchema = new mongodb.Schema({
  name: String,
  description: String,
  location: {
    type: [Number],
    index: '2d'
  },
  address: String
});

CourseSchema.index({location: '2d'});

var Course = mongodb.model('Courses', CourseSchema);

// CourseSchema.methods.geoNear = function(loc){
//   console.log('in GeoNear');
//   return this.runCommand({
//     goeNear: "Courses",
//     //near: [37.783682, -122.409021]
//     near: loc,
//     spherical: true,
//     limit: 3
//   })
// };

module.exports = Course;<|endoftext|>


<commit_before>/**
 * medloader - code4sa.org
 */

var timer,
    delay = 500,
    animate_speed = 750;
var search_url = function(term) { return "/api/search-lite?q=" + term; }
var related_url = function(id) { return "/api/related?product=" + id };
var product_detail_url = function(id) { return "/api/detail?product=" + id };

var log = function(obj) {
    if (window.console) {
        window.console.log(obj);
    }
};

var map = {
    0 : "sep",
    1 : "schedule",
    2 : "dosage_form",
    3 : "pack_size",
    4 : "num_packs",
    5 : "is_generic"
};

var load_data = function(url, foo) {
    on_loading();
    return $.getJSON(url, function(data) {
        on_loaded(data);
        foo(data);
    });
}

Product = function(data, block) {
    this.data = data;
    this.block = block.addClass("product");
}

Product.prototype = {

    set_name : function() {
        $(".product-name", this.block).html(this.data.name).attr('href', '#product-detail-' + this.data.id);
    },

    set_price : function() {
        $(".product-price", this.block).html(this.data.sep);
    },

    set_class_names: function() {
        // We can't assume all data returned is of type: string :(
        if (typeof this.data.is_generic == 'string') {
            var classNameGeneric = 'type_' + this.data.is_generic.toLowerCase();
            $(this.block).addClass(classNameGeneric);
        }
        if (typeof this.data.dosage_form == 'string') {
            var classNameDosageForm = 'df_' + this.data.dosage_form.toLowerCase().replace(" ", "_");
            $(this.block).addClass(classNameDosageForm);
        }
    },

    build_product : function() {
        this.set_name();
        this.set_price();
        this.set_class_names();
        return this.block;
    }
}

var on_loading = function() {
    $("#search-container").addClass("js-loading");
}

var on_loaded = function(result) {
    $("#search-container").removeClass("js-loading");
}

var process_request = function(result) {
    $(".products .product").remove();
    $("#search-container").removeClass("js-results");
    $("#noresults").hide();
    $("#resultsheader").hide();

    var resultLength = result.length;
    if (resultLength) {
        $("#resultsheader").show();
        $("#resultsheader span").html(resultLength);
        $("#search-container").addClass("js-results");

        var $templateRow = $(".products .template");
        for (var i = 0; i < resultLength; i++) {
            var $product = new Product(result[i], $templateRow.clone().removeClass("template"));
            $('.products').append($product.build_product());
        }

        $('.product .product-name').on('click', function(e){
            e.preventDefault();
            add_product_detail($(this));
        });
    } else {
        $("#noresults").show();
    }
    on_loaded(result);
}

var $templateDetail = $(".products .template-panel-body");
var add_product_detail = function(elem) {
    var target_id = elem.attr('href').split('#product-detail-')[1];

    load_data(product_detail_url(target_id), function(data) {
        // Switch off any further event bindings to the source anchor, so that we don't get two results
        elem.off();

        // Set up the template
        var $product_detail = $templateDetail.clone().removeClass('template-panel-body');

        // Add product detail
        $(".details dd", $product_detail).each(function(idx) {
            var key = map[idx];
            $(this).html(data[key]);
        });

        // Add ingredients
        var $ingredientsList = $(".ingredients dl", $product_detail);
        var productIngredients = data.ingredients;
        var productIngredientsLength = productIngredients.length;
        for (var j = 0; j < productIngredientsLength; j++) {
            $ingredientsList.append("
" + productIngredients[j].name.trim() + ":
");
            $ingredientsList.append("
" + productIngredients[j].strength + productIngredients[j].unit + "
");
        }

        // Add related products link
        var related_link = $(".related", $product_detail);
        related_link.attr("href", "#related:" + target_id);

        // Add meta data
        $('.product-reg-number', $product_detail).html(data.regno);

        // Add product-detail ID so that we have something to target with collapse()
        $product_detail.attr('id', 'product-detail-' + target_id);

        // Append the detail to the product in question
        elem.parents('.product').append($product_detail);

        // Add collapse toggle to the source anchor
        elem.on("click", function(){
            $(this).collapse();
        });
    })
    .error(function() {
        // What to do on error?
        alert('There was a problem getting the details for this medicine. :(\nPlease try again later.');
    });

}

var entermedicine = function(e) {
    searchTerm = e.target.value;
    if (searchTerm.length < 4) return;

    var load_data = function() {
        location.hash = "search:" + searchTerm;
    }

    var reset_delay_before_requesting = function() {
        clearTimeout(timer);
        timer = setTimeout(load_data, delay);
    }

    reset_delay_before_requesting();
};

var load_medicines = function(value) {
    if (value.indexOf(":") >= 0) {
        var s = value.split(":")
        var key = s[0]
        var value = s[1]

        if (key == "#related") {
            load_data(related_url(value), process_request);
        } else if (key == "#search") {
            load_data(search_url(value), process_request);
        }

        $('html, body').animate({
            scrollTop: $("#top").offset().top
        }, animate_speed);
    }
}
<commit_msg>Removed redundant code<commit_after>/**
 * medloader - code4sa.org
 */

var timer,
    delay = 500,
    animate_speed = 750;
var search_url = function(term) { return "/api/search-lite?q=" + term; }
var related_url = function(id) { return "/api/related?product=" + id };
var product_detail_url = function(id) { return "/api/detail?product=" + id };

var log = function(obj) {
    if (window.console) {
        window.console.log(obj);
    }
};

var map = {
    0 : "sep",
    1 : "schedule",
    2 : "dosage_form",
    3 : "pack_size",
    4 : "num_packs",
    5 : "is_generic"
};

var load_data = function(url, foo) {
    on_loading();
    return $.getJSON(url, function(data) {
        on_loaded(data);
        foo(data);
    });
}

Product = function(data, block) {
    this.data = data;
    this.block = block.addClass("product");
}

Product.prototype = {

    set_name : function() {
        $(".product-name", this.block).html(this.data.name).attr('href', '#product-detail-' + this.data.id);
    },

    set_price : function() {
        $(".product-price", this.block).html(this.data.sep);
    },

    set_class_names: function() {
        // We can't assume all data returned is of type: string :(
        if (typeof this.data.is_generic == 'string') {
            var classNameGeneric = 'type_' + this.data.is_generic.toLowerCase();
            $(this.block).addClass(classNameGeneric);
        }
        if (typeof this.data.dosage_form == 'string') {
            var classNameDosageForm = 'df_' + this.data.dosage_form.toLowerCase().replace(" ", "_");
            $(this.block).addClass(classNameDosageForm);
        }
    },

    build_product : function() {
        this.set_name();
        this.set_price();
        this.set_class_names();
        return this.block;
    }
}

var on_loading = function() {
    $("#search-container").addClass("js-loading");
}

var on_loaded = function(result) {
    $("#search-container").removeClass("js-loading");
}

var process_request = function(result) {
    $(".products .product").remove();
    $("#search-container").removeClass("js-results");
    $("#noresults").hide();
    $("#resultsheader").hide();

    if (result.length) {
        $("#resultsheader").show();
        $("#resultsheader span").html(result.length);
        $("#search-container").addClass("js-results");

        var $templateRow = $(".products .template");
        for (var i = 0; i < result.length; i++) {
            var $product = new Product(result[i], $templateRow.clone().removeClass("template"));
            $('.products').append($product.build_product());
        }

        $('.product .product-name').on('click', function(e){
            e.preventDefault();
            add_product_detail($(this));
        });
    } else {
        $("#noresults").show();
    }
    on_loaded(result);
}

var $templateDetail = $(".products .template-panel-body");
var add_product_detail = function(elem) {
    var target_id = elem.attr('href').split('#product-detail-')[1];

    load_data(product_detail_url(target_id), function(data) {
        // Switch off any further event bindings to the source anchor, so that we don't get two results
        elem.off();

        // Set up the template
        var $product_detail = $templateDetail.clone().removeClass('template-panel-body');

        // Add product detail
        $(".details dd", $product_detail).each(function(idx) {
            var key = map[idx];
            $(this).html(data[key]);
        });

        // Add ingredients
        var $ingredientsList = $(".ingredients dl", $product_detail);
        var productIngredients = data.ingredients;
        var productIngredientsLength = productIngredients.length;
        for (var j = 0; j < productIngredientsLength; j++) {
            $ingredientsList.append("
" + productIngredients[j].name.trim() + ":
");
            $ingredientsList.append("
" + productIngredients[j].strength + productIngredients[j].unit + "
");
        }

        // Add related products link
        var related_link = $(".related", $product_detail);
        related_link.attr("href", "#related:" + target_id);

        // Add meta data
        $('.product-reg-number', $product_detail).html(data.regno);

        // Add product-detail ID so that we have something to target with collapse()
        $product_detail.attr('id', 'product-detail-' + target_id);

        // Append the detail to the product in question
        elem.parents('.product').append($product_detail);

        // Add collapse toggle to the source anchor
        elem.on("click", function(){
            $(this).collapse();
        });
    })
    .error(function() {
        // What to do on error?
        alert('There was a problem getting the details for this medicine. :(\nPlease try again later.');
    });

}

var entermedicine = function(e) {
    searchTerm = e.target.value;
    if (searchTerm.length < 4) return;

    var load_data = function() {
        location.hash = "search:" + searchTerm;
    }

    var reset_delay_before_requesting = function() {
        clearTimeout(timer);
        timer = setTimeout(load_data, delay);
    }

    reset_delay_before_requesting();
};

var load_medicines = function(value) {
    if (value.indexOf(":") >= 0) {
        var s = value.split(":")
        var key = s[0]
        var value = s[1]

        if (key == "#related") {
            load_data(related_url(value), process_request);
        } else if (key == "#search") {
            load_data(search_url(value), process_request);
        }

        $('html, body').animate({
            scrollTop: $("#top").offset().top
        }, animate_speed);
    }
}
<|endoftext|>