<commit_before><commit_msg>Add skeleton of integration script<commit_after>/*
 * Copyright 2014 Jiří Janoušek <janousek.jiri@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

(function(Nuvola)
{

// Create media player component
var player = Nuvola.$object(Nuvola.MediaPlayer);

// Handy aliases
var PlaybackState = Nuvola.PlaybackState;
var PlayerAction = Nuvola.PlayerAction;

// Create new WebApp prototype
var WebApp = Nuvola.$WebApp();

// Initialization routines
WebApp._onInitWebWorker = function(emitter)
{
    Nuvola.WebApp._onInitWebWorker.call(this, emitter);

    var state = document.readyState;
    if (state === "interactive" || state === "complete")
        this._onPageReady();
    else
        document.addEventListener("DOMContentLoaded", this._onPageReady.bind(this));
}

// Page is ready for magic
WebApp._onPageReady = function()
{
    // Connect handler for signal ActionActivated
    Nuvola.actions.connect("ActionActivated", this);

    // Start update routine
    this.update();
}

// Extract data from the web page
WebApp.update = function()
{
    var track = {
        title: null,
        artist: null,
        album: null,
        artLocation: null
    }

    player.setTrack(track);
    player.setPlaybackState(PlaybackState.UNKNOWN);

    // Schedule the next update
    setTimeout(this.update.bind(this), 500);
}

// Handler of playback actions
WebApp._onActionActivated = function(emitter, name, param)
{
}

WebApp.start();

})(this);  // function(Nuvola)
<|endoftext|>


<commit_before>import fs from 'fs-extra'
import _debug from 'debug'
import webpackCompiler from '../build/webpack-compiler'
import webpackConfig from '../build/webpack.config'
import config from '../config'

const debug = _debug('app:bin:compile')
const paths = config.utils_paths

;(async function () {
  try {
    debug('Run compiler')
    const stats = await webpackCompiler(webpackConfig)
    console.log('stats', stats)
    if (stats.warnings.length && config.compiler_fail_on_warning) {
      debug('Config set to fail on warning, exiting with status code "1".')
      process.exit(1)
    }
    debug('Copy static assets to dist folder.')
    fs.copySync(paths.client('static'), paths.dist())
  } catch (e) {
    debug('Compiler encountered an error.', e)
    process.exit(1)
  }
})()
<commit_msg>chore(compile): remove debug log statement<commit_after>import fs from 'fs-extra'
import _debug from 'debug'
import webpackCompiler from '../build/webpack-compiler'
import webpackConfig from '../build/webpack.config'
import config from '../config'

const debug = _debug('app:bin:compile')
const paths = config.utils_paths

;(async function () {
  try {
    debug('Run compiler')
    const stats = await webpackCompiler(webpackConfig)
    // console.log('stats', stats)
    if (stats.warnings.length && config.compiler_fail_on_warning) {
      debug('Config set to fail on warning, exiting with status code "1".')
      process.exit(1)
    }
    debug('Copy static assets to dist folder.')
    fs.copySync(paths.client('static'), paths.dist())
  } catch (e) {
    debug('Compiler encountered an error.', e)
    process.exit(1)
  }
})()
<|endoftext|>


<commit_before>/**
* LAVA Sidebar plugin for jQuery
* http://launchpad.net/lava-server/
* Copyright (c): 2011 Zygmunt Krynicki
* Licensed under AGPLv3.
**/
(function($) {
  var baseClass = "lava-sidebar";
  var hiddenClass = "lava-sidebar-hidden";

  $.widget("lava.sidebar", {
    options: {
      // hidden by default (unless pinned)
      hidden: false,
      // pinned by default (so users see the sidebar by default
      // but can un-pin it if desired)
      pinned: false,
      pinnedCookieName: "lava-sidebar-pinned",
      pinnedCookiePath: "/",
      extraControls: [],
      onShow: null,
      onHide: null,
      onDestroy: null,
      onPin: null,
      onUnpin: null,
    },
    _pin_button: null,
    _close_button: null,
    _controls: null,
    controls: function() {
      /* Container of sidebar controls */
      return this._controls;
    },
    _create: function() {
      /* Constructor */
      var self = this;
      if (this.element.html().trim() == "") {
        // If the sidebar was empty then just hide it
        this.element.hide();
      } else {
        // Load cookie to check for pin status
        this._load_pin_option();
        // Initialize basic stuff:
        // 1) css class
        // 2) click handler
        this.element
          .addClass(baseClass)
          .bind("click.sidebar", function(event) {
            if (self.element.hasClass(hiddenClass)) {
              self.show();
              event.preventDefault();
              event.stopPropagation();
            }
          });
        // Initialize controls bar
        self._controls = $("<div/>", {
            "class": "lava-sidebar-controls"
          })
          .prependTo(this.element);
        // Initialize pin button
        self._pin_button = $("<span/>", {
            title: "Pin/unpin the sidebar"
          })
        .button({
            text: false,
            icons: { primary: this.options.pinned ? 'ui-icon-pin-s' : 'ui-icon-pin-w'}
          })
          .click(function(event) {
            self.element.sidebar("option", "pinned", !self.options.pinned);
          })
          .appendTo(self._controls);
        // Initialize close button
        self._close_button = $("<span/>", {
            title: "Collapse the sidebar"
          })
          .button({
            text: false,
            icons: { primary: 'ui-icon-circle-triangle-e'}
          })
          .bind("click", function(event) {
            self.hide();
            event.preventDefault();
            event.stopPropagation();
          })
          .appendTo(self._controls);
        $.each(self.options.extraControls, function(index, control) {
          control.appendTo(self._controls);
        });
      }
    },
    _init: function() {
      /* Initializer */
      if (this.options.pinned == false && this.options.hidden == true) {
        this.hide();
      } else {
        this.show();
      }
    },
    destroy: function() {
      /* Destructor */
      this.element.removeClass(baseClass);
      this.element.removeClass(hiddenClass);
      this.element.unbind("click.sidebar");
      this._controls.remove();
      $.Widget.prototype.destroy.call(this);
      if (this.options.onDestroy) {
        this.options.onDestroy();
      }
    },
    show: function() {
      /* Show the sidebar */
      this.element.removeClass(hiddenClass);
      this.options.hidden = false;
      if (this.options.onShow) {
        this.options.onShow();
      }
    },
    hide: function() {
      /* Hide the sidebar */
      this.element.addClass(hiddenClass);
      this.options.hidden = true;
      if (this.options.onHide) {
        this.options.onHide();
      }
    },
    pin: function() {
      /* Pin the sidebar so that it is shown by default */
      this._set_pinned(true);
    },
    unpin: function() {
      /* Unpin the sidebar */
      this._set_pinned(false);
    },
    _set_pinned: function(pin_state) {
      this.options.pinned = (pin_state == true);
      this._pin_button.button("option", "icons", { primary: this.options.pinned ? 'ui-icon-pin-s' : 'ui-icon-pin-w'});
      this._save_pin_option();
      if (this.options.pinned == true && this.options.onPin) {
        this.options.onPin();
      }
      if (this.options.pinned == false && this.options.onUnpin) {
        this.options.onUnpin();
      }
    },
    _load_pin_option: function() {
      this.options.pinned = $.cookie(
        this.options.pinnedCookieName, {
          path: this.optionsPinnedCookiePath,
          expires: 365
        }) == "pinned";
    },
    _save_pin_option: function() {
      $.cookie(
        this.options.pinnedCookieName,
        this.options.pinned ? "pinned" : "", {
          path: this.options.pinnedCookiePath,
          expires: 365
        });
    },
    _setOption: function(key, value) {
      /* jQueryUI widget method for implementing option setter */
      $.Widget.prototype._setOption.apply(this, arguments);
      if (key == "hidden") {
        if (value) {
          this.hide();
        } else {
          this.show();
        }
      }
      if (key == "pinned") {
        this._set_pinned(value);
      }
    }
  });
})(jQuery);
<commit_msg>Fix defaults so that pinning the sidebar has side effects<commit_after>/**
* LAVA Sidebar plugin for jQuery
* http://launchpad.net/lava-server/
* Copyright (c): 2011 Zygmunt Krynicki
* Licensed under AGPLv3.
**/
(function($) {
  var baseClass = "lava-sidebar";
  var hiddenClass = "lava-sidebar-hidden";

  $.widget("lava.sidebar", {
    options: {
      // hidden by default (unless pinned)
      hidden: true,
      // not pinned by default
      pinned: false,
      pinnedCookieName: "lava-sidebar-pinned",
      pinnedCookiePath: "/",
      extraControls: [],
      onShow: null,
      onHide: null,
      onDestroy: null,
      onPin: null,
      onUnpin: null,
    },
    _pin_button: null,
    _close_button: null,
    _controls: null,
    controls: function() {
      /* Container of sidebar controls */
      return this._controls;
    },
    _create: function() {
      /* Constructor */
      var self = this;
      if (this.element.html().trim() == "") {
        // If the sidebar was empty then just hide it
        this.element.hide();
      } else {
        // Load cookie to check for pin status
        this._load_pin_option();
        // Initialize basic stuff:
        // 1) css class
        // 2) click handler
        this.element
          .addClass(baseClass)
          .bind("click.sidebar", function(event) {
            if (self.element.hasClass(hiddenClass)) {
              self.show();
              event.preventDefault();
              event.stopPropagation();
            }
          });
        // Initialize controls bar
        self._controls = $("<div/>", {
            "class": "lava-sidebar-controls"
          })
          .prependTo(this.element);
        // Initialize pin button
        self._pin_button = $("<span/>", {
            title: "Pin/unpin the sidebar"
          })
        .button({
            text: false,
            icons: { primary: this.options.pinned ? 'ui-icon-pin-s' : 'ui-icon-pin-w'}
          })
          .click(function(event) {
            self.element.sidebar("option", "pinned", !self.options.pinned);
          })
          .appendTo(self._controls);
        // Initialize close button
        self._close_button = $("<span/>", {
            title: "Collapse the sidebar"
          })
          .button({
            text: false,
            icons: { primary: 'ui-icon-circle-triangle-e'}
          })
          .bind("click", function(event) {
            self.hide();
            event.preventDefault();
            event.stopPropagation();
          })
          .appendTo(self._controls);
        $.each(self.options.extraControls, function(index, control) {
          control.appendTo(self._controls);
        });
      }
    },
    _init: function() {
      /* Initializer */
      if (this.options.pinned == false && this.options.hidden == true) {
        this.hide();
      } else {
        this.show();
      }
    },
    destroy: function() {
      /* Destructor */
      this.element.removeClass(baseClass);
      this.element.removeClass(hiddenClass);
      this.element.unbind("click.sidebar");
      this._controls.remove();
      $.Widget.prototype.destroy.call(this);
      if (this.options.onDestroy) {
        this.options.onDestroy();
      }
    },
    show: function() {
      /* Show the sidebar */
      this.element.removeClass(hiddenClass);
      this.options.hidden = false;
      if (this.options.onShow) {
        this.options.onShow();
      }
    },
    hide: function() {
      /* Hide the sidebar */
      this.element.addClass(hiddenClass);
      this.options.hidden = true;
      if (this.options.onHide) {
        this.options.onHide();
      }
    },
    pin: function() {
      /* Pin the sidebar so that it is shown by default */
      this._set_pinned(true);
    },
    unpin: function() {
      /* Unpin the sidebar */
      this._set_pinned(false);
    },
    _set_pinned: function(pin_state) {
      this.options.pinned = (pin_state == true);
      this._pin_button.button("option", "icons", { primary: this.options.pinned ? 'ui-icon-pin-s' : 'ui-icon-pin-w'});
      this._save_pin_option();
      if (this.options.pinned == true && this.options.onPin) {
        this.options.onPin();
      }
      if (this.options.pinned == false && this.options.onUnpin) {
        this.options.onUnpin();
      }
    },
    _load_pin_option: function() {
      this.options.pinned = $.cookie(
        this.options.pinnedCookieName, {
          path: this.optionsPinnedCookiePath,
          expires: 365
        }) == "pinned";
    },
    _save_pin_option: function() {
      $.cookie(
        this.options.pinnedCookieName,
        this.options.pinned ? "pinned" : "", {
          path: this.options.pinnedCookiePath,
          expires: 365
        });
    },
    _setOption: function(key, value) {
      /* jQueryUI widget method for implementing option setter */
      $.Widget.prototype._setOption.apply(this, arguments);
      if (key == "hidden") {
        if (value) {
          this.hide();
        } else {
          this.show();
        }
      }
      if (key == "pinned") {
        this._set_pinned(value);
      }
    }
  });
})(jQuery);
<|endoftext|>


<commit_before>// Copyright 2013-2016, University of Colorado Boulder

/**
 * Configuration file for development and production deployments.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

require.config( {
  // depends on all of Scenery, Kite, Dot, Axon and phet-core
  deps: [ 'main', 'KITE/main', 'DOT/main', 'AXON/main', 'PHET_CORE/main' ],

  paths: {

    // plugins
    image: '../../chipper/js/requirejs-plugins/image',
    ifphetio: '../../chipper/js/requirejs-plugins/ifphetio',

    // third-party libs
    text: '../../sherpa/lib/text-2.0.12',

    AXON: '../../axon/js',

    DOT: '../../dot/js',
    KITE: '../../kite/js',
    PHET_CORE: '../../phet-core/js',
    SCENERY: '.',
    TANDEM: '../../tandem/js',

    REPOSITORY: '..'
  },

  // optional cache buster to make browser refresh load all included scripts, can be disabled with ?cacheBuster=false
  urlArgs: Date.now()
} );
<commit_msg>Fix urlArgs arguments, see https://github.com/phetsims/sherpa/issues/76<commit_after>// Copyright 2013-2016, University of Colorado Boulder

/**
 * Configuration file for development and production deployments.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

require.config( {
  // depends on all of Scenery, Kite, Dot, Axon and phet-core
  deps: [ 'main', 'KITE/main', 'DOT/main', 'AXON/main', 'PHET_CORE/main' ],

  paths: {

    // plugins
    image: '../../chipper/js/requirejs-plugins/image',
    ifphetio: '../../chipper/js/requirejs-plugins/ifphetio',

    // third-party libs
    text: '../../sherpa/lib/text-2.0.12',

    AXON: '../../axon/js',

    DOT: '../../dot/js',
    KITE: '../../kite/js',
    PHET_CORE: '../../phet-core/js',
    SCENERY: '.',
    TANDEM: '../../tandem/js',

    REPOSITORY: '..'
  },

  // optional cache buster to make browser refresh load all included scripts, can be disabled with ?cacheBuster=false
  urlArgs: 'bust=' + ( new Date() ).getTime()
} );
<|endoftext|>


<commit_before>import React, {
  Fragment,
  Children,
  cloneElement,
  useRef,
  useEffect
} from 'react';
import { createPortal } from 'react-dom';
import PropTypes from 'prop-types';
import cx from 'classnames';

import idgen from './idgen';
import Button from './Button';

const Modal = ({
  actions,
  bottomSheet,
  children,
  fixedFooter,
  header,
  className,
  trigger,
  options,
  open,
  root,
  ...props
}) => {
  const _modalRoot = useRef(null);
  const _modalInstance = useRef(null);
  const _modalRef = useRef(null);
  if (root === null) {
    console.warn(
      'React Materialize: root should be a valid node element to render a Modal'
    );
  }

  useEffect(() => {
    const modalRoot = _modalRoot.current;
    _modalInstance.current = M.Modal.init(_modalRef.current, options);

    return () => {
      root.removeChild(modalRoot);
      _modalInstance.current.destroy();
    };
  }, [options, root, children]);

  useEffect(() => {
    if (open) {
      showModal();
    } else {
      hideModal();
    }
  }, [open]);

  const showModal = e => {
    e && e.preventDefault();

    _modalInstance.current && _modalInstance.current.open();
  };

  const hideModal = e => {
    e && e.preventDefault();

    _modalInstance.current && _modalInstance.current.close();
  };

  const classes = cx(
    'modal',
    {
      'modal-fixed-footer': fixedFooter,
      'bottom-sheet': bottomSheet
    },
    className
  );

  const renderModalPortal = () => {
    if (!_modalRoot.current) {
      _modalRoot.current = document.createElement('div');
      root.appendChild(_modalRoot.current);
    }

    return createPortal(

{header}

          {children}

{Children.toArray(actions)}

,
      _modalRoot.current
    );
  };

  return (
    <Fragment>
      {trigger && cloneElement(trigger, { onClick: showModal })}
      {renderModalPortal()}
    </Fragment>
  );
};

Modal.propTypes = {
  /**
   * Options
   * Object with options for modal
   */
  options: PropTypes.shape({
    /**
     * Opacity of the modal overlay.
     */
    opacity: PropTypes.number,
    /**
     * Transition in duration in milliseconds.
     */
    inDuration: PropTypes.number,
    /**
     * Transition out duration in milliseconds.
     */
    outDuration: PropTypes.number,
    /**
     * Callback function called before modal is opened.
     */
    onOpenStart: PropTypes.func,
    /**
     * Callback function called after modal is opened.
     */
    onOpenEnd: PropTypes.func,
    /**
     * Callback function called before modal is closed.
     */
    onCloseStart: PropTypes.func,
    /**
     * Callback function called after modal is closed.
     */
    onCloseEnd: PropTypes.func,
    /**
     * Prevent page from scrolling while modal is open.
     */
    preventScrolling: PropTypes.bool,
    /**
     * Allow modal to be dismissed by keyboard or overlay click.
     */
    dismissible: PropTypes.bool,
    /**
     * Starting top offset
     */
    startingTop: PropTypes.string,
    /**
     * Ending top offset
     */
    endingTop: PropTypes.string
  }),
  /**
   * Extra class to added to the Modal
   */
  className: PropTypes.string,
  /**
   * Modal is opened on mount
   * @default false
   */
  open: PropTypes.bool,
  /**
   * BottomSheet styled modal
   * @default false
   */
  bottomSheet: PropTypes.bool,
  /**
   * Component children
   */
  children: PropTypes.node,
  /**
   * FixedFooter styled modal
   * @default false
   */
  fixedFooter: PropTypes.bool,
  /**
   * Text to shown in the header of the modal
   */
  header: PropTypes.string,
  /**
   * The button to trigger the display of the modal
   */
  trigger: PropTypes.node,
  /**
   * The buttons to show in the footer of the modal
   * @default <Button>Close</Button>
   */
  actions: PropTypes.node,
  /**
   * The ID to trigger the modal opening/closing
   */
  id: PropTypes.string,
  /**
   * Root node where modal should be injected
   * @default document.body
   */
  root: PropTypes.any
};

Modal.defaultProps = {
  id: `Modal-${idgen()}`,
  root: typeof window !== 'undefined' ? document.body : null,
  open: false,
  options: {
    opacity: 0.5,
    inDuration: 250,
    outDuration: 250,
    onOpenStart: null,
    onOpenEnd: null,
    onCloseStart: null,
    onCloseEnd: null,
    preventScrolling: true,
    dismissible: true,
    startingTop: '4%',
    endingTop: '10%'
  },
  fixedFooter: false,
  bottomSheet: false,
  actions: [
    <Button waves="green" modal="close" flat>
      Close
    </Button>
  ]
};

export default Modal;
<commit_msg>Modal: remove children from reinitialize dependency<commit_after>import React, {
  Fragment,
  Children,
  cloneElement,
  useRef,
  useEffect
} from 'react';
import { createPortal } from 'react-dom';
import PropTypes from 'prop-types';
import cx from 'classnames';

import idgen from './idgen';
import Button from './Button';

const Modal = ({
  actions,
  bottomSheet,
  children,
  fixedFooter,
  header,
  className,
  trigger,
  options,
  open,
  root,
  ...props
}) => {
  const _modalRoot = useRef(null);
  const _modalInstance = useRef(null);
  const _modalRef = useRef(null);
  if (root === null) {
    console.warn(
      'React Materialize: root should be a valid node element to render a Modal'
    );
  }

  useEffect(() => {
    const modalRoot = _modalRoot.current;
    _modalInstance.current = M.Modal.init(_modalRef.current, options);

    return () => {
      root.removeChild(modalRoot);
      _modalInstance.current.destroy();
    };
  }, [options, root]);

  useEffect(() => {
    if (open) {
      showModal();
    } else {
      hideModal();
    }
  }, [open]);

  const showModal = e => {
    e && e.preventDefault();

    _modalInstance.current && _modalInstance.current.open();
  };

  const hideModal = e => {
    e && e.preventDefault();

    _modalInstance.current && _modalInstance.current.close();
  };

  const classes = cx(
    'modal',
    {
      'modal-fixed-footer': fixedFooter,
      'bottom-sheet': bottomSheet
    },
    className
  );

  const renderModalPortal = () => {
    if (!_modalRoot.current) {
      _modalRoot.current = document.createElement('div');
      root.appendChild(_modalRoot.current);
    }

    return createPortal(

{header}

          {children}

{Children.toArray(actions)}

,
      _modalRoot.current
    );
  };

  return (
    <Fragment>
      {trigger && cloneElement(trigger, { onClick: showModal })}
      {renderModalPortal()}
    </Fragment>
  );
};

Modal.propTypes = {
  /**
   * Options
   * Object with options for modal
   */
  options: PropTypes.shape({
    /**
     * Opacity of the modal overlay.
     */
    opacity: PropTypes.number,
    /**
     * Transition in duration in milliseconds.
     */
    inDuration: PropTypes.number,
    /**
     * Transition out duration in milliseconds.
     */
    outDuration: PropTypes.number,
    /**
     * Callback function called before modal is opened.
     */
    onOpenStart: PropTypes.func,
    /**
     * Callback function called after modal is opened.
     */
    onOpenEnd: PropTypes.func,
    /**
     * Callback function called before modal is closed.
     */
    onCloseStart: PropTypes.func,
    /**
     * Callback function called after modal is closed.
     */
    onCloseEnd: PropTypes.func,
    /**
     * Prevent page from scrolling while modal is open.
     */
    preventScrolling: PropTypes.bool,
    /**
     * Allow modal to be dismissed by keyboard or overlay click.
     */
    dismissible: PropTypes.bool,
    /**
     * Starting top offset
     */
    startingTop: PropTypes.string,
    /**
     * Ending top offset
     */
    endingTop: PropTypes.string
  }),
  /**
   * Extra class to added to the Modal
   */
  className: PropTypes.string,
  /**
   * Modal is opened on mount
   * @default false
   */
  open: PropTypes.bool,
  /**
   * BottomSheet styled modal
   * @default false
   */
  bottomSheet: PropTypes.bool,
  /**
   * Component children
   */
  children: PropTypes.node,
  /**
   * FixedFooter styled modal
   * @default false
   */
  fixedFooter: PropTypes.bool,
  /**
   * Text to shown in the header of the modal
   */
  header: PropTypes.string,
  /**
   * The button to trigger the display of the modal
   */
  trigger: PropTypes.node,
  /**
   * The buttons to show in the footer of the modal
   * @default <Button>Close</Button>
   */
  actions: PropTypes.node,
  /**
   * The ID to trigger the modal opening/closing
   */
  id: PropTypes.string,
  /**
   * Root node where modal should be injected
   * @default document.body
   */
  root: PropTypes.any
};

Modal.defaultProps = {
  id: `Modal-${idgen()}`,
  root: typeof window !== 'undefined' ? document.body : null,
  open: false,
  options: {
    opacity: 0.5,
    inDuration: 250,
    outDuration: 250,
    onOpenStart: null,
    onOpenEnd: null,
    onCloseStart: null,
    onCloseEnd: null,
    preventScrolling: true,
    dismissible: true,
    startingTop: '4%',
    endingTop: '10%'
  },
  fixedFooter: false,
  bottomSheet: false,
  actions: [
    <Button waves="green" modal="close" flat>
      Close
    </Button>
  ]
};

export default Modal;
<|endoftext|>


<commit_before>// Returns CJS module (sync or async) path resolver

"use strict";

var dirname = function (path) {
	return path.slice(0, path.lastIndexOf("/")) || "/";
};
var join = function (path1, path2) {
	return path1 === "/" ? path1 + path2 : path1 + "/" + path2;
};

module.exports = function (extensions, confirmFile, resolvePackageMain) {
	var resolveFile = function (path, extIndex) {
		var targetPath = path + (extIndex == null ? "" : extensions[extIndex]);
		return confirmFile(targetPath).then(function (result) {
			if (result) return result;
			if (extIndex == null) extIndex = 0;
			else ++extIndex;
			if (!extensions[extIndex]) return null;
			return resolveFile(path, extIndex);
		});
	};
	var resolveDirectory = function (path) {
		return resolvePackageMain(path).then(function (result) {
			if (result) {
				var mainPath = join(path, result);
				return resolveFile(mainPath).then(function (mainResult) {
					if (mainResult) return mainResult;
					return resolveFile(join(mainPath, "index"), 0);
				});
			}
			return resolveFile(join(path, "index"), 0);
		});
	};
	var resolveLocal = function (path) {
		var pathChar = path.charAt(path.length - 1);
		if (pathChar === "/") return resolveDirectory(path);
		if (pathChar === ".") {
			pathChar = path.charAt(path.length - 2);
			if (pathChar === "/") return resolveDirectory(path);
			if (pathChar === ".") {
				if (path.charAt(path.length - 3) === "/") return resolveDirectory(path);
			}
		}
		return resolveFile(path).then(function (result) {
			return result || resolveDirectory(path);
		});
	};
	var resolveExternal = function (dir, path) {
		return resolveLocal(join(dir, "node_modules") + "/" + path).then(function (result) {
			if (result) return result;
			if (dir === "/") return null;
			return resolveExternal(dirname(dir), path);
		});
	};
	return function (dir, path) {
		var pathChar;
		if (path.charAt(0) === "/") return resolveLocal(path);
		if (path.charAt(0) === ".") {
			pathChar = path.charAt(1);
			if (!pathChar || pathChar === "/") return resolveLocal(join(dir, path));
			if (pathChar === ".") {
				pathChar = path.charAt(2);
				if (!pathChar || pathChar === "/") return resolveLocal(join(dir, path));
			}
		}
		return resolveExternal(dir, path);
	};
};
<commit_msg>style: prettier<commit_after>// Returns CJS module (sync or async) path resolver

"use strict";

var dirname = function (path) { return path.slice(0, path.lastIndexOf("/")) || "/"; };
var join = function (path1, path2) { return path1 === "/" ? path1 + path2 : path1 + "/" + path2; };

module.exports = function (extensions, confirmFile, resolvePackageMain) {
	var resolveFile = function (path, extIndex) {
		var targetPath = path + (extIndex == null ? "" : extensions[extIndex]);
		return confirmFile(targetPath).then(function (result) {
			if (result) return result;
			if (extIndex == null) extIndex = 0;
			else ++extIndex;
			if (!extensions[extIndex]) return null;
			return resolveFile(path, extIndex);
		});
	};
	var resolveDirectory = function (path) {
		return resolvePackageMain(path).then(function (result) {
			if (result) {
				var mainPath = join(path, result);
				return resolveFile(mainPath).then(function (mainResult) {
					if (mainResult) return mainResult;
					return resolveFile(join(mainPath, "index"), 0);
				});
			}
			return resolveFile(join(path, "index"), 0);
		});
	};
	var resolveLocal = function (path) {
		var pathChar = path.charAt(path.length - 1);
		if (pathChar === "/") return resolveDirectory(path);
		if (pathChar === ".") {
			pathChar = path.charAt(path.length - 2);
			if (pathChar === "/") return resolveDirectory(path);
			if (pathChar === ".") {
				if (path.charAt(path.length - 3) === "/") return resolveDirectory(path);
			}
		}
		return resolveFile(path).then(function (result) {
			return result || resolveDirectory(path);
		});
	};
	var resolveExternal = function (dir, path) {
		return resolveLocal(join(dir, "node_modules") + "/" + path).then(function (result) {
			if (result) return result;
			if (dir === "/") return null;
			return resolveExternal(dirname(dir), path);
		});
	};
	return function (dir, path) {
		var pathChar;
		if (path.charAt(0) === "/") return resolveLocal(path);
		if (path.charAt(0) === ".") {
			pathChar = path.charAt(1);
			if (!pathChar || pathChar === "/") return resolveLocal(join(dir, path));
			if (pathChar === ".") {
				pathChar = path.charAt(2);
				if (!pathChar || pathChar === "/") return resolveLocal(join(dir, path));
			}
		}
		return resolveExternal(dir, path);
	};
};
<|endoftext|>


<commit_before>// Debug tasks with:
// iron-node $(which gulp) build

'use strict';

var gulp          = require('gulp');
var filter        = require('gulp-filter');
var util          = require('gulp-util');
var htmlmin       = require('gulp-htmlmin');
var ignore        = require('gulp-ignore');
var rename        = require('gulp-rename');
var marked        = require('gulp-markdown');
var frontMatter   = require('gulp-front-matter');

var through2      = require('through2');
var es            = require('event-stream');
var runSequence   = require('run-sequence');
var webpack       = require('webpack');
var settings      = require('./config/settings');
var argv          = require('minimist')(process.argv.slice(2));
var path          = require('path');
var _             = require("lodash");
var fs            = require("fs");
var mkdirp        = require("mkdirp");
var ejs           = require('ejs');

// Settings
var release       = argv.release;
var stage         = release ? "production" : "development";
var outputPath    = release ? settings.prodOutput : settings.devOutput;
var webpackConfig = require('./config/webpack.config')(stage);
var webpackStats;

var defaultLayout = 'application.html';

// -----------------------------------------------------------------------------
// Clean up
// -----------------------------------------------------------------------------
gulp.task('clean', function(cb){
  var rimraf = require('rimraf');
  rimraf(outputPath, cb);
});

// -----------------------------------------------------------------------------
// Copy vendor files
// -----------------------------------------------------------------------------
// Use this task to copy assets (ie fonts) from node modules
gulp.task('vendor', function(){
  return es.merge(
    gulp.src('./node_modules/bootstrap-sass/assets/fonts/**')
      .pipe(gulp.dest(outputPath + '/fonts')),
    gulp.src('./node_modules/font-awesome/fonts/**')
      .pipe(gulp.dest(outputPath + '/fonts'))
  );
});

// -----------------------------------------------------------------------------
// Build markdown files
// -----------------------------------------------------------------------------
gulp.task('markdown', function(){

  var options = {
    gfm: true,
    tables: true,
    breaks: false,
    pedantic: false,
    sanitize: false,
    smartLists: true,
    smartypants: false
    // highlight: function (code, lang, callback) {
    //   require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {
    //     callback(err, result.toString());
    //   });
    // }
  };

  return gulp.src('./html/**/*.md')
    .pipe(frontMatter({property: 'metadata', remove: true}))
    .pipe(marked(options))
    .pipe(applyLayout(defaultLayout))
    .pipe(applyWebpack()) // Change to webpack hashed file names in release
    .pipe(!release ? util.noop() : htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      minifyJS: true
    }))
    .pipe(rename({extname: '.html'}))
    .pipe(gulp.dest(outputPath));
});

// -----------------------------------------------------------------------------
// Process files in the html diretory
// -----------------------------------------------------------------------------
gulp.task('html', function(){

  var htmlFilter = filter('**/*.html', {restore: true});

  return gulp.src('./html/**/*')
    .pipe(ignore.exclude('layouts/**'))
    .pipe(ignore.exclude('layouts'))
    .pipe(ignore.exclude('partials/**'))
    .pipe(ignore.exclude('partials'))
    .pipe(ignore.exclude('**/*.md'))
    .pipe(htmlFilter)
    .pipe(applyLayout(defaultLayout))
    .pipe(applyWebpack()) // Change to webpack hashed file names in release
    .pipe(!release ? util.noop() : htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      minifyJS: true
    }))
    .pipe(htmlFilter.restore)
    .pipe(gulp.dest(outputPath));
});

// -----------------------------------------------------------------------------
// Create JavaScript bundle
// -----------------------------------------------------------------------------
gulp.task('javascript', function(cb){

  var bundler = webpack(webpackConfig);
  function bundle(err, stats){
    webpackStats = stats.toJson();
    if (err){
      throw new util.PluginError('webpack', err);
    }
    //util.log('[webpack]', stats.toString({colors: true}));
    cb();
  }
  bundler.run(bundle);
});

// -----------------------------------------------------------------------------
// Create Canvas API Manifest
// -----------------------------------------------------------------------------
gulp.task('canvas_manifest', function(){
  return gulp.src('./js/**/*')
    .pipe(writeCanvasManifest());
});

// -----------------------------------------------------------------------------
// Build the app from source code
// -----------------------------------------------------------------------------
gulp.task('build', ['clean'], function(cb){
  runSequence('canvas_manifest', 'javascript', ['html', 'markdown'], cb);
});

// -----------------------------------------------------------------------------
// Watch for changes to html files and rebuild as needed. Webpack watches everything else
// and serves js, css, etc from memory. Html files are served from the build directory.
// -----------------------------------------------------------------------------
gulp.task('watch', ['html', 'markdown'], function() {
  gulp.watch(['html/**/*'], ['html', 'markdown']);
});

// -----------------------------------------------------------------------------
// The default task
// -----------------------------------------------------------------------------
gulp.task('default', ['watch']);

// *****************************************************************************
// A bit hackish. This function can't be called until after the javascript task has been run
// because webpackStats is undefined until webpack has run.
// *****************************************************************************
function getHashed(entryPoint, ext){
  return _.find(webpackStats.assetsByChunkName[entryPoint], function(hashEntry){
    return path.extname(hashEntry).toLowerCase() === '.' + ext;
  });
}

// *****************************************************************************
// Changes webpack paths as needed.
// *****************************************************************************
function applyWebpack(){
  return through2.obj(function (html, enc, cb) { // replace entry points with names generated by webpack
    if(release){
      var result = String(html.contents);
      _.each(webpackConfig.entry, function(path, entry){
        if(_.has(settings.entries, entry)){
          result = result.replace(entry + settings.buildSuffix, getHashed(entry, 'js'));
        } else if(_.has(settings.cssEntries, entry)){
          result = result.replace(entry + '.css', getHashed(entry, 'css'));
        }
      });
      html.contents = new Buffer(result);
    }
    this.push(html);
    cb();
  });
}

// *****************************************************************************
// Find calls to the Canvas API in the code and generate a manifest file
// *****************************************************************************
function writeCanvasManifest(){
  var canvasApiCalls = [];
  return through2.obj(function(file, enc, cb){
    if(file.contents){

      var contents = file.contents.toString();
      var match;

      // Find individual imports
      // import { list_users_in_course_users } from "../../libs/canvas/constants/courses";
      // import { list_users_in_course_users, other_thing } from "../../libs/canvas/constants/courses";
      var singleImportRegex = /.*import\s+\{\s*([\w_,]+)\s*\}.+\/libs\/canvas\/constants\/(.+)"/g;

      // Find bulk imports
      // import * as AssignmentConstants from "../../libs/canvas/constants/assignments";
      var bulkImportRegEx = /.*import\s+\*.+\/libs\/canvas\/constants\/(.+)"/g;

      // Find contants in canvas contants files
      //export const delete_assignment = { type: "DELETE_ASSIGNMENT", method: "delete", reducer: 'assignments'};
      var constantsRegEx = /export const (.+) =/g;

      while(match = findMatch(singleImportRegex, contents)){
        var parts = match[1].split(",");
        _.each(parts, function(part){
          canvasApiCalls.push(_.trim(part));
        });
      }

      while(match = findMatch(bulkImportRegEx, contents)){
        var file = path.join(__dirname + "/js/libs/canvas/constants/", match[1] + ".js");
        console.log("Matching all constants in: " + file);
        var constants = fs.readFileSync(file);

        while(match = findMatch(constantsRegEx, constants)){
          canvasApiCalls.push(match[1]);
        }
      }

    }
    this.push(file);
    cb();
  },
  function(cb) {
    var contents = '["' + canvasApiCalls.join('",\n "') + '"];';
    fs.writeFile(path.join("./", "canvas.manifest"), contents, cb);
  });
}

function findMatch(regEx, content){
  var match;
  if((match = regEx.exec(content)) !== null){
    if(match.index === regEx.lastIndex){
      regEx.lastIndex++;
    }
  }
  return match;
}

// *****************************************************************************
// Apply templates to content
// *****************************************************************************
function applyLayout(defaultLayout){
  return through2.obj(function (file, enc, cb) {

    var data = {
      metadata: file.metadata
    };

    // Allow ejs code in content
    data.content = ejs.compile(String(file.contents), {
      cache: false,
      filename: file.path
    })(data);

    // If the user has specified a layout in the front matter user that.
    // Otherwise use the default
    var layout = file.metadata && file.metadata.layout ? file.metadata.layout : defaultLayout;
    layout = path.extname(layout) ? layout : layout + '.html';
    layout = path.join(__dirname, './html/layouts/' + layout);

    var template = ejs.compile(fs.readFileSync(layout, 'utf8'), {
      cache: false,
      filename: layout
    });

    file.contents = new Buffer(template(data), 'utf8');
    this.push(file);
    cb();

  });
}<commit_msg>Handle multiline import statement<commit_after>// Debug tasks with:
// iron-node $(which gulp) build

'use strict';

var gulp          = require('gulp');
var filter        = require('gulp-filter');
var util          = require('gulp-util');
var htmlmin       = require('gulp-htmlmin');
var ignore        = require('gulp-ignore');
var rename        = require('gulp-rename');
var marked        = require('gulp-markdown');
var frontMatter   = require('gulp-front-matter');

var through2      = require('through2');
var es            = require('event-stream');
var runSequence   = require('run-sequence');
var webpack       = require('webpack');
var settings      = require('./config/settings');
var argv          = require('minimist')(process.argv.slice(2));
var path          = require('path');
var _             = require("lodash");
var fs            = require("fs");
var mkdirp        = require("mkdirp");
var ejs           = require('ejs');

// Settings
var release       = argv.release;
var stage         = release ? "production" : "development";
var outputPath    = release ? settings.prodOutput : settings.devOutput;
var webpackConfig = require('./config/webpack.config')(stage);
var webpackStats;

var defaultLayout = 'application.html';

// -----------------------------------------------------------------------------
// Clean up
// -----------------------------------------------------------------------------
gulp.task('clean', function(cb){
  var rimraf = require('rimraf');
  rimraf(outputPath, cb);
});

// -----------------------------------------------------------------------------
// Copy vendor files
// -----------------------------------------------------------------------------
// Use this task to copy assets (ie fonts) from node modules
gulp.task('vendor', function(){
  return es.merge(
    gulp.src('./node_modules/bootstrap-sass/assets/fonts/**')
      .pipe(gulp.dest(outputPath + '/fonts')),
    gulp.src('./node_modules/font-awesome/fonts/**')
      .pipe(gulp.dest(outputPath + '/fonts'))
  );
});

// -----------------------------------------------------------------------------
// Build markdown files
// -----------------------------------------------------------------------------
gulp.task('markdown', function(){

  var options = {
    gfm: true,
    tables: true,
    breaks: false,
    pedantic: false,
    sanitize: false,
    smartLists: true,
    smartypants: false
    // highlight: function (code, lang, callback) {
    //   require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {
    //     callback(err, result.toString());
    //   });
    // }
  };

  return gulp.src('./html/**/*.md')
    .pipe(frontMatter({property: 'metadata', remove: true}))
    .pipe(marked(options))
    .pipe(applyLayout(defaultLayout))
    .pipe(applyWebpack()) // Change to webpack hashed file names in release
    .pipe(!release ? util.noop() : htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      minifyJS: true
    }))
    .pipe(rename({extname: '.html'}))
    .pipe(gulp.dest(outputPath));
});

// -----------------------------------------------------------------------------
// Process files in the html diretory
// -----------------------------------------------------------------------------
gulp.task('html', function(){

  var htmlFilter = filter('**/*.html', {restore: true});

  return gulp.src('./html/**/*')
    .pipe(ignore.exclude('layouts/**'))
    .pipe(ignore.exclude('layouts'))
    .pipe(ignore.exclude('partials/**'))
    .pipe(ignore.exclude('partials'))
    .pipe(ignore.exclude('**/*.md'))
    .pipe(htmlFilter)
    .pipe(applyLayout(defaultLayout))
    .pipe(applyWebpack()) // Change to webpack hashed file names in release
    .pipe(!release ? util.noop() : htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      minifyJS: true
    }))
    .pipe(htmlFilter.restore)
    .pipe(gulp.dest(outputPath));
});

// -----------------------------------------------------------------------------
// Create JavaScript bundle
// -----------------------------------------------------------------------------
gulp.task('javascript', function(cb){

  var bundler = webpack(webpackConfig);
  function bundle(err, stats){
    webpackStats = stats.toJson();
    if (err){
      throw new util.PluginError('webpack', err);
    }
    //util.log('[webpack]', stats.toString({colors: true}));
    cb();
  }
  bundler.run(bundle);
});

// -----------------------------------------------------------------------------
// Create Canvas API Manifest
// -----------------------------------------------------------------------------
gulp.task('canvas_manifest', function(){
  return gulp.src('./js/**/*')
    .pipe(writeCanvasManifest());
});

// -----------------------------------------------------------------------------
// Build the app from source code
// -----------------------------------------------------------------------------
gulp.task('build', ['clean'], function(cb){
  runSequence('canvas_manifest', 'javascript', ['html', 'markdown'], cb);
});

// -----------------------------------------------------------------------------
// Watch for changes to html files and rebuild as needed. Webpack watches everything else
// and serves js, css, etc from memory. Html files are served from the build directory.
// -----------------------------------------------------------------------------
gulp.task('watch', ['html', 'markdown'], function() {
  gulp.watch(['html/**/*'], ['html', 'markdown']);
});

// -----------------------------------------------------------------------------
// The default task
// -----------------------------------------------------------------------------
gulp.task('default', ['watch']);

// *****************************************************************************
// A bit hackish. This function can't be called until after the javascript task has been run
// because webpackStats is undefined until webpack has run.
// *****************************************************************************
function getHashed(entryPoint, ext){
  return _.find(webpackStats.assetsByChunkName[entryPoint], function(hashEntry){
    return path.extname(hashEntry).toLowerCase() === '.' + ext;
  });
}

// *****************************************************************************
// Changes webpack paths as needed.
// *****************************************************************************
function applyWebpack(){
  return through2.obj(function (html, enc, cb) { // replace entry points with names generated by webpack
    if(release){
      var result = String(html.contents);
      _.each(webpackConfig.entry, function(path, entry){
        if(_.has(settings.entries, entry)){
          result = result.replace(entry + settings.buildSuffix, getHashed(entry, 'js'));
        } else if(_.has(settings.cssEntries, entry)){
          result = result.replace(entry + '.css', getHashed(entry, 'css'));
        }
      });
      html.contents = new Buffer(result);
    }
    this.push(html);
    cb();
  });
}

// *****************************************************************************
// Find calls to the Canvas API in the code and generate a manifest file
// *****************************************************************************
function writeCanvasManifest(){
  var canvasApiCalls = [];
  return through2.obj(function(file, enc, cb){
    if(file.contents){

      var contents = file.contents.toString();
      var match;

      // Find individual imports
      // import { list_users_in_course_users } from "../../libs/canvas/constants/courses";
      // import { list_users_in_course_users, other_thing } from "../../libs/canvas/constants/courses";
      var singleImportRegex = /.*import\s+\{\s*([\w_,\s]+)\s*\}.+\/libs\/canvas\/constants\/(.+)"/g;

      // Find bulk imports
      // import * as AssignmentConstants from "../../libs/canvas/constants/assignments";
      var bulkImportRegEx = /.*import\s+\*.+\/libs\/canvas\/constants\/(.+)"/g;

      // Find contants in canvas contants files
      //export const delete_assignment = { type: "DELETE_ASSIGNMENT", method: "delete", reducer: 'assignments'};
      var constantsRegEx = /export const (.+) =/g;

      while(match = findMatch(singleImportRegex, contents)){
        var parts = match[1].replace(/\s/g, "").split(",");
        _.each(parts, function(part){
          canvasApiCalls.push(_.trim(part));
        });
      }

      while(match = findMatch(bulkImportRegEx, contents)){
        var file = path.join(__dirname + "/js/libs/canvas/constants/", match[1] + ".js");
        console.log("Matching all constants in: " + file);
        var constants = fs.readFileSync(file);

        while(match = findMatch(constantsRegEx, constants)){
          canvasApiCalls.push(match[1]);
        }
      }

    }
    this.push(file);
    cb();
  },
  function(cb) {
    var contents = '["' + canvasApiCalls.join('",\n "') + '"];';
    fs.writeFile(path.join("./", "canvas.manifest"), contents, cb);
  });
}

function findMatch(regEx, content){
  var match;
  if((match = regEx.exec(content)) !== null){
    if(match.index === regEx.lastIndex){
      regEx.lastIndex++;
    }
  }
  return match;
}

// *****************************************************************************
// Apply templates to content
// *****************************************************************************
function applyLayout(defaultLayout){
  return through2.obj(function (file, enc, cb) {

    var data = {
      metadata: file.metadata
    };

    // Allow ejs code in content
    data.content = ejs.compile(String(file.contents), {
      cache: false,
      filename: file.path
    })(data);

    // If the user has specified a layout in the front matter user that.
    // Otherwise use the default
    var layout = file.metadata && file.metadata.layout ? file.metadata.layout : defaultLayout;
    layout = path.extname(layout) ? layout : layout + '.html';
    layout = path.join(__dirname, './html/layouts/' + layout);

    var template = ejs.compile(fs.readFileSync(layout, 'utf8'), {
      cache: false,
      filename: layout
    });

    file.contents = new Buffer(template(data), 'utf8');
    this.push(file);
    cb();

  });
}<|endoftext|>


<commit_before>import Ember from 'ember';
import layout from '../templates/components/animated-container';
import Resize from '../motions/resize';
import { task } from 'ember-concurrency';
import { Promise } from '../concurrency-helpers';
import Sprite from '../sprite';

export default Ember.Component.extend({
  layout,
  classNames: ['animated-container'],

  init() {
    this._super();
    this._signals = null;
    this._signalWaiter = null;
  },

  animate: task(function * () {
    yield* this.waitForSignal('measured');
    yield (this.motion || Resize).create(this.sprite, { duration: 500 }).run();
    yield* this.waitForSignal('unlock');
    this.sprite.unlock();
  }).restartable(),

  resetSignals() {
    this._signals = [];
  },

  receivedSignal(name) {
    if (!this._signals) { return; }
    this._signals.push(name);
    let s = this._signalWaiter;
    this._signalWaiter = null;
    if (s) {
      s();
    }
  },

  waitForSignal: function * (name) {
    while (this._signals.indexOf(name) < 0) {
      if (!this._signalWaiter) {
        yield new Promise(resolve => {
          this._signalWaiter = resolve;
        });
      } else {
        yield this._signalWaiter;
      }
    }
  },

  actions: {
    lock() {
      let sprite = new Sprite(this.element, this);
      this.sprite = sprite;
      this.resetSignals();
      sprite.measureInitialBounds();
      sprite.lockDimensions();
      this.get('animate').perform();
    },
    measure() {
      if (this.sprite) {
        this.sprite.unlock();
        this.sprite.measureFinalBounds();
        this.sprite.lockDimensions();
      }
      this.receivedSignal('measured');
    },
    unlock() {
      this.receivedSignal('unlock');
    }
  }
});
<commit_msg>bugfix animated-container signals<commit_after>import Ember from 'ember';
import layout from '../templates/components/animated-container';
import Resize from '../motions/resize';
import { task } from 'ember-concurrency';
import { Promise } from '../concurrency-helpers';
import Sprite from '../sprite';

export default Ember.Component.extend({
  layout,
  classNames: ['animated-container'],

  init() {
    this._super();
    this._signals = null;
    this._signalPromise = null;
    this._signalResolve= null;
  },

  animate: task(function * () {
    yield* this.waitForSignal('measured');
    yield (this.motion || Resize).create(this.sprite, { duration: 500 }).run();
    yield* this.waitForSignal('unlock');
    this.sprite.unlock();
  }).restartable(),

  resetSignals() {
    this._signals = [];
  },

  receivedSignal(name) {
    if (!this._signals) { return; }
    this._signals.push(name);
    let s = this._signalResolve;
    this._signalResolve = null;
    this._signalPromise = null;
    if (s) {
      s();
    }
  },

  waitForSignal: function * (name) {
    while (this._signals.indexOf(name) < 0) {
      if (!this._signalPromise) {
        this._signalPromise = new Promise(resolve => {
          this._signalResolve = resolve;
        });
      }
      yield this._signalPromise;
    }
  },

  actions: {
    lock() {
      let sprite = new Sprite(this.element, this);
      this.sprite = sprite;
      this.resetSignals();
      sprite.measureInitialBounds();
      sprite.lockDimensions();
      this.get('animate').perform();
    },
    measure() {
      if (this.sprite) {
        this.sprite.unlock();
        this.sprite.measureFinalBounds();
        this.sprite.lockDimensions();
      }
      this.receivedSignal('measured');
    },
    unlock() {
      this.receivedSignal('unlock');
    }
  }
});
<|endoftext|>


<commit_before>var SwipeTable = (function(){
    "use strict";

    // Define keys that your table will use,
    // in the order you want them to be displayed.
    // First item is leftmost, last item is rightmost
    //TODO: Fix above sentence
    var keys = [
        "id",
        "time",
        "time2",
        "location",
        "location2"
    ];

    var tableClass = 'table';
    var rowHeight = 39;
//    tableClass += ' table-bordered';
    tableClass += ' table-condensed'; rowHeight = 33;

    // RESTful provider URI
    // (relative or absolute)
    var dataProvider = "api";

    //---------------------------------------------
    //== No more configuration beyond this point ==
    //
    //=== Variables ===
    //Initialize other variables
    var doneTables = 0;
    var totalTables = 0;
    var pageSize = 1;
    var sortColumn;
    var sortAscending = true;

    //=== Functions ===

    var init = function(){
        // responsejs.com/labs/dimensions/
        var matchMedia = window.matchMedia || window.msMatchMedia;
        var viewportH = (function(win, docElem, mM) {
            var client = docElem['clientHeight']
                , inner = win['innerHeight'];
            return ( mM && client < inner && true === mM('(min-height:' + inner + 'px)')['matches']
                ? win['innerHeight']
                : docElem['clientHeight']
                );
        }(window, document.documentElement, matchMedia));

        // Remove one rowHeight for the header;
        viewportH -= rowHeight;
        pageSize = Math.floor(viewportH / rowHeight);
    }

    var makeRequest = function (queries){
        if(!queries.server){
            console.log("No server provided to makeRequest, not making request");
            return
        }
        console.log("Making request to "+ queries.server+ ".");
        var r = new XMLHttpRequest();
        if(queries.timestamp){
            if(queries.sortField || queries.sortAsc){
                if(!queries.sortField || !queries.sortAsc){
                    console.log("Missing sort parameter");
                    return
                }

                if(queries.page){
                    r.open("GET", queries.server + "?p=" + queries.page + "&ps=" + pageSize + "&ts=" + queries.timestamp + "sort[field]=" + queries.sortField + "&sort[asc]=" + queries.sortAsc, true);
                    r.onreadystatechange =  function(){
                        if(r.readyState !== 4 || r.status !== 200){
                            console.log("Request went sour");
                            return;
                        }
                        console.log("Request successful.");
                        parseResponse(queries.table, r.responseText);
                    };
                }
                else{
                    r.open("GET", queries.server + "?ps=" + pageSize + "&ts=" + queries.timestamp + "sort[field]=" + queries.sortField + "&sort[asc]=" + queries.sortAsc, true);
                    r.onreadystatechange =  function(){
                        if(r.readyState !== 4 || r.status !== 200){
                            console.log("Request went sour");
                            return;
                        }
                        console.log("Request successful.");
                        parseResponse(queries.table, r.responseText);
                    };
                }
            }
            else{
                if(!queries.page){
                    console.log("Missing page, not according to spec.");
                    return;
                }
                // No sorting, must be page request
                r.open("GET", queries.server + "?p=" + queries.page + "&ps=" + pageSize + "&ts=" + queries.timestamp, true);
                r.onreadystatechange =  function(){
                    if(r.readyState !== 4 || r.status !== 200){
                        console.log("Request went sour");
                        return;
                    }
                    console.log("Request successful.");
                    parseResponse(queries.table, r.responseText);
                };
            }
        }
        else{
            // No timestamp, fresh request
            r.open("GET", queries.server + "?&ps=" + pageSize, true);
            r.onreadystatechange =  function(){
                if(r.readyState !== 4 || r.status !== 200){
                    console.log("Request went sour");
                    return;
                }
                console.log("Request successful.");
                parseResponse(queries.table, r.responseText);
            };
        }
        r.send(null);
    };

    var parseResponse = function(table, response){
        console.log("Parsing response.");
        fillTable(table, JSON.parse(response));
    };

    var createTable = (function(){
        console.log("Creating Table.");
        var tableInstance;
        return function(){
            if(tableInstance){
                console.log("Giving table instance");
                totalTables += 1;
                var copy = tableInstance.cloneNode(true);
                return copy;
            }
            else{
                console.log("Creating new Table");
                var i = 0;
                var table = document.createElement("table");
                table.className = tableClass;
                var thead = document.createElement("thead");
                var tr = document.createElement("tr");

                for (i; i < keys.length; i+=1){
                    var th = document.createElement("th");
                    th.appendChild(document.createTextNode(keys[i]));
                    tr.appendChild(th);
                }

                thead.appendChild(tr);
                table.appendChild(thead);
                console.log("Table created.");
                tableInstance = table.cloneNode(true);
                totalTables += 1;
                return table;
            }
        };
    }());

    var fillTable = function(table, dataSet){
        console.log("Filling table.");

        var numRows = dataSet.length;
        if(numRows === 0){
            return;
        }

        var tbody = document.createElement("tbody");
        table.appendChild(tbody);

        var i = 0;
        while (i < numRows){
            var col = dataSet[i];
            var tr = document.createElement("tr");
            var colCells = Object.keys(col).length;

            var j = 0;
            while (j < colCells)
            {
                var td = document.createElement("td");
                td.appendChild(document.createTextNode(col[keys[j]]));
                tr.appendChild(td);
                j+=1;
            }

            tbody.appendChild(tr);
            i+=1;
        }
        var container = document.getElementsByClassName('swipe-table-container')[0];
        var tableContainer = document.createElement('div');
        var scrollableContainer = tableContainer.cloneNode(true);
        var pinnedContainer = tableContainer.cloneNode(true);
        tableContainer.className = 'swipe-table-table-container table-wrapper';
        scrollableContainer.className = 'scrollable';
        pinnedContainer.className = 'pinned';
        var cloned = table.cloneNode(true);
        table.className +=' responsive';
        scrollableContainer.appendChild(table);
        pinnedContainer.appendChild(cloned);
        tableContainer.appendChild(scrollableContainer);
        tableContainer.appendChild(pinnedContainer);
        if(window.mySwipe !== undefined){
            window.mySwipe.prepareForAddition(tableContainer);
        }
        container.appendChild(tableContainer);
        tableDone();
    };

    var tableDone = function(){
        doneTables += 1;
        if (doneTables === totalTables){
            if(window.mySwipe === undefined){
                window.mySwipe = Swipe(document.getElementById('slider'),{
                    continuous:false,
                    callback: function(currentIndex, element){
                        if (currentIndex === element.parentNode.childNodes.length - 1){
                            console.log("fetching next item");
                            SwipeTable.nextPage();
                        }
                    },
                    transitionEnd: function(currentIndex, element){
                        SwipeTable.updateHeader(element);
                    }
                });
                if(doneTables === 1){
                    nextPage();
                    updateHeader(document.getElementsByClassName('swipe-table-table-container')[0]);
                }
            }
            else {
                window.mySwipe.setup();
            }
        }
    };

    var nextPage = function(){
        var pos = window.mySwipe.getPos() + 1;

        var table = createTable();
        if(sortColumn === undefined){
            makeRequest({
                table: table ,
                server: dataProvider,
                page: pos + 1,
                timestamp: 10
            });
        }
        else{
            makeRequest({
                table: table,
                server: dataProvider,
                page: pos + 1,
                sortField: sortColumn,
                sortAsc: sortAscending
            });
        }
    };

    var updateHeader = function(element){
        var copy = element.cloneNode(true);
        var header = document.getElementsByClassName('swipe-table-header')[0];
        header.innerHTML = '';
        copy.removeAttribute('style');
        copy.removeAttribute('data-index');
        header.appendChild(copy);

        var scrollable = header.getElementsByClassName('scrollable')[0];
        if (scrollable){
            scrollable.onscroll = function(){
                console.log("Scrolling is happening!");
                SwipeTable.setPosition(this.scrollLeft);
                SwipeTable.updateScrollables();
            };

            var pos = SwipeTable.getPosition();
            if (pos !== undefined){
                scrollable.scrollLeft = pos;
                SwipeTable.updateScrollables();
            }
            else{
                SwipeTable.setPosition(0);
            }
        }
    };

    var updateScrollFunc = function(){
        var position;
        console.log("Entered updateScroll");

        var getPosition = function(){
            console.log("Getting position " + position);
            return position;
        };

        var setPosition = function(newPos){
            console.log("Setting position " + newPos);
            position = newPos;
        };

        var updateScrollables = function(){
            console.log("Updating scrollables");
            var targets = document.getElementsByClassName('swipe-table-container')[0].getElementsByClassName('scrollable');
            var i = 0;
            for(i;i<targets.length;i+=1){
                targets[i].scrollLeft = position;
            }
        };

        return {
            getPosition : getPosition,
            setPosition : setPosition,
            updateScrollables : updateScrollables
        }
    };

    //=== Logic ===
    init();
    var updateScroll = updateScrollFunc();

    var dataTable = createTable();
    console.log("dataProvider === " + dataProvider);
    makeRequest({
        table: dataTable,
        server: dataProvider
    });
    updateHeader(dataTable);

    var methods = {
        nextPage : nextPage,
        updateHeader : updateHeader,
        getPosition : updateScroll.getPosition,
        setPosition : updateScroll.setPosition,
        updateScrollables : updateScroll.updateScrollables
    };

    return methods;
}());<commit_msg>Restructure updateScroll()<commit_after>var SwipeTable = (function(){
    "use strict";

    // Define keys that your table will use,
    // in the order you want them to be displayed.
    // First item is leftmost, last item is rightmost
    //TODO: Fix above sentence
    var keys = [
        "id",
        "time",
        "time2",
        "location",
        "location2"
    ];

    var tableClass = 'table';
    var rowHeight = 39;
//    tableClass += ' table-bordered';
    tableClass += ' table-condensed'; rowHeight = 33;

    // RESTful provider URI
    // (relative or absolute)
    var dataProvider = "api";

    //---------------------------------------------
    //== No more configuration beyond this point ==
    //
    //=== Variables ===
    //Initialize other variables
    var doneTables = 0;
    var totalTables = 0;
    var pageSize = 1;
    var sortColumn;
    var sortAscending = true;

    //=== Functions ===

    var init = function(){
        // responsejs.com/labs/dimensions/
        var matchMedia = window.matchMedia || window.msMatchMedia;
        var viewportH = (function(win, docElem, mM) {
            var client = docElem['clientHeight']
                , inner = win['innerHeight'];
            return ( mM && client < inner && true === mM('(min-height:' + inner + 'px)')['matches']
                ? win['innerHeight']
                : docElem['clientHeight']
                );
        }(window, document.documentElement, matchMedia));

        // Remove one rowHeight for the header;
        viewportH -= rowHeight;
        pageSize = Math.floor(viewportH / rowHeight);
    }

    var makeRequest = function (queries){
        if(!queries.server){
            console.log("No server provided to makeRequest, not making request");
            return
        }
        console.log("Making request to "+ queries.server+ ".");
        var r = new XMLHttpRequest();
        if(queries.timestamp){
            if(queries.sortField || queries.sortAsc){
                if(!queries.sortField || !queries.sortAsc){
                    console.log("Missing sort parameter");
                    return
                }

                if(queries.page){
                    r.open("GET", queries.server + "?p=" + queries.page + "&ps=" + pageSize + "&ts=" + queries.timestamp + "sort[field]=" + queries.sortField + "&sort[asc]=" + queries.sortAsc, true);
                    r.onreadystatechange =  function(){
                        if(r.readyState !== 4 || r.status !== 200){
                            console.log("Request went sour");
                            return;
                        }
                        console.log("Request successful.");
                        parseResponse(queries.table, r.responseText);
                    };
                }
                else{
                    r.open("GET", queries.server + "?ps=" + pageSize + "&ts=" + queries.timestamp + "sort[field]=" + queries.sortField + "&sort[asc]=" + queries.sortAsc, true);
                    r.onreadystatechange =  function(){
                        if(r.readyState !== 4 || r.status !== 200){
                            console.log("Request went sour");
                            return;
                        }
                        console.log("Request successful.");
                        parseResponse(queries.table, r.responseText);
                    };
                }
            }
            else{
                if(!queries.page){
                    console.log("Missing page, not according to spec.");
                    return;
                }
                // No sorting, must be page request
                r.open("GET", queries.server + "?p=" + queries.page + "&ps=" + pageSize + "&ts=" + queries.timestamp, true);
                r.onreadystatechange =  function(){
                    if(r.readyState !== 4 || r.status !== 200){
                        console.log("Request went sour");
                        return;
                    }
                    console.log("Request successful.");
                    parseResponse(queries.table, r.responseText);
                };
            }
        }
        else{
            // No timestamp, fresh request
            r.open("GET", queries.server + "?&ps=" + pageSize, true);
            r.onreadystatechange =  function(){
                if(r.readyState !== 4 || r.status !== 200){
                    console.log("Request went sour");
                    return;
                }
                console.log("Request successful.");
                parseResponse(queries.table, r.responseText);
            };
        }
        r.send(null);
    };

    var parseResponse = function(table, response){
        console.log("Parsing response.");
        fillTable(table, JSON.parse(response));
    };

    var createTable = (function(){
        console.log("Creating Table.");
        var tableInstance;
        return function(){
            if(tableInstance){
                console.log("Giving table instance");
                totalTables += 1;
                var copy = tableInstance.cloneNode(true);
                return copy;
            }
            else{
                console.log("Creating new Table");
                var i = 0;
                var table = document.createElement("table");
                table.className = tableClass;
                var thead = document.createElement("thead");
                var tr = document.createElement("tr");

                for (i; i < keys.length; i+=1){
                    var th = document.createElement("th");
                    th.appendChild(document.createTextNode(keys[i]));
                    tr.appendChild(th);
                }

                thead.appendChild(tr);
                table.appendChild(thead);
                console.log("Table created.");
                tableInstance = table.cloneNode(true);
                totalTables += 1;
                return table;
            }
        };
    }());

    var fillTable = function(table, dataSet){
        console.log("Filling table.");

        var numRows = dataSet.length;
        if(numRows === 0){
            return;
        }

        var tbody = document.createElement("tbody");
        table.appendChild(tbody);

        var i = 0;
        while (i < numRows){
            var col = dataSet[i];
            var tr = document.createElement("tr");
            var colCells = Object.keys(col).length;

            var j = 0;
            while (j < colCells)
            {
                var td = document.createElement("td");
                td.appendChild(document.createTextNode(col[keys[j]]));
                tr.appendChild(td);
                j+=1;
            }

            tbody.appendChild(tr);
            i+=1;
        }
        var container = document.getElementsByClassName('swipe-table-container')[0];
        var tableContainer = document.createElement('div');
        var scrollableContainer = tableContainer.cloneNode(true);
        var pinnedContainer = tableContainer.cloneNode(true);
        tableContainer.className = 'swipe-table-table-container table-wrapper';
        scrollableContainer.className = 'scrollable';
        pinnedContainer.className = 'pinned';
        var cloned = table.cloneNode(true);
        table.className +=' responsive';
        scrollableContainer.appendChild(table);
        pinnedContainer.appendChild(cloned);
        tableContainer.appendChild(scrollableContainer);
        tableContainer.appendChild(pinnedContainer);
        if(window.mySwipe !== undefined){
            window.mySwipe.prepareForAddition(tableContainer);
        }
        container.appendChild(tableContainer);
        tableDone();
    };

    var tableDone = function(){
        doneTables += 1;
        if (doneTables === totalTables){
            if(window.mySwipe === undefined){
                window.mySwipe = Swipe(document.getElementById('slider'),{
                    continuous:false,
                    callback: function(currentIndex, element){
                        if (currentIndex === element.parentNode.childNodes.length - 1){
                            console.log("fetching next item");
                            SwipeTable.nextPage();
                        }
                    },
                    transitionEnd: function(currentIndex, element){
                        SwipeTable.updateHeader(element);
                    }
                });
                if(doneTables === 1){
                    nextPage();
                    updateHeader(document.getElementsByClassName('swipe-table-table-container')[0]);
                }
            }
            else {
                window.mySwipe.setup();
            }
        }
    };

    var nextPage = function(){
        var pos = window.mySwipe.getPos() + 1;

        var table = createTable();
        if(sortColumn === undefined){
            makeRequest({
                table: table ,
                server: dataProvider,
                page: pos + 1,
                timestamp: 10
            });
        }
        else{
            makeRequest({
                table: table,
                server: dataProvider,
                page: pos + 1,
                sortField: sortColumn,
                sortAsc: sortAscending
            });
        }
    };

    var updateHeader = function(element){
        var copy = element.cloneNode(true);
        var header = document.getElementsByClassName('swipe-table-header')[0];
        header.innerHTML = '';
        copy.removeAttribute('style');
        copy.removeAttribute('data-index');
        header.appendChild(copy);

        var scrollable = header.getElementsByClassName('scrollable')[0];
        if (scrollable){
            scrollable.onscroll = function(){
                console.log("Scrolling is happening!");
                SwipeTable.setPosition(this.scrollLeft);
                SwipeTable.updateScrollables();
            };

            var pos = SwipeTable.getPosition();
            if (pos !== undefined){
                scrollable.scrollLeft = pos;
                SwipeTable.updateScrollables();
            }
            else{
                SwipeTable.setPosition(0);
            }
        }
    };

    var updateScroll = (function(){
        var position;
        console.log("Entered updateScroll");

        return {
            getPosition : function(){
                console.log("Getting position " + position);
                return position;
            },
            setPosition : function(newPos){
                console.log("Setting position " + newPos);
                position = newPos;
            },
            updateScrollables : function(){
                console.log("Updating scrollables");
                var targets = document.getElementsByClassName('swipe-table-container')[0].getElementsByClassName('scrollable');
                var i = 0;
                for(i;i<targets.length;i+=1){
                    targets[i].scrollLeft = position;
                }
            }
        }
    }());

    //=== Logic ===
    init();

    var dataTable = createTable();
    console.log("dataProvider === " + dataProvider);
    makeRequest({
        table: dataTable,
        server: dataProvider
    });
    updateHeader(dataTable);

    var methods = {
        nextPage : nextPage,
        updateHeader : updateHeader,
        getPosition : updateScroll.getPosition,
        setPosition : updateScroll.setPosition,
        updateScrollables : updateScroll.updateScrollables
    };

    return methods;
}());<|endoftext|>


<commit_before>$(function() {

  var $searchForm = $('form.search.public');

  if ($searchForm.length) {
    $searchInput = $searchForm.find('input.search_user');
    $searchInput.on('autocompleteselect', function(e, ui) {
      setTimeout(function() {
        $searchForm.submit();
      }, 10);
    });
    $searchForm.submit(function() {
      location.href = $searchForm.attr('action') + $searchInput.val();
      return false;
    });
  }

  $("div.user_show .mod_zone_toggle").each(function() {
    $(this).click(function() {
      var $zone = $("div.user_show .mod_zone");
      if ($zone.is(':visible')) $zone.hide();
      else $zone.html("Loading...").show();
      $zone.load($(this).attr("href"), function() {
        $zone.find('form.fide_title select').on('change', function() {
          $(this).parent('form').submit();
        });
        $('body').trigger('lichess.content_loaded');
        var relatedUsers = +$('.reportCard thead th:last').text();
        if (relatedUsers > 100) {
          $zone.find('.others').css('display', 'none').before('Show ' + relatedUsers + ' related users');
          $zone.find('.others-show').click(function() {
            $(this).next().css('display', '');
            $(this).remove();
          });
        }
        $zone.find('li.ip').slice(0, 3).each(function() {
          var $li = $(this);
          $.ajax({
            url: '/mod/ip-intel?ip=' + $(this).find('.address').text(),
            success: function(res) {
              var p = Math.round(parseFloat(res) * 100);
              $li.append($('' + p + '% proxy'));
            }
          });
        });
      });
      return false;
    });
    if (location.search.indexOf('mod') === 1) $(this).click();
  });

  $("div.user_show .note_zone_toggle").each(function() {
    $(this).click(function() {
      $("div.user_show .note_zone").toggle();
    });
    if (location.search.indexOf('note') != -1) $(this).click();
  });

  $('.buttonset').buttonset().disableSelection();

  $('form.autosubmit').each(function() {
    var $form = $(this);
    $form.find('input').change(function() {
      $.ajax({
        url: $form.attr('action'),
        method: $form.attr('method'),
        data: $form.serialize(),
        success: function() {
          $form.find('.saved').fadeIn();
        }
      });
    });
  });

  $("div.user_show .claim_title_zone").each(function() {
    var $zone = $(this);
    $zone.find('.actions a').click(function() {
      $.post($(this).attr('href'));
      $zone.remove();
      return false;
    });
  });

  if ($('div.user_show.myself').length &&
    $('div.sub_ratings .relevant').length &&
    lichess.once('user-perf-stats-tour')) lichess.hopscotch(function() {
    hopscotch.configure({
      i18n: {
        doneBtn: 'OK, got it'
      }
    }).startTour({
      id: 'perf-stats',
      showPrevButton: true,
      steps: [{
        title: "New: performance stats",
        content: "You can now click your ratings to display stats about your play!",
        target: $('div.sub_ratings .relevant')[0],
        placement: "right",
        xOffset: -40
      }]
    });
  });
  else if ($('#perfStat.correspondence .view_games').length &&
    lichess.once('user-correspondence-view-games')) lichess.hopscotch(function() {
    hopscotch.configure({
      i18n: {
        doneBtn: 'OK, got it'
      }
    }).startTour({
      id: 'correspondence-games',
      showPrevButton: true,
      steps: [{
        title: "Recently finished games",
        content: "Would you like to display the list of your correspondence games, sorted by completion date?",
        target: $('#perfStat.correspondence .view_games')[0],
        placement: "bottom"
      }]
    });
  });
});
<commit_msg>Use loading spinner for the mod zone<commit_after>$(function() {

  var $searchForm = $('form.search.public');
  var loadingSpinner = '
<svg viewBox="0 0 40 40"><circle cx="20" cy="20" r="18" fill="none"></circle></svg>
';

  if ($searchForm.length) {
    $searchInput = $searchForm.find('input.search_user');
    $searchInput.on('autocompleteselect', function(e, ui) {
      setTimeout(function() {
        $searchForm.submit();
      }, 10);
    });
    $searchForm.submit(function() {
      location.href = $searchForm.attr('action') + $searchInput.val();
      return false;
    });
  }

  $("div.user_show .mod_zone_toggle").each(function() {
    $(this).click(function() {
      var $zone = $("div.user_show .mod_zone");
      if ($zone.is(':visible')) $zone.hide();
      else $zone.html(loadingSpinner).show();
      $zone.load($(this).attr("href"), function() {
        $zone.find('form.fide_title select').on('change', function() {
          $(this).parent('form').submit();
        });
        $('body').trigger('lichess.content_loaded');
        var relatedUsers = +$('.reportCard thead th:last').text();
        if (relatedUsers > 100) {
          $zone.find('.others').css('display', 'none').before('Show ' + relatedUsers + ' related users');
          $zone.find('.others-show').click(function() {
            $(this).next().css('display', '');
            $(this).remove();
          });
        }
        $zone.find('li.ip').slice(0, 3).each(function() {
          var $li = $(this);
          $.ajax({
            url: '/mod/ip-intel?ip=' + $(this).find('.address').text(),
            success: function(res) {
              var p = Math.round(parseFloat(res) * 100);
              $li.append($('' + p + '% proxy'));
            }
          });
        });
      });
      return false;
    });
    if (location.search.indexOf('mod') === 1) $(this).click();
  });

  $("div.user_show .note_zone_toggle").each(function() {
    $(this).click(function() {
      $("div.user_show .note_zone").toggle();
    });
    if (location.search.indexOf('note') != -1) $(this).click();
  });

  $('.buttonset').buttonset().disableSelection();

  $('form.autosubmit').each(function() {
    var $form = $(this);
    $form.find('input').change(function() {
      $.ajax({
        url: $form.attr('action'),
        method: $form.attr('method'),
        data: $form.serialize(),
        success: function() {
          $form.find('.saved').fadeIn();
        }
      });
    });
  });

  $("div.user_show .claim_title_zone").each(function() {
    var $zone = $(this);
    $zone.find('.actions a').click(function() {
      $.post($(this).attr('href'));
      $zone.remove();
      return false;
    });
  });

  if ($('div.user_show.myself').length &&
    $('div.sub_ratings .relevant').length &&
    lichess.once('user-perf-stats-tour')) lichess.hopscotch(function() {
    hopscotch.configure({
      i18n: {
        doneBtn: 'OK, got it'
      }
    }).startTour({
      id: 'perf-stats',
      showPrevButton: true,
      steps: [{
        title: "New: performance stats",
        content: "You can now click your ratings to display stats about your play!",
        target: $('div.sub_ratings .relevant')[0],
        placement: "right",
        xOffset: -40
      }]
    });
  });
  else if ($('#perfStat.correspondence .view_games').length &&
    lichess.once('user-correspondence-view-games')) lichess.hopscotch(function() {
    hopscotch.configure({
      i18n: {
        doneBtn: 'OK, got it'
      }
    }).startTour({
      id: 'correspondence-games',
      showPrevButton: true,
      steps: [{
        title: "Recently finished games",
        content: "Would you like to display the list of your correspondence games, sorted by completion date?",
        target: $('#perfStat.correspondence .view_games')[0],
        placement: "bottom"
      }]
    });
  });
});
<|endoftext|>


<commit_before>import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { toastr } from 'react-redux-toastr';

// Constants
import { EXPLORE_SECTIONS } from 'layout/explore/constants';
import { TOPICS } from 'layout/explore/explore-topics/constants';

// Services
import { fetchRWConfig } from 'services/config';
import { fetchDatasets } from 'services/dataset';

// Components
import TopicsList from 'layout/explore/explore-topics/list';
import Spinner from 'components/ui/Spinner';

// Responsive
import MediaQuery from 'react-responsive';
import { breakpoints } from 'utils/responsive';

// Explore components
import DatasetList from 'layout/explore/explore-datasets/list';
import ExploreDatasetsActions from 'layout/explore/explore-datasets/explore-datasets-actions';

// Styles
import './styles.scss';

function ExploreDiscover(props) {
  const { setSidebarSection, responsive } = props;
  const [config, setConfig] = useState({ relatedTopics: [] });
  const [highlightedDatasets, setHighlightedDatasets] = useState({ loading: true, list: [] });
  const [recentUpdatedDatasets, setRecentUpdatedDatasets] = useState({ loading: true, list: [] });
  const [recentlyAddedDatasets, setRecentlyAddedDatasets] = useState({ loading: true, list: [] });

  useEffect(() => {
    const tempConfig = fetchRWConfig();
    setConfig(tempConfig);

    // ---- Highlighted datasets ----
    fetchDatasets({
      'page[size]': 4,
      isHighlighted: true,
      includes: 'layer,metadata,widget'
    })
      .then(data => setHighlightedDatasets({ loading: false, list: data }))
      .catch(err => toastr.error('Error loading highlighted datasets', err));

    // ----- Recently updated datasets -------
    fetchDatasets({
      'page[size]': 4,
      sort: '-dataLastUpdated',
      includes: 'layer,metadata,widget',
      'concepts[0][0]': 'near_real_time'
    })
      .then(data => setRecentUpdatedDatasets({ loading: false, list: data }))
      .catch(err => toastr.error('Error loading recently updated datasets', err));

    // ----- Recently added datasets --------
    fetchDatasets({
      'page[size]': 4,
      sort: '-createdAt',
      includes: 'layer,metadata,widget'
    })
      .then(data => setRecentlyAddedDatasets({ loading: false, list: data }))
      .catch(err => toastr.error('Error loading recently added datasets', err));
  }, []);

  const {
    relatedTopics
  } = config;

  return (

Trending datasets

 setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
            onKeyPress={() => setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
          >
                        SEE ALL DATA

        <Spinner isLoading={highlightedDatasets.loading} className="-light -relative" />
        {!highlightedDatasets.loading &&
          <DatasetList
            list={highlightedDatasets.list}
            actions={
              <MediaQuery
                minDeviceWidth={breakpoints.medium}
                values={{ deviceWidth: responsive.fakeWidth }}
              >
                <ExploreDatasetsActions />
              </MediaQuery>
            }
          />
        }

Related topics

 setSidebarSection(EXPLORE_SECTIONS.TOPICS)}
            onKeyPress={() => setSidebarSection(EXPLORE_SECTIONS.TOPICS)}
          >
                        SEE ALL

        {relatedTopics.length > 0 &&
          <TopicsList
            topics={TOPICS.filter(t => relatedTopics.find(rT => rT === t.id))}
            onClick={(id) => {
              props.setFiltersSearch('');
              props.resetFiltersSort();
              props.setFiltersSelected({ key: 'topics', list: [id] });
              props.setDatasetsPage(1);
              props.fetchDatasets();
              props.setSidebarSection(EXPLORE_SECTIONS.ALL_DATA);
            }}
          />
        }

Recently added datasets

 setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
            onKeyPress={() => setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
          >
                        SEE ALL DATA

        <Spinner isLoading={recentlyAddedDatasets.loading} className="-light -relative" />
        {!recentlyAddedDatasets.loading &&
          <DatasetList
            list={recentlyAddedDatasets.list}
            actions={
              <MediaQuery
                minDeviceWidth={breakpoints.medium}
                values={{ deviceWidth: responsive.fakeWidth }}
              >
                <ExploreDatasetsActions />
              </MediaQuery>
            }
          />
        }

Recent updated datasets

 setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
            onKeyPress={() => setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
          >
                        SEE ALL DATA

        <Spinner isLoading={recentUpdatedDatasets.loading} className="-light -relative" />
        {!recentUpdatedDatasets.loading &&
          <DatasetList
            list={recentUpdatedDatasets.list}
            actions={
              <MediaQuery
                minDeviceWidth={breakpoints.medium}
                values={{ deviceWidth: responsive.fakeWidth }}
              >
                <ExploreDatasetsActions />
              </MediaQuery>
            }
          />
        }

  );
}

ExploreDiscover.propTypes = {
  setSidebarSection: PropTypes.func.isRequired,
  setFiltersSearch: PropTypes.func.isRequired,
  resetFiltersSort: PropTypes.func.isRequired,
  setDatasetsPage: PropTypes.func.isRequired,
  fetchDatasets: PropTypes.func.isRequired,
  setFiltersSelected: PropTypes.func.isRequired,
  responsive: PropTypes.object.isRequired
};

export default ExploreDiscover;
<commit_msg>minor fix for section link<commit_after>import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { toastr } from 'react-redux-toastr';

// Constants
import { EXPLORE_SECTIONS } from 'layout/explore/constants';
import { TOPICS } from 'layout/explore/explore-topics/constants';

// Services
import { fetchRWConfig } from 'services/config';
import { fetchDatasets } from 'services/dataset';

// Components
import TopicsList from 'layout/explore/explore-topics/list';
import Spinner from 'components/ui/Spinner';

// Responsive
import MediaQuery from 'react-responsive';
import { breakpoints } from 'utils/responsive';

// Explore components
import DatasetList from 'layout/explore/explore-datasets/list';
import ExploreDatasetsActions from 'layout/explore/explore-datasets/explore-datasets-actions';

// Styles
import './styles.scss';

function ExploreDiscover(props) {
  const { setSidebarSection, responsive } = props;
  const [config, setConfig] = useState({ relatedTopics: [] });
  const [highlightedDatasets, setHighlightedDatasets] = useState({ loading: true, list: [] });
  const [recentUpdatedDatasets, setRecentUpdatedDatasets] = useState({ loading: true, list: [] });
  const [recentlyAddedDatasets, setRecentlyAddedDatasets] = useState({ loading: true, list: [] });

  useEffect(() => {
    const tempConfig = fetchRWConfig();
    setConfig(tempConfig);

    // ---- Highlighted datasets ----
    fetchDatasets({
      'page[size]': 4,
      isHighlighted: true,
      includes: 'layer,metadata,widget'
    })
      .then(data => setHighlightedDatasets({ loading: false, list: data }))
      .catch(err => toastr.error('Error loading highlighted datasets', err));

    // ----- Recently updated datasets -------
    fetchDatasets({
      'page[size]': 4,
      sort: '-dataLastUpdated',
      includes: 'layer,metadata,widget',
      'concepts[0][0]': 'near_real_time'
    })
      .then(data => setRecentUpdatedDatasets({ loading: false, list: data }))
      .catch(err => toastr.error('Error loading recently updated datasets', err));

    // ----- Recently added datasets --------
    fetchDatasets({
      'page[size]': 4,
      sort: '-createdAt',
      includes: 'layer,metadata,widget'
    })
      .then(data => setRecentlyAddedDatasets({ loading: false, list: data }))
      .catch(err => toastr.error('Error loading recently added datasets', err));
  }, []);

  const {
    relatedTopics
  } = config;

  return (

Trending datasets

 setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
            onKeyPress={() => setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
          >
                        SEE ALL DATA

        <Spinner isLoading={highlightedDatasets.loading} className="-light -relative" />
        {!highlightedDatasets.loading &&
          <DatasetList
            list={highlightedDatasets.list}
            actions={
              <MediaQuery
                minDeviceWidth={breakpoints.medium}
                values={{ deviceWidth: responsive.fakeWidth }}
              >
                <ExploreDatasetsActions />
              </MediaQuery>
            }
          />
        }

Related topics

 setSidebarSection(EXPLORE_SECTIONS.TOPICS)}
            onKeyPress={() => setSidebarSection(EXPLORE_SECTIONS.TOPICS)}
          >
                        SEE ALL

        {relatedTopics.length > 0 &&
          <TopicsList
            topics={TOPICS.filter(t => relatedTopics.find(rT => rT === t.id))}
            onClick={(id) => {
              props.setFiltersSearch('');
              props.resetFiltersSort();
              props.setFiltersSelected({ key: 'topics', list: [id] });
              props.setDatasetsPage(1);
              props.fetchDatasets();
              props.setSidebarSection(EXPLORE_SECTIONS.ALL_DATA);
            }}
          />
        }

Recently added datasets

 setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
            onKeyPress={() => setSidebarSection(EXPLORE_SECTIONS.ALL_DATA)}
          >
                        SEE ALL DATA

        <Spinner isLoading={recentlyAddedDatasets.loading} className="-light -relative" />
        {!recentlyAddedDatasets.loading &&
          <DatasetList
            list={recentlyAddedDatasets.list}
            actions={
              <MediaQuery
                minDeviceWidth={breakpoints.medium}
                values={{ deviceWidth: responsive.fakeWidth }}
              >
                <ExploreDatasetsActions />
              </MediaQuery>
            }
          />
        }

Recent updated datasets

 setSidebarSection(EXPLORE_SECTIONS.NEAR_REAL_TIME)}
            onKeyPress={() => setSidebarSection(EXPLORE_SECTIONS.NEAR_REAL_TIME)}
          >
                        SEE ALL DATA

        <Spinner isLoading={recentUpdatedDatasets.loading} className="-light -relative" />
        {!recentUpdatedDatasets.loading &&
          <DatasetList
            list={recentUpdatedDatasets.list}
            actions={
              <MediaQuery
                minDeviceWidth={breakpoints.medium}
                values={{ deviceWidth: responsive.fakeWidth }}
              >
                <ExploreDatasetsActions />
              </MediaQuery>
            }
          />
        }

  );
}

ExploreDiscover.propTypes = {
  setSidebarSection: PropTypes.func.isRequired,
  setFiltersSearch: PropTypes.func.isRequired,
  resetFiltersSort: PropTypes.func.isRequired,
  setDatasetsPage: PropTypes.func.isRequired,
  fetchDatasets: PropTypes.func.isRequired,
  setFiltersSelected: PropTypes.func.isRequired,
  responsive: PropTypes.object.isRequired
};

export default ExploreDiscover;
<|endoftext|>