<commit_before>import React, {Component, PropTypes} from 'react'
import { Link, browserHistory } from 'react-router'
import 'stylesheets/modules/showcase'
import 'stylesheets/utilities/clearfix'

class Showcase extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      dragXStart: null,
      dragXNext: null,
      direction: null,
      xOffset: -200 - (100*(this.props.params.number - 1)),
      showcaseIndex: ((this.props.params.number - 1) || 0),
      sliding: false,
      transition: '0.5s',
      length: this.props.params.piece ? this.props.images[this.props.params.piece].slideshow.length : this.props.images[30].slideshow.length
    };
    this.hideDrag = this.hideDrag.bind(this);
    this.drag = this.drag.bind(this);
    this.setDrag = this.setDrag.bind(this);
    this.setIndex = this.setIndex.bind(this);
    this.setFocus = this.setFocus.bind(this);
    this.incrementIndex = this.incrementIndex.bind(this);
    this.decrementIndex = this.decrementIndex.bind(this);
  }

  render() {
    const showcaseNumber = this.props.params.piece;
    const showcaseItem = this.props.params.piece ? this.props.images[this.props.params.piece]: this.props.images[30];
    const showcaseIndex = this.state.showcaseIndex;
     const slideshow = showcaseItem.slideshow;
     const slideShowLength = slideshow.length;
     const setIndex = this.setIndex;
     const setFocus = this.setFocus;
       return (

        {showcaseItem.type !== "Animation" && }
        {showcaseItem.type === "Animation" && }
         {slideShowLength < 5 && slideShowLength > 1 &&

            {slideshow.map(function(item, index){
              return (
                <Link key={index} to={ {pathname: '/work/'+showcaseNumber+'/'+(index+1)} }>
                   setFocus(index)} className={(index === showcaseIndex) ? 'focus' : 'non-focus'} src={item} />
                </Link>
              )
            })
            }

 }
          {slideShowLength > 4 &&

             this.setIndex((slideShowLength - 4), showcaseIndex, slideShowLength)} className={'slider-item non-focus'} src={slideshow[slideShowLength - 4]} />
             this.setIndex((slideShowLength - 3), showcaseIndex, slideShowLength)} className={'slider-item non-focus'} src={slideshow[slideShowLength - 3]} />
             this.setIndex((slideShowLength - 2), showcaseIndex, slideShowLength)} className={((slideShowLength - 2) === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={slideshow[slideShowLength - 2]} />
             this.setIndex((slideShowLength - 1), showcaseIndex, slideShowLength)} className={((slideShowLength - 1) === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={slideshow[slideShowLength - 1]} />

          {slideshow.map(function(item, sliderIndex){
             return (
                setIndex(sliderIndex, showcaseIndex, slideShowLength)} className={(sliderIndex === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={item} />
              );
             }
          )}
            this.setIndex(0, showcaseIndex, slideShowLength)} className={(0 === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={slideshow[0]} />
            this.setIndex(1, showcaseIndex, slideShowLength)} className={(1 === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={slideshow[1]} />
            this.setIndex(2, showcaseIndex, slideShowLength)} className={'slider-item non-focus'} src={slideshow[2]} />
            this.setIndex(3, showcaseIndex, slideShowLength)} className={'slider-item non-focus'} src={slideshow[3]} />

}

{showcaseItem.name}

{showcaseItem.year}

          {showcaseItem.description &&
{showcaseItem.description}
}
          {showcaseItem.publisher &&
{showcaseItem.publisher}
}

        )
  }

  componentDidUpdate() {
    if(this.props.showcaseItem !== false){
    document.getElementsByClassName('showcase-image')[0].addEventListener('dragstart', this.hideDrag);
    }
   }

  componentWillUnmount() {
    document.getElementsByClassName('showcase-image')[0].removeEventListener('dragstart', this.hideDrag);
  }

  setFocus(newIndex) {
    this.setState({showcaseIndex: newIndex});
  }

  setIndex(newIndex, oldIndex) {
    const length = this.state.length;
    if (!this.state.sliding){
      this.setState({sliding: true});
      if((newIndex - oldIndex) > 3){
        const tx = this.state.xOffset + ((oldIndex + (length - newIndex))*100);
        this.setState({xOffset: tx, showcaseIndex: newIndex});
        if (this.state.xOffset > -300){
          setTimeout(
            function(){
              this.setState({transition: '0s', xOffset: this.state.xOffset - (length * 100)});
            }.bind(this), 550);
          setTimeout(
            function(){
              this.setState({transition: '0.5s', sliding: false});
            }.bind(this), 590);
       }
      } else if ((oldIndex - newIndex) > 3) {
         const tx = this.state.xOffset - ((newIndex + (length - oldIndex))*100);
         this.setState({xOffset: tx, showcaseIndex: newIndex});
         if (this.state.xOffset < -200){
           setTimeout(
             function(){
               this.setState({transition: '0s', xOffset: this.state.xOffset + (length * 100)});
             }.bind(this), 550);
           setTimeout(
             function(){
               this.setState({transition: '0.5s', sliding: false});
             }.bind(this), 590);
         }
      } else {
        const tx = this.state.xOffset + ((oldIndex  - newIndex)*100);
        this.setState({xOffset: tx, showcaseIndex: newIndex, sliding: false});
      }
    }
    setTimeout(function(){
      browserHistory.push('/work/'+this.props.params.piece+'/'+(newIndex+1));
    }.bind(this),500);
  }

  incrementIndex() {
    const newIndex = (this.state.showcaseIndex === this.state.length - 1) ? 0 : (this.state.showcaseIndex + 1)
    const oldIndex = this.state.showcaseIndex;
    this.setIndex(newIndex, oldIndex);
    setTimeout(function(){
      browserHistory.push('/work/'+this.props.params.piece+'/'+(newIndex+1));
    }.bind(this),500);
  }

  decrementIndex() {
    const newIndex = (this.state.showcaseIndex === 0) ? (this.state.length - 1) : (this.state.showcaseIndex - 1);
    const oldIndex = this.state.showcaseIndex;
    this.setIndex(newIndex, oldIndex);
    setTimeout(function(){
      browserHistory.push('/work/'+this.props.params.piece+'/'+(newIndex+1));
    }.bind(this),500);
  }

  setDrag(){
    this.setState({direction: null, dragXStart: null, dragXNext: null});
  }

  drag(event) {
    if(event.type === 'drag'){
    } else if (event.type === 'touch'){
    }
    if(this.state.dragXStart === null){
      if(event.type === 'drag'){
      this.setState({dragXStart: event.clientX});
      } else if (event.type === 'touchmove'){
        this.setState({dragXStart: event.touches[0].pageX});
      }
    } else if((this.state.dragXNext === null) && (this.state.dragXStart!==null)) {
      if (event.type === 'drag' && (this.state.dragXStart !== event.clientX)){
      this.setState({dragXNext: event.clientX}, function(){
        if(this.state.dragXStart < this.state.dragXNext){
          this.setState({direction: 'right'}, this.decrementIndex);
          } else if(this.state.dragXStart > this.state.dragXNext){
          this.setState({direction: 'left'}, this.incrementIndex);
        }
      });
      } else if (event.type === 'touchmove' && (this.state.dragXStart !== event.touches[0].clientX)){
      this.setState({dragXNext: event.touches[0].clientX}, function(){
        if(this.state.dragXStart < this.state.dragXNext){
          this.setState({direction: 'right'}, this.decrementIndex);
        } else if (this.state.dragXStart > this.state.dragXNext) {
          this.setState({direction: 'left'}, this.incrementIndex);
        }
        });
      }
    }
  }

  hideDrag(event) {
    if(this.props.showcaseItem !== false){
      event.dataTransfer.effectAllowed = 'none';
      const image = this.props.images[this.props.showcaseItem].slideshow[this.props.showcaseIndex]
      event.dataTransfer.setData("text/plain", event.target.id);
      var img = new Image();
      img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
      event.dataTransfer.setDragImage(img, 100, 100);
    }
  }

}

export default Showcase
<commit_msg>provide hash<commit_after>import React, {Component, PropTypes} from 'react'
import { Link, browserHistory } from 'react-router'
import 'stylesheets/modules/showcase'
import 'stylesheets/utilities/clearfix'

class Showcase extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      dragXStart: null,
      dragXNext: null,
      direction: null,
      xOffset: -200 - (100*(this.props.params.number - 1)),
      showcaseIndex: ((this.props.params.number - 1) || 0),
      sliding: false,
      transition: '0.5s',
      length: this.props.params.piece ? this.props.images[this.props.params.piece].slideshow.length : this.props.images[30].slideshow.length
    };
    this.hideDrag = this.hideDrag.bind(this);
    this.drag = this.drag.bind(this);
    this.setDrag = this.setDrag.bind(this);
    this.setIndex = this.setIndex.bind(this);
    this.setFocus = this.setFocus.bind(this);
    this.incrementIndex = this.incrementIndex.bind(this);
    this.decrementIndex = this.decrementIndex.bind(this);
  }

  render() {
    const showcaseNumber = this.props.params.piece;
    const showcaseItem = this.props.params.piece ? this.props.images[this.props.params.piece]: this.props.images[30];
    const showcaseIndex = this.state.showcaseIndex;
     const slideshow = showcaseItem.slideshow;
     const slideShowLength = slideshow.length;
     const setIndex = this.setIndex;
     const setFocus = this.setFocus;
       return (

        {showcaseItem.type !== "Animation" && }
        {showcaseItem.type === "Animation" && }
         {slideShowLength < 5 && slideShowLength > 1 &&

            {slideshow.map(function(item, index){
              return (
                <Link key={index} to={ {pathname: '/work/'+showcaseNumber+'/'+(index+1)} }>
                   setFocus(index)} className={(index === showcaseIndex) ? 'focus' : 'non-focus'} src={item} />
                </Link>
              )
            })
            }

 }
          {slideShowLength > 4 &&

             this.setIndex((slideShowLength - 4), showcaseIndex, slideShowLength)} className={'slider-item non-focus'} src={slideshow[slideShowLength - 4]} />
             this.setIndex((slideShowLength - 3), showcaseIndex, slideShowLength)} className={'slider-item non-focus'} src={slideshow[slideShowLength - 3]} />
             this.setIndex((slideShowLength - 2), showcaseIndex, slideShowLength)} className={((slideShowLength - 2) === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={slideshow[slideShowLength - 2]} />
             this.setIndex((slideShowLength - 1), showcaseIndex, slideShowLength)} className={((slideShowLength - 1) === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={slideshow[slideShowLength - 1]} />

          {slideshow.map(function(item, sliderIndex){
             return (
                setIndex(sliderIndex, showcaseIndex, slideShowLength)} className={(sliderIndex === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={item} />
              );
             }
          )}
            this.setIndex(0, showcaseIndex, slideShowLength)} className={(0 === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={slideshow[0]} />
            this.setIndex(1, showcaseIndex, slideShowLength)} className={(1 === showcaseIndex) ? 'slider-item focus' : 'slider-item non-focus'} src={slideshow[1]} />
            this.setIndex(2, showcaseIndex, slideShowLength)} className={'slider-item non-focus'} src={slideshow[2]} />
            this.setIndex(3, showcaseIndex, slideShowLength)} className={'slider-item non-focus'} src={slideshow[3]} />

}

{showcaseItem.name}

{showcaseItem.year}

          {showcaseItem.description &&
{showcaseItem.description}
}
          {showcaseItem.publisher &&
{showcaseItem.publisher}
}

        )
  }

  componentDidUpdate() {
    if(this.props.showcaseItem !== false){
    document.getElementsByClassName('showcase-image')[0].addEventListener('dragstart', this.hideDrag);
    }
   }

  componentWillUnmount() {
    document.getElementsByClassName('showcase-image')[0].removeEventListener('dragstart', this.hideDrag);
  }

  setFocus(newIndex) {
    this.setState({showcaseIndex: newIndex});
  }

  setIndex(newIndex, oldIndex) {
    const length = this.state.length;
    if (!this.state.sliding){
      this.setState({sliding: true});
      if((newIndex - oldIndex) > 3){
        const tx = this.state.xOffset + ((oldIndex + (length - newIndex))*100);
        this.setState({xOffset: tx, showcaseIndex: newIndex});
        if (this.state.xOffset > -300){
          setTimeout(
            function(){
              this.setState({transition: '0s', xOffset: this.state.xOffset - (length * 100)});
            }.bind(this), 550);
          setTimeout(
            function(){
              this.setState({transition: '0.5s', sliding: false});
            }.bind(this), 590);
       }
      } else if ((oldIndex - newIndex) > 3) {
         const tx = this.state.xOffset - ((newIndex + (length - oldIndex))*100);
         this.setState({xOffset: tx, showcaseIndex: newIndex});
         if (this.state.xOffset < -200){
           setTimeout(
             function(){
               this.setState({transition: '0s', xOffset: this.state.xOffset + (length * 100)});
             }.bind(this), 550);
           setTimeout(
             function(){
               this.setState({transition: '0.5s', sliding: false});
             }.bind(this), 590);
         }
      } else {
        const tx = this.state.xOffset + ((oldIndex  - newIndex)*100);
        this.setState({xOffset: tx, showcaseIndex: newIndex, sliding: false});
      }
    }
    setTimeout(function(){
      browserHistory.push('#/work/'+this.props.params.piece+'/'+(newIndex+1));
    }.bind(this),500);
  }

  incrementIndex() {
    const newIndex = (this.state.showcaseIndex === this.state.length - 1) ? 0 : (this.state.showcaseIndex + 1)
    const oldIndex = this.state.showcaseIndex;
    this.setIndex(newIndex, oldIndex);
    setTimeout(function(){
      browserHistory.push('#/work/'+this.props.params.piece+'/'+(newIndex+1));
    }.bind(this),500);
  }

  decrementIndex() {
    const newIndex = (this.state.showcaseIndex === 0) ? (this.state.length - 1) : (this.state.showcaseIndex - 1);
    const oldIndex = this.state.showcaseIndex;
    this.setIndex(newIndex, oldIndex);
    setTimeout(function(){
      browserHistory.push('#/work/'+this.props.params.piece+'/'+(newIndex+1));
    }.bind(this),500);
  }

  setDrag(){
    this.setState({direction: null, dragXStart: null, dragXNext: null});
  }

  drag(event) {
    if(event.type === 'drag'){
    } else if (event.type === 'touch'){
    }
    if(this.state.dragXStart === null){
      if(event.type === 'drag'){
      this.setState({dragXStart: event.clientX});
      } else if (event.type === 'touchmove'){
        this.setState({dragXStart: event.touches[0].pageX});
      }
    } else if((this.state.dragXNext === null) && (this.state.dragXStart!==null)) {
      if (event.type === 'drag' && (this.state.dragXStart !== event.clientX)){
      this.setState({dragXNext: event.clientX}, function(){
        if(this.state.dragXStart < this.state.dragXNext){
          this.setState({direction: 'right'}, this.decrementIndex);
          } else if(this.state.dragXStart > this.state.dragXNext){
          this.setState({direction: 'left'}, this.incrementIndex);
        }
      });
      } else if (event.type === 'touchmove' && (this.state.dragXStart !== event.touches[0].clientX)){
      this.setState({dragXNext: event.touches[0].clientX}, function(){
        if(this.state.dragXStart < this.state.dragXNext){
          this.setState({direction: 'right'}, this.decrementIndex);
        } else if (this.state.dragXStart > this.state.dragXNext) {
          this.setState({direction: 'left'}, this.incrementIndex);
        }
        });
      }
    }
  }

  hideDrag(event) {
    if(this.props.showcaseItem !== false){
      event.dataTransfer.effectAllowed = 'none';
      const image = this.props.images[this.props.showcaseItem].slideshow[this.props.showcaseIndex]
      event.dataTransfer.setData("text/plain", event.target.id);
      var img = new Image();
      img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
      event.dataTransfer.setDragImage(img, 100, 100);
    }
  }

}

export default Showcase
<|endoftext|>


<commit_before>/**
 * @license ngResize.js v1.0.0
 * (c) 2014 Daniel Smith http://www.danmasta.com
 * License: MIT
 */
(function(window, angular, undefined) { 'use strict';

/**
 * @name ngResize
 * @description
 *
 * # ngResize
 *
 * The ngResize module provides an angular directive for handling resize events
 * expression is run when the window resizes.
 * The implementation is the same as default angular event handlers.
 * Event object is available as $event.
 */

// define ngResize module
var ngResize = angular.module('ngResize', []);

// Factory for checking and binding resize event to window.
//
// Broadcasts 'resize' event from $rootScope which gets inherited
// by all child scopes
ngResize.factory('resize', ['$window', '$interval', '$rootScope', function($window, $interval, $rootScope) {
  return {
    check: function() {
      if (angular.isUndefined($rootScope.catchResize))
        return false;
      return $rootScope.catchResize;
    },
    bind: function() {
      var w = angular.element($window);
      var resizeThrottle = 100;
      var resized = false;
      var timer = false;
      w.on('resize', function(event) {
        if (!resized) {
          timer = $interval(function() {
            if (resized) {
              resized = false;
              $interval.cancel(timer);
              $rootScope.$broadcast('resize', {
                width: $window.innerWidth,
                height: $window.innerHeight
              });
            }
          }, resizeThrottle);
        }
        resized = true;
      });
      w.resize();
      $rootScope.catchResize = true;
    },
    set: function(){
      if (!this.check()) this.bind();
    }
  };
}]);

// ngResize directive, uses throttled resize event bound to window; will bind event only once.
// Broadcasts 'resize' event from $rootScope
//
// Usage: ng-resize="expression()"
// Event data is available as $event
// Timeout is used to debounce any expressions to the end of the current digest
ngResize.directive('ngResize', ['$parse', '$timeout', 'resize', function($parse, $timeout, resize) {
  return {
    compile: function($element, attr) {
      var fn = $parse(attr['ngResize']);
      return function(scope, element, attr) {
        resize.set();
        scope.$on('resize', function(event, data) {
          $timeout(function() {
            scope.$apply(function() {
              fn(scope, { $event: data });
            });
          });
        });
      };
    }
  };
}]);

})(window, window.angular);
<commit_msg>cleanup<commit_after>/**
 * @license ngResize.js v1.0.0
 * (c) 2014 Daniel Smith http://www.danmasta.com
 * License: MIT
 */
(function(window, angular, undefined) { 'use strict';

/**
 * @name ngResize
 * @description
 *
 * # ngResize
 *
 * The ngResize module provides an angular directive for handling resize events
 * expression is run when the window resizes.
 * The implementation is the same as default angular event handlers.
 * Event object is available as $event.
 */

// define ngResize module
var ngResize = angular.module('ngResize', []);

// Factory for checking and binding resize event to window.
//
// Broadcasts 'resize' event from $rootScope which gets inherited
// by all child scopes
ngResize.factory('resize', ['$window', '$interval', '$rootScope', function($window, $interval, $rootScope) {
  return {
    check: function() {
      if (angular.isUndefined($rootScope.catchResize)) return false;
      return $rootScope.catchResize;
    },
    bind: function() {
      var w = angular.element($window);
      var resizeThrottle = 100;
      var resized = false;
      var timer = false;
      w.on('resize', function(event) {
        if (!resized) {
          timer = $interval(function() {
            if (resized) {
              resized = false;
              $interval.cancel(timer);
              $rootScope.$broadcast('resize', {
                width: $window.innerWidth,
                height: $window.innerHeight
              });
            }
          }, resizeThrottle);
        }
        resized = true;
      });
      w.resize();
      $rootScope.catchResize = true;
    },
    set: function(){
      if (!this.check()) this.bind();
    }
  };
}]);

// ngResize directive, uses throttled resize event bound to window; will bind event only once.
// Broadcasts 'resize' event from $rootScope
//
// Usage: ng-resize="expression()"
// Event data is available as $event
// Timeout is used to debounce any expressions to the end of the current digest
ngResize.directive('ngResize', ['$parse', '$timeout', 'resize', function($parse, $timeout, resize) {
  return {
    compile: function($element, attr) {
      var fn = $parse(attr['ngResize']);
      return function(scope, element, attr) {
        resize.set();
        scope.$on('resize', function(event, data) {
          $timeout(function() {
            scope.$apply(function() {
              fn(scope, { $event: data });
            });
          });
        });
      };
    }
  };
}]);

})(window, window.angular);
<|endoftext|>


<commit_before>/**
 * Provides the public API for the Kolibri FrontEnd core app.
 * @module Facade
 */

const vue = require('vue');
const vuex = require('vuex');
const Mediator = require('./mediator');
const ResourceManager = require('../api-resource').ResourceManager;
const Resources = require('../api-resources');
const rest = require('rest');
const mime = require('rest/interceptor/mime');
const csrf = require('rest/interceptor/csrf');
const errorCode = require('rest/interceptor/errorCode');
const cookiejs = require('js-cookie');
const constructorExport = require('./constructorExport');

/**
 * Array containing the names of all methods of the Mediator that
 * should be exposed publicly through the Facade.
 * @type {string[]}
 */
const publicMethods = [
  'registerKolibriModuleAsync',
  'registerKolibriModuleSync',
  'stopListening',
  'emit',
  'on',
  'once',
  'off',
  'registerLanguageAssets',
  'registerLanguageAssetsUrl',
];

/**
 * Constructor for object that forms the public API for the Kolibri
 * core app.
 * @constructor
 */

module.exports = class CoreApp {
  constructor() {
    Object.assign(this, constructorExport());

    this.resources = new ResourceManager(this);
    const mediator = new Mediator();

    Object.keys(Resources).forEach((resourceClassName) =>
      this.resources.registerResource(resourceClassName, Resources[resourceClassName]));

    vue.prototype.Kolibri = this;
    /**
     * Use vuex for state management.
     */
    vue.use(vuex);

    // Register global components
    vue.component('content-renderer', require('../vue/content-renderer'));
    vue.component('assessment-wrapper', require('../vue/assessment-wrapper'));
    vue.component('download-button', require('../vue/content-renderer/download-button'));
    vue.component('loading-spinner', require('../vue/loading-spinner'));
    vue.component('core-modal', require('../vue/core-modal'));
    vue.component('progress-bar', require('../vue/progress-bar'));
    vue.component('content-icon', require('../vue/content-icon'));
    vue.component('core-base', require('../vue/core-base'));

    this.i18n = {
      reversed: false,
    };

    // Shim window.location.origin for IE.
    if (!window.location.origin) {
      window.location.origin = `${window.location.protocol}//${window.location.hostname}${(
            window.location.port ? `:${window.location.port}` : '')}`;
    }

    const self = this;

    function setUpVueIntl() {
      /**
       * Use the vue-intl plugin.
       **/
      const VueIntl = require('vue-intl');
      vue.use(VueIntl, { defaultLocale: 'en-us' });

      vue.prototype.$tr = function $tr(messageId, ...args) {
        const defaultMessageText = this.$options.$trs[messageId];
        const message = {
          id: `${this.$options.$trNameSpace}.${messageId}`,
          defaultMessage: defaultMessageText,
        };
        // Allow string reversal in debug mode.
        if (process.env.NODE_ENV === 'debug') {
          if (self.i18n.reversed) {
            return defaultMessageText.split('').reverse().join('');
          }
        }
        return this.$formatMessage(message, ...args);
      };
      vue.prototype.$trHtml = function $trHtml(messageId, ...args) {
        const defaultMessageText = this.$options.$trs[messageId];
        const message = {
          id: `${this.$options.$trNameSpace}.${messageId}`,
          defaultMessage: defaultMessageText,
        };
        // Allow string reversal in debug mode.
        if (process.env.NODE_ENV === 'debug') {
          if (self.i18n.reversed) {
            return defaultMessageText.split('').reverse().join('');
          }
        }
        return this.$formatHTMLMessage(message, ...args);
      };

      if (global.languageCode) {
        vue.setLocale(global.languageCode);
        if (global.coreLanguageMessages) {
          vue.registerMessages(global.languageCode, global.coreLanguageMessages);
        }
      }

      mediator.setReady();
    }

    /**
     * If the browser doesn't support the Intl polyfill, we retrieve that and
     * the modules need to wait until that happens.
     **/
    if (!global.hasOwnProperty('Intl')) {
      require.ensure(
        [
          'intl',
          'intl/locale-data/jsonp/en.js',
          // add more locales here
        ],
        (require) => {
          require('intl');
          require('intl/locale-data/jsonp/en.js');

          setUpVueIntl();
        }
      );
    } else {
      setUpVueIntl();
    }

    // Bind 'this' value for public methods - those that will be exposed in the Facade.
    this.kolibri_modules = mediator._kolibriModuleRegistry;
    publicMethods.forEach((method) => {
      this[method] = mediator[method].bind(mediator);
    });
  }

  get client() {
    return rest.wrap(mime, { mime: 'application/json' }).wrap(csrf, { name: 'X-CSRFToken',
        token: cookiejs.get('csrftoken') }).wrap(errorCode);
  }
};
<commit_msg>register icon-button as global component<commit_after>/**
 * Provides the public API for the Kolibri FrontEnd core app.
 * @module Facade
 */

const vue = require('vue');
const vuex = require('vuex');
const Mediator = require('./mediator');
const ResourceManager = require('../api-resource').ResourceManager;
const Resources = require('../api-resources');
const rest = require('rest');
const mime = require('rest/interceptor/mime');
const csrf = require('rest/interceptor/csrf');
const errorCode = require('rest/interceptor/errorCode');
const cookiejs = require('js-cookie');
const constructorExport = require('./constructorExport');

/**
 * Array containing the names of all methods of the Mediator that
 * should be exposed publicly through the Facade.
 * @type {string[]}
 */
const publicMethods = [
  'registerKolibriModuleAsync',
  'registerKolibriModuleSync',
  'stopListening',
  'emit',
  'on',
  'once',
  'off',
  'registerLanguageAssets',
  'registerLanguageAssetsUrl',
];

/**
 * Constructor for object that forms the public API for the Kolibri
 * core app.
 * @constructor
 */

module.exports = class CoreApp {
  constructor() {
    Object.assign(this, constructorExport());

    this.resources = new ResourceManager(this);
    const mediator = new Mediator();

    Object.keys(Resources).forEach((resourceClassName) =>
      this.resources.registerResource(resourceClassName, Resources[resourceClassName]));

    vue.prototype.Kolibri = this;
    /**
     * Use vuex for state management.
     */
    vue.use(vuex);

    // Register global components
    vue.component('content-renderer', require('../vue/content-renderer'));
    vue.component('assessment-wrapper', require('../vue/assessment-wrapper'));
    vue.component('download-button', require('../vue/content-renderer/download-button'));
    vue.component('loading-spinner', require('../vue/loading-spinner'));
    vue.component('core-modal', require('../vue/core-modal'));
    vue.component('progress-bar', require('../vue/progress-bar'));
    vue.component('icon-button', require('../vue/icon-button'));
    vue.component('content-icon', require('../vue/content-icon'));
    vue.component('core-base', require('../vue/core-base'));

    this.i18n = {
      reversed: false,
    };

    // Shim window.location.origin for IE.
    if (!window.location.origin) {
      window.location.origin = `${window.location.protocol}//${window.location.hostname}${(
            window.location.port ? `:${window.location.port}` : '')}`;
    }

    const self = this;

    function setUpVueIntl() {
      /**
       * Use the vue-intl plugin.
       **/
      const VueIntl = require('vue-intl');
      vue.use(VueIntl, { defaultLocale: 'en-us' });

      vue.prototype.$tr = function $tr(messageId, ...args) {
        const defaultMessageText = this.$options.$trs[messageId];
        const message = {
          id: `${this.$options.$trNameSpace}.${messageId}`,
          defaultMessage: defaultMessageText,
        };
        // Allow string reversal in debug mode.
        if (process.env.NODE_ENV === 'debug') {
          if (self.i18n.reversed) {
            return defaultMessageText.split('').reverse().join('');
          }
        }
        return this.$formatMessage(message, ...args);
      };
      vue.prototype.$trHtml = function $trHtml(messageId, ...args) {
        const defaultMessageText = this.$options.$trs[messageId];
        const message = {
          id: `${this.$options.$trNameSpace}.${messageId}`,
          defaultMessage: defaultMessageText,
        };
        // Allow string reversal in debug mode.
        if (process.env.NODE_ENV === 'debug') {
          if (self.i18n.reversed) {
            return defaultMessageText.split('').reverse().join('');
          }
        }
        return this.$formatHTMLMessage(message, ...args);
      };

      if (global.languageCode) {
        vue.setLocale(global.languageCode);
        if (global.coreLanguageMessages) {
          vue.registerMessages(global.languageCode, global.coreLanguageMessages);
        }
      }

      mediator.setReady();
    }

    /**
     * If the browser doesn't support the Intl polyfill, we retrieve that and
     * the modules need to wait until that happens.
     **/
    if (!global.hasOwnProperty('Intl')) {
      require.ensure(
        [
          'intl',
          'intl/locale-data/jsonp/en.js',
          // add more locales here
        ],
        (require) => {
          require('intl');
          require('intl/locale-data/jsonp/en.js');

          setUpVueIntl();
        }
      );
    } else {
      setUpVueIntl();
    }

    // Bind 'this' value for public methods - those that will be exposed in the Facade.
    this.kolibri_modules = mediator._kolibriModuleRegistry;
    publicMethods.forEach((method) => {
      this[method] = mediator[method].bind(mediator);
    });
  }

  get client() {
    return rest.wrap(mime, { mime: 'application/json' }).wrap(csrf, { name: 'X-CSRFToken',
        token: cookiejs.get('csrftoken') }).wrap(errorCode);
  }
};
<|endoftext|>


<commit_before>
//Variabler
var serverQuizzer; //Quiz[]
var lokaleQuizzer = []; //Quiz[]
var ferdigQuizzer;
var lokaleFerdigQuizzer = [];
var tid = window.setInterval(refresh,2000);
var tid2 = window.setInterval(oppdaterTid,1000);

//Generelle metoder

//Legger til og fjerner quizzer lokalt avhengig av hvordan det ser ut på serveren
function sjekkMotLokalt() {
    //Sletter først, mindre å gå gjennom etterpå

    /* Fjernekoden fungerer ikke enda. Men man kan refreshe for å fjerne
    var fant2 = false;
    //Sjekk om det finnes et element i lokaleQuizzer som ikke finnes i serverQuizzer
    //Gå gjennom alle elementer i lokaleQuizzer
    for (i = 0; i < lokaleQuizzer.length; i++) {
        //Sjekk om hver i i lokaleQuizzer finnes i serverQuizzer
        for (j = 0; j < serverQuizzer.length; j++) {
            //Hvis vi fant den lokale quizzen i serverquizzlisten
            if (lokaleQuizzer[i].id == serverQuizzer[j].id) {
                fant2 = true;
                break;
            }
        }
        //Hvis vi ikke fant den lokale quizzen i serverQuizzlisten
        if (fant2 != true) {
            //Fjern den lokale quizzen fra den lokale quizlisten og HTML
            fjernQuiz(lokaleQuizzer[i].id);
        }
    }
    */

    //Sammenlign alle quizIDer i serverquizzer med quizIDer i lokaleQuizzer
    //Legg inn nye quizzer
    var fant = false;
    //Gå gjennom alle quizzer i serverQuizzer
    for (i = 0; i < serverQuizzer.length; i++) {

        //Sammenlign element i i serverquizzer, med alle element i lokalequizzer
        for (j = 0; j < lokaleQuizzer.length; j++) {

            fant = false;
            //Hvis element j har en match i lokaleQuizzer
            if (serverQuizzer[i].id == lokaleQuizzer[j].id) {
                //MÅ FINNE MINST EN!
                //Når den har funnet en, ikke let etter samme igjen!
                //Når den har funnet en instans av serverQuiz[0] i lokalequiz
                //Ikke sjekk serverQuiz[0] igjen
                fant = true;
                break;
            }
        }
        //Hvis det ikke har en match i lokale quizzer
        if (fant != true) {

            //Legg inn ny quiz i lokaleQuizzer array og i HTML
            leggInnQuiz(serverQuizzer[i]);
        }
    }

    var fantFerdigQuiz = false;
    for (i = 0; i < ferdigQuizzer.length; i++) {
        for (j = 0;  j < lokaleFerdigQuizzer.length; j++) {
            fantFerdigQuiz = false;
            if (ferdigQuizzer[i].id == lokaleFerdigQuizzer[j].id) {
                fant = true;
                break;
            }
        }
        if (!fant) {
            leggInnFerdigQuiz(ferdigQuizzer[i]);
        }
    }
}

//Endre layout/html

//Oppdater tiden det er igjen til quizzen starter
function oppdaterTid() {

    //If (tidfelt regn ut hvor mange sekunder som er igjen) < 100

    for (i=0; i < lokaleQuizzer.length + 1; i++) {
        var selector = "#tidFelt";
        selector += i;
        var tidNaa = $(selector).text();
        if (tidNaa < -30000 || tidNaa === "Ugyldig tid") {
            $(selector).text("Ugyldig tid");
        }
        else if (tidNaa < 0 || tidNaa === "Startet") {
            $(selector).text("Startet");
        }
        else {
            tidNaa--;
            $(selector).text(tidNaa);
        }

    }
}

//Knapp for å navigere til quiz
var valgtQuiz;
$(document).on("click", ".quizButton", function(event){
    valgtQuiz = $(this).attr('id');
    $('#kallenavnModal').modal('show');
});

$(document).on("click", ".quizArkivButton", function(event) {
   console.log("JASDASd")
});

$("#kallenavnOK").click(function () {
    localStorage.setItem("quizId", valgtQuiz);
    localStorage.setItem("kallenavn", $("#kallenavnInput").val());
    document.location.href = "venteside.html";
});

//Knapp for å åpne scoreboardet til en quiz
$(document).on("click", ".scoreboardKnapp", function(event){
    //Må ta substring her
        valgtQuizString = $(this).attr('id');
        valgtQuiz = valgtQuizString.slice(-1);
        localStorage.setItem("quizId", valgtQuiz);
        localStorage.setItem("kallenavn", "");
        document.location.href = "scoreboard.html";

});

//Legg inn ferdig quiz i quizArkiv
function leggInnFerdigQuiz(quiz) {

    lokaleFerdigQuizzer.push(quiz);
    var markupStart = "
"+quiz.tittel+"	<button id='";
    var markupMiddle = quiz.id;
    var markupLast = "' type='submit' class='btn btn-block quizArkivButton'>Start</button></form>
";
    var con1 = markupStart.concat(markupMiddle);
    var con2 = con1.concat(markupLast);
    $("#quizArkivTable tbody").append(con2);
}

//Legg inn en quiz i tabellen
function leggInnQuiz(quiz) {
    lokaleQuizzer.push(quiz);

    var startTid = new Date(quiz.startDate);
    var tidnaa = new Date();
    var sekundertil = startTid.getTime() - tidnaa.getTime();
    sekundertil = Math.round(sekundertil/1000);

    //Brukes til å finne  som skal oppdateres
    var tidFeltId = "tidFelt";
    tidFeltId += quiz.id;
    var scoreBoardId = "scoreBoard";
    scoreBoardId += quiz.id;

    //Alt herfra er bare for å få med hvilken quiz man har klikket på
    var markupStart = "
"+quiz.tittel+"	" + sekundertil + "	8/20	<button id='";
    var markupMiddle = quiz.id;
    var markupLast = "' type='submit' class='btn btn-block quizButton'>Bli med!</button></form>
";
    var con1 = markupStart.concat(markupMiddle);
    var con2 = con1.concat(markupLast);
    $("#myTable tbody").append(con2);
}

//Fjern quiz fra tabellen
function fjernQuiz(quizID) {
    console.log("Inne i fjernQuiz");
    var rad = "#rad"+quizID;
    console.log("Rad: "+rad);
    $(rad).remove();
}

//AJAX, koding mot serveren

//Henter inn en array med quizzer fra serveren
function refresh() {
    $.ajax({
        url: 'rest/QuizService/quiz',
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (result) {
            serverQuizzer = result; //Dette er en array med quizzer
            if (typeof lokaleQuizzer == 'undefined') {
                console.log("Undefined found. Setting to serverquizzer!")
                //lokaleQuizzer = serverQuizzer;
            }
        }
    });

    $.ajax({
        url: 'rest/QuizService/ferdigquiz',
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (result) {
            ferdigQuizzer = result; //Dette er en array med quizzer
            if (typeof lokaleQuizzer == 'undefined') {
                console.log("Undefined found. Setting to serverquizzer!")
                //lokaleQuizzer = serverQuizzer;
            }
            sjekkMotLokalt();
        }
    });
}

// Find and remove selected table rows
/* WTF IS DIS
$(".delete-row").click(function(){
    $("table tbody").find('input[name="record"]').each(function(){
        if($(this).is(":checked")){
            $(this).parents("tr").remove();
        }
    });
});
*/<commit_msg>enterknappen skal funke når man legger til kallenavn, men vet ikke. Får ikke testet fordi jeg ikke ser quizer som er lagt til pga 404-feil<commit_after>
//Variabler
var serverQuizzer; //Quiz[]
var lokaleQuizzer = []; //Quiz[]
var ferdigQuizzer;
var lokaleFerdigQuizzer = [];
var tid = window.setInterval(refresh,2000);
var tid2 = window.setInterval(oppdaterTid,1000);

//Generelle metoder

//Legger til og fjerner quizzer lokalt avhengig av hvordan det ser ut på serveren
function sjekkMotLokalt() {
    //Sammenlign alle quizIDer i serverquizzer med quizIDer i lokaleQuizzer
    //Legg inn nye quizzer
    var fant = false;
    //Gå gjennom alle quizzer i serverQuizzer
    for (i = 0; i < serverQuizzer.length; i++) {

        //Sammenlign element i i serverquizzer, med alle element i lokalequizzer
        for (j = 0; j < lokaleQuizzer.length; j++) {

            fant = false;
            //Hvis element j har en match i lokaleQuizzer
            if (serverQuizzer[i].id == lokaleQuizzer[j].id) {
                //MÅ FINNE MINST EN!
                //Når den har funnet en, ikke let etter samme igjen!
                //Når den har funnet en instans av serverQuiz[0] i lokalequiz
                //Ikke sjekk serverQuiz[0] igjen
                fant = true;
                break;
            }
        }
        //Hvis det ikke har en match i lokale quizzer
        if (fant != true) {

            //Legg inn ny quiz i lokaleQuizzer array og i HTML
            leggInnQuiz(serverQuizzer[i]);
        }
    }

    var fantFerdigQuiz = false;
    for (i = 0; i < ferdigQuizzer.length; i++) {
        for (j = 0;  j < lokaleFerdigQuizzer.length; j++) {
            fantFerdigQuiz = false;
            if (ferdigQuizzer[i].id == lokaleFerdigQuizzer[j].id) {
                fant = true;
                break;
            }
        }
        if (!fant) {
            leggInnFerdigQuiz(ferdigQuizzer[i]);
        }
    }
}

//Endre layout/html

//Oppdater tiden det er igjen til quizzen starter
function oppdaterTid() {

    //If (tidfelt regn ut hvor mange sekunder som er igjen) < 100

    for (i=0; i < lokaleQuizzer.length + 1; i++) {
        var selector = "#tidFelt";
        selector += i;
        var tidNaa = $(selector).text();
        if (tidNaa < -30000 || tidNaa === "Ugyldig tid") {
            $(selector).text("Ugyldig tid");
        }
        else if (tidNaa < 0 || tidNaa === "Startet") {
            $(selector).text("Startet");
        }
        else {
            tidNaa--;
            $(selector).text(tidNaa);
        }

    }
}

//Knapp for å navigere til quiz
var valgtQuiz;
$(document).on("click", ".quizButton", function(event){
    valgtQuiz = $(this).attr('id');
    $('#kallenavnModal').modal('show');
});

$(document).on("click", ".quizArkivButton", function(event) {
   console.log("JASDASd")
});

$("#kallenavnOK").click(function () {
    localStorage.setItem("quizId", valgtQuiz);
    localStorage.setItem("kallenavn", $("#kallenavnInput").val());
});

$(document).keypress(function (event) {
    var code = event.keyCode;
    if(code == 13 && $("#kallenavnInput").is(":focus")) {
        localStorage.setItem("quizId", valgtQuiz);
        localStorage.setItem("kallenavn", $("#kallenavnInput").val());
        document.location.href = "venteside.html";
    }
});

//Knapp for å åpne scoreboardet til en quiz
$(document).on("click", ".scoreboardKnapp", function(event){
    //Må ta substring her
    valgtQuizString = $(this).attr('id');
    valgtQuiz = valgtQuizString.slice(-1);
    localStorage.setItem("quizId", valgtQuiz);
    localStorage.setItem("kallenavn", "");
    document.location.href = "scoreboard.html";
});

//Legg inn ferdig quiz i quizArkiv
function leggInnFerdigQuiz(quiz) {

    lokaleFerdigQuizzer.push(quiz);
    var markupStart = "
"+quiz.tittel+"	<button id='";
    var markupMiddle = quiz.id;
    var markupLast = "' type='submit' class='btn btn-block quizArkivButton'>Start</button></form>
";
    var con1 = markupStart.concat(markupMiddle);
    var con2 = con1.concat(markupLast);
    $("#quizArkivTable tbody").append(con2);
}

//Legg inn en quiz i tabellen
function leggInnQuiz(quiz) {
    lokaleQuizzer.push(quiz);

    var startTid = new Date(quiz.startDate);
    var tidnaa = new Date();
    var sekundertil = startTid.getTime() - tidnaa.getTime();
    sekundertil = Math.round(sekundertil/1000);

    //Brukes til å finne  som skal oppdateres
    var tidFeltId = "tidFelt";
    tidFeltId += quiz.id;
    var scoreBoardId = "scoreBoard";
    scoreBoardId += quiz.id;

    //Alt herfra er bare for å få med hvilken quiz man har klikket på
    var markupStart = "
"+quiz.tittel+"	" + sekundertil + "	8/20	<button id='";
    var markupMiddle = quiz.id;
    var markupLast = "' type='submit' class='btn btn-block quizButton'>Bli med!</button></form>
";
    var con1 = markupStart.concat(markupMiddle);
    var con2 = con1.concat(markupLast);
    $("#myTable tbody").append(con2);
}

//Fjern quiz fra tabellen
function fjernQuiz(quizID) {
    console.log("Inne i fjernQuiz");
    var rad = "#rad"+quizID;
    console.log("Rad: "+rad);
    $(rad).remove();
}

//AJAX, koding mot serveren

//Henter inn en array med quizzer fra serveren
function refresh() {
    $.ajax({
        url: 'rest/QuizService/quiz',
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (result) {
            serverQuizzer = result; //Dette er en array med quizzer
            if (typeof lokaleQuizzer == 'undefined') {
                console.log("Undefined found. Setting to serverquizzer!")
                //lokaleQuizzer = serverQuizzer;
            }
        }
    });

    $.ajax({
        url: 'rest/QuizService/ferdigquiz',
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: function (result) {
            ferdigQuizzer = result; //Dette er en array med quizzer
            if (typeof lokaleQuizzer == 'undefined') {
                console.log("Undefined found. Setting to serverquizzer!")
                //lokaleQuizzer = serverQuizzer;
            }
            sjekkMotLokalt();
        }
    });
}

// Find and remove selected table rows
/* WTF IS DIS
$(".delete-row").click(function(){
    $("table tbody").find('input[name="record"]').each(function(){
        if($(this).is(":checked")){
            $(this).parents("tr").remove();
        }
    });
});
*/<|endoftext|>


<commit_before>describe('M.SignupView', function() {
  var view;

  beforeEach(function() {
    view = new M.SignupView();
  });

  describe('#el', function() {
    it('returns the el', function() {
      expect(view.$el.selector).toBe('#signup-form');
    });
  });
});
<commit_msg>fix broken spec<commit_after>describe('M.SignupView', function() {
  var view;

  beforeEach(function() {
    view = new M.SignupView();
  });

  describe('#el', function() {
    it('returns the el', function() {
      expect(view.$el.selector).toBe('#money');
    });
  });
});
<|endoftext|>


<commit_before>module.exports = {
  "ejs": "html",
  "haml": "html",
  "jade": "html",
  "kit": "html",
  "md": "html",
  "slim": "html",

  "less": "css",
  "sass": "css",
  "scss": "css",
  "styl": "css",

  "coffee": "js"
  "ngt": "js"
  "ts": "js"
};
<commit_msg>Fix syntax error<commit_after>module.exports = {
  "ejs": "html",
  "haml": "html",
  "jade": "html",
  "kit": "html",
  "md": "html",
  "slim": "html",

  "less": "css",
  "sass": "css",
  "scss": "css",
  "styl": "css",

  "coffee": "js",
  "ngt": "js",
  "ts": "js"
};
<|endoftext|>


<commit_before>;(function() {

  /**
   * Example attribute value (contains both html tags and html entities):
   *
   * "The 10 Buffer Values and How We Act on Them Every Day open.buffer.com/... / Here's how to cook..."
   */
  var getDecodedAttribute = function(element, attrName) {
    var attrValue = element.getAttribute(attrName);

    // Strip html tags from attr value (Pinterest stores some html tags in attributes)
    // Using a regex is by no means perfect, but Pinterest only stores simple html tags
    // in there, so it should be solid enough.
    attrValue = attrValue.replace(/<\/?[^>]+(>|$)/g, '');

    // Decode html entities
    attrValue = he.decode(attrValue);

    return attrValue;
  };

  var config = [

    // Stream Pins
    {
      placement: 'pinterest-stream-pins',
      selector: '.Pin.Module .rightSideButtonsWrapper:not(.buffer-inserted)',
      $button: $([
        '<button class="Button BufferButton Module btn rounded" type="button">',
          '',
          'Buffer',
        '</button>'
      ].join('')),
      insert: function(el) {
        var $actions = $(el);

        // In some cases, Pinterest's DOM manipulations make us lose the .buffer-inserted
        // marker: make sure there's no Buffer button already before inserting a new one.
        var existingButton = $actions.find('.BufferButton:first');
        if (existingButton.length > 0) return existingButton.first();

        var $newActionItem = this.$button.clone();

        $actions
          .addClass('buffer-inserted')
          .append($newActionItem);

        if ($actions.find('.isBrioFlat:first').length > 0) {
          $newActionItem.addClass('isBrioFlat');
        }

        return $newActionItem;
      },
      getData: function(el) {
        var $pin = $(el).closest('.Pin.Module');
        var $img = $pin.find('img').first();
        var image = $img.attr('src');
        var pinLink;
        var pinIdParts;
        var pinId;
        var text;
        var $source;
        var source;
        var pageSource;
        var pinSourceRegex;
        var pinSourceMatches;

        text = getDecodedAttribute($img[0], 'alt');

        $source = $pin.find('.pinNavLink, .NavigateButton, .navigateLink').first();

        // If we haven't found a link, try to get it from the page's source using
        // some regex magic
        if ($source.length === 0) {
          pinLink = $img.closest('a').attr('href');
          pinIdParts = pinLink.split('/');
          pinId = pinIdParts[pinIdParts.length - 2];

          pageSource = document.body.innerHTML;

          // That regex looks into inline JSON to find the "link" field in the pin object
          // that follows that pin's id field. If we ever need something more robust to make
          // sure we get the right "link" field, I've come up with this more involved regex:
          // /"id":\s*"22447698119542969"(?:,\s*"[^"]+":\s*(?:\d+(?:\.\d+)?|\w+|"[^"]+"|{(?:(?:{[^}]*})?|[^}])*}|\[[^]]*]))*,\s*"link":\s*("[^"]+")/i
          pinSourceRegex = RegExp('"id":\\s*"' + pinId + '".*?"link":\\s*("[^"]+")');

          pinSourceMatches = pageSource.match(pinSourceRegex);

          if (pinSourceMatches) source = JSON.parse(pinSourceMatches[1]);
        }

        // If we still haven't found a link, default to the domain name
        if ($source.length === 0 && !source) {
          $source = $pin.find('.pinDomain');
        }

        source = source || $source.attr('href') || $source.text();

        return {
          text: text,
          url: source,
          picture: getFullSizeImageUrl(image),
          placement: this.placement
        };
      }
    },
    // Single Pins
    {
      placement: 'pinterest-single-pin',
      selector: '.PinActionBar:not(.buffer-inserted)',
      $button: $([
        '<button class="Button BufferButton Module btn rounded pinActionBarButton hasText medium" type="button">',
          '' + ' ',
          'Buffer',
        '</button>'
      ].join('')),
      insert: function(el) {
        var $actions = $(el);
        var $newActionItem = this.$button.clone();

        var showModalButton = $actions.find('.Button.ShowModalButton:first()');

        $actions.addClass('buffer-inserted');

        if (showModalButton.hasClass('isBrioFlat')) $newActionItem.addClass('isBrioFlat');
        showModalButton.after($newActionItem);

        return $newActionItem;
      },
      getData: function(el) {
        var $img = $(el).parents('.closeupActionBarContainer')
                        .siblings('.closeupContainer')
                        .find('.pinImage');

        var image = $img.attr('src');
        // Grab text from image alt attribute
        var text = getDecodedAttribute($img[0], 'alt');

        var source = $(el).closest('.Closeup').find('.paddedPinLink').attr('href');

        return {
          text: text,
          url: source,
          picture: getFullSizeImageUrl(image),
          placement: this.placement
        };
      }
    },
    // Pin Action Popup Pin
    {
      placement: 'pinterest-pin-popup',
      selector: '.SelectList li.item .BoardLabel:not(.buffer-inserted)',
      $button: $([
        '<button class="Button BufferButton Module btn rounded" type="button">',
          '' + ' ',
          'Buffer',
        '</button>'
      ].join('')),
      insert: function(el) {
        var $actions = $(el);
        var $newActionItem = this.$button.clone();

        $actions
          .addClass('buffer-inserted')
          .prepend($newActionItem);

          if ($newActionItem.next().hasClass('isBrioFlat')) {
            $newActionItem.addClass('isBrioFlat');
          }

        return $newActionItem;
      },
      getData: function(el) {
        var $img = $('.TwoPaneModal .pinContainer .pinImg');

        var image = $img.attr('src');
        var text = $('.pinDescriptionInput').val();

        // Grab full url from board behind modal
        var $source = $(document).find('img[src="'+image+'"]').parents('.pinHolder').siblings('.pinNavLink');
        var source = $source.attr('href');

        // If that didn't work, the Pin may have been open directly (there's no board in the
        // background): there may be a pinterestapp:source meta tag we'll try to get it from
        if (!source) source = $('meta[name=\'pinterestapp:source\']').attr('content');

        if(!source){
          if(window.location.search){
            var params = window.location.search.split('&');

            var urlIndex = -1;
            for(var i = 0; i < params.length; i++){
              if(params[i].indexOf('url=') > -1){
                urlIndex = i;
                break;
              }
            }

            if(urlIndex > -1){
              source = decodeURIComponent(params[urlIndex].split("=")[1]);
            }
          }

        }

        return {
          text: text,
          url: source,
          picture: getFullSizeImageUrl(image),
          placement: this.placement
        };
      }
    }
  ];

  var insertButton = function(target) {
    $(target.selector).each(function(i, el) {
      var $button = target.insert(el);
      $button.on('click', function(e) {
        e.preventDefault();
        e.stopImmediatePropagation();
        xt.port.emit('buffer_click', target.getData(el));
      })
    });
  };

  var insertButtons = function() {
    config.forEach(insertButton);
  };

  var pinterestLoop = function() {
    insertButtons();

    /**
     * Pinterest mutates the DOM on hover, and we need to insert the button after
     * it has done so. To minimize the visual impact of the Buffer button appearing
     * after hovering, we need to insert the button as fast as possible. This value
     * has proven to be a good tradeof between perceived speed and minimizing the
     * performance impact on the overall page.
     */
    setTimeout(pinterestLoop, 50);
  };

  var start = function() {

    // Add class for css scoping
    document.body.classList.add('buffer-pinterest');

    // Start the loop that will watch for new DOM elements
    pinterestLoop();
  };

  // Make sure we get the fullsize image
  // Example src: 'https://s-media-cache-ak0.pinimg.com/236x/55/1f/ac/551fac47c0dacff21f04012cb5c020cf.jpg'
  var getFullSizeImageUrl = function(url) {
    if (typeof url === 'undefined') return;

    var urlParts = url.split('/');
    var isPinterestImage = urlParts[2].indexOf('pinimg.com') != -1;

    // Non-Pinterest images should already be full-size
    if (!isPinterestImage) return url;

    urlParts[3] = '736x'; // 736 is the Pinterest standard for fullsize images
    return urlParts.join('/');
  };

  // Wait for xt.options to be set
  ;(function check() {
    // If Pinterest is switched on, start the main loop
    if (!xt.options) {
      setTimeout(check, 0);
    } else if (xt.options['buffer.op.pinterest'] === 'pinterest' || typeof xt.options['buffer.op.pinterest'] == 'undefined') {
      start();
    } else {
      setTimeout(check, 2000);
    }
  }());

}());
<commit_msg>Add hostname check to Pinterest integration for Safari<commit_after>;(function() {

  /**
   * On Safari, this gets injected in all pages. Since we've got a somewhat intensive
   * loop in there, only run the script on Pinterest sites:
   *
   * - www.pinterest.com
   * - www.pinterest.pt
   */
  var hostname = document.location.hostname;
  if (!/^([^\.]+\.)?pinterest\.(com|pt)$/.test(hostname)) return;

  /**
   * Example attribute value (contains both html tags and html entities):
   *
   * "The 10 Buffer Values and How We Act on Them Every Day open.buffer.com/... / Here's how to cook..."
   */
  var getDecodedAttribute = function(element, attrName) {
    var attrValue = element.getAttribute(attrName);

    // Strip html tags from attr value (Pinterest stores some html tags in attributes)
    // Using a regex is by no means perfect, but Pinterest only stores simple html tags
    // in there, so it should be solid enough.
    attrValue = attrValue.replace(/<\/?[^>]+(>|$)/g, '');

    // Decode html entities
    attrValue = he.decode(attrValue);

    return attrValue;
  };

  var config = [

    // Stream Pins
    {
      placement: 'pinterest-stream-pins',
      selector: '.Pin.Module .rightSideButtonsWrapper:not(.buffer-inserted)',
      $button: $([
        '<button class="Button BufferButton Module btn rounded" type="button">',
          '',
          'Buffer',
        '</button>'
      ].join('')),
      insert: function(el) {
        var $actions = $(el);

        // In some cases, Pinterest's DOM manipulations make us lose the .buffer-inserted
        // marker: make sure there's no Buffer button already before inserting a new one.
        var existingButton = $actions.find('.BufferButton:first');
        if (existingButton.length > 0) return existingButton.first();

        var $newActionItem = this.$button.clone();

        $actions
          .addClass('buffer-inserted')
          .append($newActionItem);

        if ($actions.find('.isBrioFlat:first').length > 0) {
          $newActionItem.addClass('isBrioFlat');
        }

        return $newActionItem;
      },
      getData: function(el) {
        var $pin = $(el).closest('.Pin.Module');
        var $img = $pin.find('img').first();
        var image = $img.attr('src');
        var pinLink;
        var pinIdParts;
        var pinId;
        var text;
        var $source;
        var source;
        var pageSource;
        var pinSourceRegex;
        var pinSourceMatches;

        text = getDecodedAttribute($img[0], 'alt');

        $source = $pin.find('.pinNavLink, .NavigateButton, .navigateLink').first();

        // If we haven't found a link, try to get it from the page's source using
        // some regex magic
        if ($source.length === 0) {
          pinLink = $img.closest('a').attr('href');
          pinIdParts = pinLink.split('/');
          pinId = pinIdParts[pinIdParts.length - 2];

          pageSource = document.body.innerHTML;

          // That regex looks into inline JSON to find the "link" field in the pin object
          // that follows that pin's id field. If we ever need something more robust to make
          // sure we get the right "link" field, I've come up with this more involved regex:
          // /"id":\s*"22447698119542969"(?:,\s*"[^"]+":\s*(?:\d+(?:\.\d+)?|\w+|"[^"]+"|{(?:(?:{[^}]*})?|[^}])*}|\[[^]]*]))*,\s*"link":\s*("[^"]+")/i
          pinSourceRegex = RegExp('"id":\\s*"' + pinId + '".*?"link":\\s*("[^"]+")');

          pinSourceMatches = pageSource.match(pinSourceRegex);

          if (pinSourceMatches) source = JSON.parse(pinSourceMatches[1]);
        }

        // If we still haven't found a link, default to the domain name
        if ($source.length === 0 && !source) {
          $source = $pin.find('.pinDomain');
        }

        source = source || $source.attr('href') || $source.text();

        return {
          text: text,
          url: source,
          picture: getFullSizeImageUrl(image),
          placement: this.placement
        };
      }
    },
    // Single Pins
    {
      placement: 'pinterest-single-pin',
      selector: '.PinActionBar:not(.buffer-inserted)',
      $button: $([
        '<button class="Button BufferButton Module btn rounded pinActionBarButton hasText medium" type="button">',
          '' + ' ',
          'Buffer',
        '</button>'
      ].join('')),
      insert: function(el) {
        var $actions = $(el);
        var $newActionItem = this.$button.clone();

        var showModalButton = $actions.find('.Button.ShowModalButton:first()');

        $actions.addClass('buffer-inserted');

        if (showModalButton.hasClass('isBrioFlat')) $newActionItem.addClass('isBrioFlat');
        showModalButton.after($newActionItem);

        return $newActionItem;
      },
      getData: function(el) {
        var $img = $(el).parents('.closeupActionBarContainer')
                        .siblings('.closeupContainer')
                        .find('.pinImage');

        var image = $img.attr('src');
        // Grab text from image alt attribute
        var text = getDecodedAttribute($img[0], 'alt');

        var source = $(el).closest('.Closeup').find('.paddedPinLink').attr('href');

        return {
          text: text,
          url: source,
          picture: getFullSizeImageUrl(image),
          placement: this.placement
        };
      }
    },
    // Pin Action Popup Pin
    {
      placement: 'pinterest-pin-popup',
      selector: '.SelectList li.item .BoardLabel:not(.buffer-inserted)',
      $button: $([
        '<button class="Button BufferButton Module btn rounded" type="button">',
          '' + ' ',
          'Buffer',
        '</button>'
      ].join('')),
      insert: function(el) {
        var $actions = $(el);
        var $newActionItem = this.$button.clone();

        $actions
          .addClass('buffer-inserted')
          .prepend($newActionItem);

          if ($newActionItem.next().hasClass('isBrioFlat')) {
            $newActionItem.addClass('isBrioFlat');
          }

        return $newActionItem;
      },
      getData: function(el) {
        var $img = $('.TwoPaneModal .pinContainer .pinImg');

        var image = $img.attr('src');
        var text = $('.pinDescriptionInput').val();

        // Grab full url from board behind modal
        var $source = $(document).find('img[src="'+image+'"]').parents('.pinHolder').siblings('.pinNavLink');
        var source = $source.attr('href');

        // If that didn't work, the Pin may have been open directly (there's no board in the
        // background): there may be a pinterestapp:source meta tag we'll try to get it from
        if (!source) source = $('meta[name=\'pinterestapp:source\']').attr('content');

        if(!source){
          if(window.location.search){
            var params = window.location.search.split('&');

            var urlIndex = -1;
            for(var i = 0; i < params.length; i++){
              if(params[i].indexOf('url=') > -1){
                urlIndex = i;
                break;
              }
            }

            if(urlIndex > -1){
              source = decodeURIComponent(params[urlIndex].split("=")[1]);
            }
          }

        }

        return {
          text: text,
          url: source,
          picture: getFullSizeImageUrl(image),
          placement: this.placement
        };
      }
    }
  ];

  var insertButton = function(target) {
    $(target.selector).each(function(i, el) {
      var $button = target.insert(el);
      $button.on('click', function(e) {
        e.preventDefault();
        e.stopImmediatePropagation();
        xt.port.emit('buffer_click', target.getData(el));
      })
    });
  };

  var insertButtons = function() {
    config.forEach(insertButton);
  };

  var pinterestLoop = function() {
    insertButtons();

    /**
     * Pinterest mutates the DOM on hover, and we need to insert the button after
     * it has done so. To minimize the visual impact of the Buffer button appearing
     * after hovering, we need to insert the button as fast as possible. This value
     * has proven to be a good tradeof between perceived speed and minimizing the
     * performance impact on the overall page.
     */
    setTimeout(pinterestLoop, 50);
  };

  var start = function() {

    // Add class for css scoping
    document.body.classList.add('buffer-pinterest');

    // Start the loop that will watch for new DOM elements
    pinterestLoop();
  };

  // Make sure we get the fullsize image
  // Example src: 'https://s-media-cache-ak0.pinimg.com/236x/55/1f/ac/551fac47c0dacff21f04012cb5c020cf.jpg'
  var getFullSizeImageUrl = function(url) {
    if (typeof url === 'undefined') return;

    var urlParts = url.split('/');
    var isPinterestImage = urlParts[2].indexOf('pinimg.com') != -1;

    // Non-Pinterest images should already be full-size
    if (!isPinterestImage) return url;

    urlParts[3] = '736x'; // 736 is the Pinterest standard for fullsize images
    return urlParts.join('/');
  };

  // Wait for xt.options to be set
  ;(function check() {
    // If Pinterest is switched on, start the main loop
    if (!xt.options) {
      setTimeout(check, 0);
    } else if (xt.options['buffer.op.pinterest'] === 'pinterest' || typeof xt.options['buffer.op.pinterest'] == 'undefined') {
      start();
    } else {
      setTimeout(check, 2000);
    }
  }());

}());
<|endoftext|>


<commit_before>const moment = require('moment');
const sha256 = require('sha256');
const rp = require('request-promise');
const Nightmare = require('nightmare');
const nightmare = Nightmare({ show: false, typeInterval: 2, waitTimeout: 5000 });

const URL = 'http://www.madr.gov.ro/transparenta-decizionala/proiecte-de-acte-normative.html';
const YEAR_THRESHOLD = 2017;

const API_TOKEN = process.env['API_TOKEN'];

function guessType(text) {
    const replaceMap = [
        [/ș/g, 's'],
        [/ş/g, 's'],
        [/ț/g, 't'],
        [/ţ/g, 't'],
        [/ă/g, 'a'],
        [/î/g, 'i'],
        [/â/g, 'a'],
    ];
    text = text.toLowerCase();
    for(let [orig, repl] of replaceMap) {
        text = text.replace(orig, repl);
    }

    if (text.match(/^ordonanta de urgenta /)) return 'OUG';
    if (text.match(/^ordonanta /)) return 'OG';
    if (text.match(/^hotarare /)) return 'HG';
    if (text.match(/^ordin /)) return 'OM';
    return 'LEGE';
}

function parsePage(firstFlag) {
    if (firstFlag) {
        nightmare
          .goto(URL);
    } else {
        nightmare
          .click('.pagination .next');
    }

    nightmare
      .wait("#itemListPrimary .itemContainer")
      .evaluate(()=> {
        let itemsList = [], items = [... document.querySelectorAll('#itemListPrimary .itemContainer')];
        for (let item of items) {
            let introText = item.querySelector(".catItemIntroText");
            let emHTML = introText.querySelector("em");
            if (emHTML !== null) {
                emHTML.remove();
            }

            let returnObj = {
                title: introText.innerText,
                date: item.querySelector(".catItemDateCreated").innerText,
                documents: [...item.querySelectorAll(".catItemAttachments a")].map((elem)=> {
                    return {
                        type: "act",//elem.title,
                        url: elem.href
                    }

                })
            };

            itemsList.push(returnObj);
        }
        return itemsList;
      })
      .then((result) => {

        let itemsList = [];

        for(let val of result) {
            let date = moment(val.date, 'ddd, DD MMMM YYYY HH:mm', 'ro');
            let year = date.year();
            if (year < YEAR_THRESHOLD) {
                console.log("halt!");
                nightmare.halt();
                return;
            }

            let identifier = sha256(val.title);
            val.date = date.format('YYYY-MM-DD');
            val.identifier = identifier;
            val.issuer = 'agricultura';
            val.description = val.title;
            val.type = guessType(val.title);
            itemsList.push(val);
        }

        function postAllItems(remaining) {
            if(! remaining.length) return;
            let val = remaining[0];
            return rp.post({
                url: 'http://czl-api.code4.ro/api/publications/',
                headers: {Authorization: `Token ${API_TOKEN}`},
                json: val
            })
            .then(() => postAllItems(remaining.slice(1)));
        }

        return postAllItems(itemsList);

      })
      .then((result) => {
        nightmare.evaluate(function () {
            let returnValue = document.querySelector('.pagination .next');
            return returnValue !== null;
        })
        .then(function(goNextFlag) {
            setTimeout(function() {
                if (goNextFlag) {
                    parsePage(false);
                }else {
                    console.log("halt!");
                    nightmare.halt();
                }
            }, 0);
        });
      })
      .catch((error) => {
        console.error('error:', error);
        nightmare.halt();
      });
}

parsePage(true);
// http://www.madr.gov.ro/transparenta-decizionala/proiecte-de-acte-normative.html?start=520
<commit_msg>print successful uploads<commit_after>const moment = require('moment');
const sha256 = require('sha256');
const rp = require('request-promise');
const Nightmare = require('nightmare');
const nightmare = Nightmare({ show: false, typeInterval: 2, waitTimeout: 5000 });

const URL = 'http://www.madr.gov.ro/transparenta-decizionala/proiecte-de-acte-normative.html';
const YEAR_THRESHOLD = 2017;

const API_TOKEN = process.env['API_TOKEN'];

function guessType(text) {
    const replaceMap = [
        [/ș/g, 's'],
        [/ş/g, 's'],
        [/ț/g, 't'],
        [/ţ/g, 't'],
        [/ă/g, 'a'],
        [/î/g, 'i'],
        [/â/g, 'a'],
    ];
    text = text.toLowerCase();
    for(let [orig, repl] of replaceMap) {
        text = text.replace(orig, repl);
    }

    if (text.match(/^ordonanta de urgenta /)) return 'OUG';
    if (text.match(/^ordonanta /)) return 'OG';
    if (text.match(/^hotarare /)) return 'HG';
    if (text.match(/^ordin /)) return 'OM';
    return 'LEGE';
}

function parsePage(firstFlag) {
    if (firstFlag) {
        nightmare
          .goto(URL);
    } else {
        nightmare
          .click('.pagination .next');
    }

    nightmare
      .wait("#itemListPrimary .itemContainer")
      .evaluate(()=> {
        let itemsList = [], items = [... document.querySelectorAll('#itemListPrimary .itemContainer')];
        for (let item of items) {
            let introText = item.querySelector(".catItemIntroText");
            let emHTML = introText.querySelector("em");
            if (emHTML !== null) {
                emHTML.remove();
            }

            let returnObj = {
                title: introText.innerText,
                date: item.querySelector(".catItemDateCreated").innerText,
                documents: [...item.querySelectorAll(".catItemAttachments a")].map((elem)=> {
                    return {
                        type: "act",//elem.title,
                        url: elem.href
                    }

                })
            };

            itemsList.push(returnObj);
        }
        return itemsList;
      })
      .then((result) => {

        let itemsList = [];

        for(let val of result) {
            let date = moment(val.date, 'ddd, DD MMMM YYYY HH:mm', 'ro');
            let year = date.year();
            if (year < YEAR_THRESHOLD) {
                console.log("halt!");
                nightmare.halt();
                return;
            }

            let identifier = sha256(val.title);
            val.date = date.format('YYYY-MM-DD');
            val.identifier = identifier;
            val.issuer = 'agricultura';
            val.description = val.title;
            val.type = guessType(val.title);
            itemsList.push(val);
        }

        function postAllItems(remaining) {
            if(! remaining.length) return;
            let val = remaining[0];
            return rp.post({
                url: 'http://czl-api.code4.ro/api/publications/',
                headers: {Authorization: `Token ${API_TOKEN}`},
                json: val
            })
            .then(() => {
                console.log('posted item: ', val.identifier);
                return postAllItems(remaining.slice(1));
            });
        }

        return postAllItems(itemsList);

      })
      .then((result) => {
        nightmare.evaluate(function () {
            let returnValue = document.querySelector('.pagination .next');
            return returnValue !== null;
        })
        .then(function(goNextFlag) {
            setTimeout(function() {
                if (goNextFlag) {
                    parsePage(false);
                }else {
                    console.log("halt!");
                    nightmare.halt();
                }
            }, 0);
        });
      })
      .catch((error) => {
        console.error('error:', error);
        nightmare.halt();
      });
}

parsePage(true);
// http://www.madr.gov.ro/transparenta-decizionala/proiecte-de-acte-normative.html?start=520
<|endoftext|>


<commit_before>var basal = require('oref0/lib/profile/basal');
var get_iob = require('oref0/lib/iob');

function detectSensitivityandCarbAbsorption(inputs) {

    glucose_data = inputs.glucose_data;
    iob_inputs = inputs.iob_inputs;
    basalprofile = inputs.basalprofile;
    profile = inputs.iob_inputs.profile;
    mealTime = new Date(inputs.mealTime);

    //console.log(mealTime);

    var avgDeltas = [];
    var bgis = [];
    var deviations = [];
    var deviationSum = 0;
    var carbsAbsorbed = 0;
    for (var i=0; i < glucose_data.length-3; ++i) {
        //console.log(glucose_data[i]);
        var bgTime;
        if (glucose_data[i].display_time) {
            bgTime = new Date(glucose_data[i].display_time.replace('T', ' '));
        } else if (glucose_data[i].dateString) {
            bgTime = new Date(glucose_data[i].dateString);
        } else { console.error("Could not determine last BG time"); }
        //console.log(bgTime);
        var bg = glucose_data[i].glucose;
        if ( bg < 40 || glucose_data[i+3].glucose < 40) {
            process.stderr.write("!");
            continue;
        }
        var avgDelta = (bg - glucose_data[i+3].glucose)/3;
        avgDelta = avgDelta.toFixed(2);
        iob_inputs.clock=bgTime;
        iob_inputs.profile.current_basal = basal.basalLookup(basalprofile, bgTime);
        //console.log(JSON.stringify(iob_inputs.profile));
        var iob = get_iob(iob_inputs)[0];
        //console.log(JSON.stringify(iob));

        var bgi = -iob.activity*profile.sens;
        bgi = bgi.toFixed(2);
        deviation = avgDelta-bgi;
        deviation = deviation.toFixed(2);
        //if (deviation < 0 && deviation > -2) {
            //console.log("BG: "+bg+", avgDelta: "+avgDelta+", BGI: "+bgi+", deviation: "+deviation);
        //}
        process.stderr.write(".");

        avgDeltas.push(avgDelta);
        bgis.push(bgi);
        deviations.push(deviation);
        deviationSum += parseFloat(deviation);

        // if bgTime is more recent than mealTime
        if(bgTime > mealTime) {
            //console.log(bgTime, deviation)
            // and deviation is positive
            if (deviation > 0) {
                // figure out how many carbs that represents
                var delta = (bg - glucose_data[i+1].glucose);
                //console.log(delta)
                absorbed = delta * profile.carb_ratio / profile.sens;
                //console.log(absorbed);
                // and add that to the running total carbsAbsorbed
                carbsAbsorbed += absorbed;
                //console.log(carbsAbsorbed);
            }
        }
    }
    console.error("");
    //console.log(JSON.stringify(avgDeltas));
    //console.log(JSON.stringify(bgis));
    avgDeltas.sort(function(a, b){return a-b});
    bgis.sort(function(a, b){return a-b});
    deviations.sort(function(a, b){return a-b});
    for (var i=0.51; i > 0.29; i = i - 0.01) {
        //console.error("p="+i.toFixed(2)+": "+percentile(avgDeltas, i).toFixed(2)+", "+percentile(bgis, i).toFixed(2)+", "+percentile(deviations, i).toFixed(2));
    }
    p50 = percentile(deviations, 0.5);
    p45 = percentile(deviations, 0.45);
    //p30 = percentile(deviations, 0.3);

    average = deviationSum / deviations.length;

    //console.error("Mean deviation: "+average.toFixed(2));
    var basalOff = 0;

    if(p50 < 0) { // sensitive
        basalOff = p50 * (60/5) / profile.sens;
        //console.error("Excess insulin sensitivity detected");
    } else if (p45 > 0) { // resistant
        basalOff = p45 * (60/5) / profile.sens;
        //console.error("Excess insulin resistance detected");
    } else {
        //console.error("Sensitivity within normal ranges");
    }
    ratio = 1 + (basalOff / profile.max_daily_basal);
    ratio = Math.round(ratio*100)/100
    newisf = profile.sens / ratio;
    //console.error("Basal adjustment "+basalOff.toFixed(2)+"U/hr");
    //console.error("Ratio: "+ratio*100+"%: new ISF: "+newisf.toFixed(1)+"mg/dL/U");
    var output = {
        "ratio": ratio
    ,   "carbsAbsorbed": carbsAbsorbed
    }
    return output;
}
module.exports = detectSensitivityandCarbAbsorption;

// From https://gist.github.com/IceCreamYou/6ffa1b18c4c8f6aeaad2
// Returns the value at a given percentile in a sorted numeric array.
// "Linear interpolation between closest ranks" method
function percentile(arr, p) {
    if (arr.length === 0) return 0;
    if (typeof p !== 'number') throw new TypeError('p must be a number');
    if (p <= 0) return arr[0];
    if (p >= 1) return arr[arr.length - 1];

    var index = arr.length * p,
        lower = Math.floor(index),
        upper = lower + 1,
        weight = index % 1;

    if (upper >= arr.length) return arr[lower];
    return arr[lower] * (1 - weight) + arr[upper] * weight;
}

// Returns the percentile of the given value in a sorted numeric array.
function percentRank(arr, v) {
    if (typeof v !== 'number') throw new TypeError('v must be a number');
    for (var i = 0, l = arr.length; i < l; i++) {
        if (v <= arr[i]) {
            while (i < l && v === arr[i]) i++;
            if (i === 0) return 0;
            if (v !== arr[i-1]) {
                i += (v - arr[i-1]) / (arr[i] - arr[i-1]);
            }
            return i / l;
        }
    }
    return 1;
}

<commit_msg>fix COB calculation<commit_after>var basal = require('oref0/lib/profile/basal');
var get_iob = require('oref0/lib/iob');

function detectSensitivityandCarbAbsorption(inputs) {

    glucose_data = inputs.glucose_data;
    iob_inputs = inputs.iob_inputs;
    basalprofile = inputs.basalprofile;
    profile = inputs.iob_inputs.profile;
    mealTime = new Date(inputs.mealTime);

    //console.log(mealTime);

    var avgDeltas = [];
    var bgis = [];
    var deviations = [];
    var deviationSum = 0;
    var carbsAbsorbed = 0;
    for (var i=0; i < glucose_data.length-3; ++i) {
        //console.log(glucose_data[i]);
        var bgTime;
        if (glucose_data[i].display_time) {
            bgTime = new Date(glucose_data[i].display_time.replace('T', ' '));
        } else if (glucose_data[i].dateString) {
            bgTime = new Date(glucose_data[i].dateString);
        } else { console.error("Could not determine last BG time"); }
        //console.log(bgTime);
        var bg = glucose_data[i].glucose;
        if ( bg < 40 || glucose_data[i+3].glucose < 40) {
            process.stderr.write("!");
            continue;
        }
        var avgDelta = (bg - glucose_data[i+3].glucose)/3;
        avgDelta = avgDelta.toFixed(2);
        var delta = (bg - glucose_data[i+1].glucose);
        iob_inputs.clock=bgTime;
        iob_inputs.profile.current_basal = basal.basalLookup(basalprofile, bgTime);
        //console.log(JSON.stringify(iob_inputs.profile));
        var iob = get_iob(iob_inputs)[0];
        //console.log(JSON.stringify(iob));

        //var bgi = -iob.activity*profile.sens;
        var bgi = Math.round(( -iob.activity * profile.sens * 5 )*100)/100;
        bgi = bgi.toFixed(2);
        deviation = delta-bgi;
        deviation = deviation.toFixed(2);
        //if (deviation < 0 && deviation > -2) { console.error("BG: "+bg+", avgDelta: "+avgDelta+", BGI: "+bgi+", deviation: "+deviation); }
        process.stderr.write(".");

        avgDeltas.push(avgDelta);
        bgis.push(bgi);
        deviations.push(deviation);
        deviationSum += parseFloat(deviation);

        // if bgTime is more recent than mealTime
        if(bgTime > mealTime) {
            //console.log(bgTime, deviation)
            // and deviation is positive
            if (deviation > 0) {
                // figure out how many carbs that represents
                //console.log(delta)
                absorbed = deviation * profile.carb_ratio / profile.sens;
                //console.log(absorbed);
                // and add that to the running total carbsAbsorbed
                carbsAbsorbed += absorbed;
                console.error(carbsAbsorbed);
            }
        }
    }
    console.error("");
    //console.log(JSON.stringify(avgDeltas));
    //console.log(JSON.stringify(bgis));
    avgDeltas.sort(function(a, b){return a-b});
    bgis.sort(function(a, b){return a-b});
    deviations.sort(function(a, b){return a-b});
    for (var i=0.51; i > 0.29; i = i - 0.01) {
        //console.error("p="+i.toFixed(2)+": "+percentile(avgDeltas, i).toFixed(2)+", "+percentile(bgis, i).toFixed(2)+", "+percentile(deviations, i).toFixed(2));
    }
    p50 = percentile(deviations, 0.5);
    p45 = percentile(deviations, 0.45);
    //p30 = percentile(deviations, 0.3);

    average = deviationSum / deviations.length;

    //console.error("Mean deviation: "+average.toFixed(2));
    var basalOff = 0;

    if(p50 < 0) { // sensitive
        basalOff = p50 * (60/5) / profile.sens;
        //console.error("Excess insulin sensitivity detected");
    } else if (p45 > 0) { // resistant
        basalOff = p45 * (60/5) / profile.sens;
        //console.error("Excess insulin resistance detected");
    } else {
        //console.error("Sensitivity within normal ranges");
    }
    ratio = 1 + (basalOff / profile.max_daily_basal);
    ratio = Math.round(ratio*100)/100
    newisf = profile.sens / ratio;
    //console.error("Basal adjustment "+basalOff.toFixed(2)+"U/hr");
    //console.error("Ratio: "+ratio*100+"%: new ISF: "+newisf.toFixed(1)+"mg/dL/U");
    var output = {
        "ratio": ratio
    ,   "carbsAbsorbed": carbsAbsorbed
    }
    return output;
}
module.exports = detectSensitivityandCarbAbsorption;

// From https://gist.github.com/IceCreamYou/6ffa1b18c4c8f6aeaad2
// Returns the value at a given percentile in a sorted numeric array.
// "Linear interpolation between closest ranks" method
function percentile(arr, p) {
    if (arr.length === 0) return 0;
    if (typeof p !== 'number') throw new TypeError('p must be a number');
    if (p <= 0) return arr[0];
    if (p >= 1) return arr[arr.length - 1];

    var index = arr.length * p,
        lower = Math.floor(index),
        upper = lower + 1,
        weight = index % 1;

    if (upper >= arr.length) return arr[lower];
    return arr[lower] * (1 - weight) + arr[upper] * weight;
}

// Returns the percentile of the given value in a sorted numeric array.
function percentRank(arr, v) {
    if (typeof v !== 'number') throw new TypeError('v must be a number');
    for (var i = 0, l = arr.length; i < l; i++) {
        if (v <= arr[i]) {
            while (i < l && v === arr[i]) i++;
            if (i === 0) return 0;
            if (v !== arr[i-1]) {
                i += (v - arr[i-1]) / (arr[i] - arr[i-1]);
            }
            return i / l;
        }
    }
    return 1;
}

<|endoftext|>


<commit_before>/* Copyright 2014-present Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 */
/* Primitive `makedepend` style utility.
 * Relies on you generating a .dep file using a compiler invocation like:
 * $(CC) $(CFLAGS) /Zs /showIncludes /EHsc $< > $(<:.c=.dep)
 * which captures the list of include files used by a given source.
 * This script will parse that output and collect it together to generate
 * an NMake style dependency graph for the target object file.
 */
shell = WScript.CreateObject("WScript.Shell");
cwd = shell.CurrentDirectory.toLowerCase() + '\\';
fs = WScript.CreateObject("Scripting.FileSystemObject");

INC_FILE = '.windeps';
// Force dependencies on the make tooling, so that objects are regenerated
// when the build environment is changed
EXTRA_DEPS = [];//'winbuild\\Makefile', 'winbuild\\depends.js'];
REL_DIR = ".";

function parse_dep_stream(is, write_back) {
  var deps = [];
  var current_file = null;
  var depfile = null;

  var includePat = /^Note: including file:\s+(.*)/

  while (!is.AtEndOfStream) {
    var line = is.ReadLine();
    var m = includePat.exec(line);
    if (m) {
      if (depfile) {
        depfile.WriteLine(line);
      }
      var candidate = m[1];
      var prefix = candidate.substr(0, cwd.length).toLowerCase();
      if (prefix == cwd) {
        deps.push('"' + candidate.substr(cwd.length) + '"');
      }
    } else {
      var candidate_file = line;
      if (REL_DIR != ".") {
        candidate_file = REL_DIR + "\\" + candidate_file;
      }

      if (!fs.FileExists(candidate_file)) {
        // Some random error that we can ignore
        continue;
      }

      // Then it is probably the name of the source file
      if (depfile) {
        depfile.Close();
        depfile = null;
      }

      current_file = candidate_file;

      deps = [];
      for (var i in EXTRA_DEPS) {
        deps.push(EXTRA_DEPS[i]);
      }

      if (write_back) {
        var depfilename = current_file.replace(/.(c|cpp)$/, '.dep');
        depfile = fs.CreateTextFile(depfilename, true);
        depfile.WriteLine(current_file);
      }
    }
  }

  if (depfile) {
    depfile.Close();
  }

  return deps;
}

function parse_dep_file(srcfile) {
  var depfile = srcfile.replace(/\.(c|cpp)$/, '.dep');
  var objfile = srcfile.replace(/\.(c|cpp)$/, '.obj');

  if (!fs.FileExists(depfile)) {
    return null;
  }
  var f = fs.GetFile(depfile);
  var is = f.OpenAsTextStream(1, 0);
  var deps = parse_dep_stream(is);
  is.Close();

  // Construct the dependency line
  var depline = objfile + ': ' + deps.join(' ');

  return {
    src: srcfile,
    obj: objfile,
    line: depline
  };
}

function load_include_file() {
  var deps = {};
  if (!fs.FileExists(INC_FILE)) {
    return deps;
  }
  var f = fs.GetFile(INC_FILE);
  var is = f.OpenAsTextStream(1, 0);
  var r = /^(.*\.obj):\s+(.*)$/;
  while (!is.AtEndOfStream) {
    var line = is.ReadLine();
    var m = r.exec(line);
    if (!m) {
      continue;
    }
    var key = m[1];
    var deplist = m[2];
    if (key.length > 0 && deplist.length > 0) {
      deps[key] = deplist;
    }
  }
  is.Close();
  return deps;
}

function save_include_file(deps) {
  var of = fs.CreateTextFile(INC_FILE, true);
  for (var key in deps) {
    of.WriteLine(deps[key]);
    // Also generate dependency between .c and .dep file
    var depfile = key.replace(/\.obj$/, '.dep');
    of.WriteLine(depfile + ": " + key);
  }
  of.Close();
}

function print_deps(deps) {
  for (var key in deps) {
    WScript.Echo(key + " -> " + deps[key]);
  }
}

DEPS = load_include_file();

function read_deps_from_stdin() {
  if (WScript.Arguments.length != 2) {
    return false;
  }
  if (WScript.Arguments(0) != '--stdin') {
    return false;
  }
  REL_DIR = WScript.Arguments(1);

  parse_dep_stream(WScript.StdIn, true);

  return true;
}

var find_blacklist = [
  shell.CurrentDirectory + "\\a",
  shell.CurrentDirectory + "\\website",
];

function is_blacklisted_dir(dir) {
  var i = find_blacklist.length;
  while (i--) {
    if (find_blacklist[i] == dir) {
      return true;
    }
  }
  return false;
}

function find_c_files(dir) {
  if (is_blacklisted_dir(dir) || /\.(git|hg|svn)/.exec(dir)) {
    return;
  }
  var f = fs.GetFolder(dir);
  var en = new Enumerator(f.files);
  for (; !en.atEnd(); en.moveNext()) {
    var item = en.item();
    if (/\.(c|cpp)$/.exec(item)) {
      var rel = item.Path.substr(cwd.length);
      var dep = parse_dep_file(rel);
      if (dep) {
        DEPS[dep.obj] = dep.line;
      }
    }
  }
  en = new Enumerator(f.subfolders);
  for (; !en.atEnd(); en.moveNext()) {
    var item = en.item();
    find_c_files(item);
  }
}

if (read_deps_from_stdin()) {
  WScript.Quit(0);
} else {
  find_c_files(shell.CurrentDirectory);
  save_include_file(DEPS);
}
<commit_msg>watchman: [EASY] remove another bit of the old windows build stuff<commit_after><|endoftext|>