<commit_before>// WDIO config file used to build/test my Github project
//
// This grunt configuration can be run locally or from Travis CL

// To Run:
//  $ grunt webdriver or wdio wdio.conf-gruntfile.js

exports.config = {

    host: (process.env.BUILD_NUMBER) ? 'localhost':'ondemand.saucelabs.com',
    port: (process.env.BUILD_NUMBER) ? 4445:80,
    //
    // =================
    // Service Providers
    // =================
    // WebdriverIO supports Sauce Labs, Browserstack and Testing Bot (other cloud providers
    // should work too though). These services define specific user and key (or access key)
    // values you need to put in here in order to connect to these services.
    //
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,

    //
    // If you are using Sauce Labs WebdriverIO takes care about updating the job information
    // once the test is done. This option is set to `true` per default.
    //
    updateJob: true,

    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the location of this
    // file.
    //
    specs: [
        'tutorial1.js',
        'copyright1.js',
        'cssValidation1.js',
        'dataLoopExample2.js',
        'formFillSubmit1.js',
        //'formFieldValidation.js',
        'linkTextURL1.js',
        'linkTextURL2.js',
        'carouselExample1.js',
        'showHideVerify1.js'
    ],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilties at the same
    // time. Depending on the number of capabilities WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude option in
    // order to group specific specs to a specific capability.
    //
    // If you have trouble getting all important capabilities together check out Sauce Labs
    // platform configurator. A great tool to configure your capabilities.
    // https://docs.saucelabs.com/reference/platforms-configurator
    //
    capabilities: [{
        browserName: 'chrome',
            version: '42.0',
            platform: 'Windows 8',
            name: 'Example using wdio + saucelabs - Chrome V42.0 on Win8'
        },
        {
         browserName: 'internet explorer',
            version: '10.0',
            platform: 'Windows 7',
            name: 'Example using wdio + saucelabs - IE V10.0 on Win7'
        },
        {
            browserName: 'safari',
            version: '8.0',
            platform: 'OS X 10.10',
            name: 'Example using wdio + saucelabs - Safari V8.0 on OSX10.10'
        }
    ],
    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // Level of logging verbosity.
    logLevel: 'silent',
    //
    // Enables colors for log output
    coloredLogs: true,
    //
    // Saves a screenshot to a given path if a command fails.
    screenshotPath: './errorShots/',
    //
    // Shorten url command calls by setting a base url. If your url parameter starts with "/"
    // the base url gets prepended.
    baseUrl: 'http://localhost',
    //
    // Default timeout for all waitForXXX commands.
    waitforTimeout: 10000,
    //
    // Initialise the browser instance with a WebdriverIO plugin. The object should have the
    // plugin name as key and the desired plugin options as property. Make sure you have
    // the plugin installed before running any tests. The following plugins are currently
    // available:
    // WebdriverCSS: https://github.com/webdriverio/webdrivercss
    // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
    // Browserevent: https://github.com/webdriverio/browserevent
    // plugins: {
    //     webdrivercss: {
    //         screenshotRoot: 'my-shots',
    //         failedComparisonsRoot: 'diffs',
    //         misMatchTolerance: 0.05,
    //         screenWidth: [320,480,640,1024]
    //     },
    //     webdriverrtc: {},
    //     browserevent: {}
    // },
    //
    // Framework you want to run your specs with.
    // The following are supported: mocha, jasmine and cucumber
    // see also: http://webdriver.io/guide/testrunner/frameworks.html
    //
    // Make sure you have the node package for the specific framework installed before running
    // any tests. If not please install the following package:
    // Mocha: `$ npm install mocha`
    // Jasmine: `$ npm install jasmine`
    // Cucumber: `$ npm install cucumber`
    framework: 'mocha',
    //
    // Test reporter for stdout.
    // The following are supported: dot (default), spec and xunit
    // see also: http://webdriver.io/guide/testrunner/reporters.html
    reporter: 'dot',

    //
    // =====
    // Hooks
    // =====
    // Run functions before or after the test. If one of them return with a promise, WebdriverIO
    // will wait until that promise got resolved to continue.
    // see also: http://webdriver.io/guide/testrunner/hooks.html
    //
    // Gets executed before all workers get launched.
    onPrepare: function() {
        // do something
    },
    //
    // Gets executed before test execution begins. At this point you will have access to all global
    // variables like `browser`. It is the perfect place to define custom commands.
    before: function() {
        // do something
    },
    //
    // Gets executed after all tests are done. You still have access to all global variables from
    // the test.
    after: function() {
        // do something
    },
    //
    // Gets executed after all workers got shut down and the process is about to exit. It is not
    // possible to defer the end of the process using a promise.
    onComplete: function() {
        // do something
    }
};<commit_msg>Testing formFieldValidation fix<commit_after>// WDIO config file used to build/test my Github project
//
// This grunt configuration can be run locally or from Travis CL

// To Run:
//  $ grunt webdriver or wdio wdio.conf-gruntfile.js

exports.config = {

    host: (process.env.BUILD_NUMBER) ? 'localhost':'ondemand.saucelabs.com',
    port: (process.env.BUILD_NUMBER) ? 4445:80,
    //
    // =================
    // Service Providers
    // =================
    // WebdriverIO supports Sauce Labs, Browserstack and Testing Bot (other cloud providers
    // should work too though). These services define specific user and key (or access key)
    // values you need to put in here in order to connect to these services.
    //
    user: process.env.SAUCE_USERNAME,
    key: process.env.SAUCE_ACCESS_KEY,

    //
    // If you are using Sauce Labs WebdriverIO takes care about updating the job information
    // once the test is done. This option is set to `true` per default.
    //
    updateJob: true,

    //
    // ==================
    // Specify Test Files
    // ==================
    // Define which test specs should run. The pattern is relative to the location of this
    // file.
    //
    specs: [
        'tutorial1.js',
        'copyright1.js',
        'cssValidation1.js',
        'dataLoopExample2.js',
        'formFillSubmit1.js',
        'formFieldValidation.js',
        'linkTextURL1.js',
        'linkTextURL2.js',
        'carouselExample1.js',
        'showHideVerify1.js'
    ],
    // Patterns to exclude.
    exclude: [
        // 'path/to/excluded/files'
    ],
    //
    // ============
    // Capabilities
    // ============
    // Define your capabilities here. WebdriverIO can run multiple capabilties at the same
    // time. Depending on the number of capabilities WebdriverIO launches several test
    // sessions. Within your capabilities you can overwrite the spec and exclude option in
    // order to group specific specs to a specific capability.
    //
    // If you have trouble getting all important capabilities together check out Sauce Labs
    // platform configurator. A great tool to configure your capabilities.
    // https://docs.saucelabs.com/reference/platforms-configurator
    //
    capabilities: [{
        browserName: 'chrome',
            version: '42.0',
            platform: 'Windows 8',
            name: 'Example using wdio + saucelabs - Chrome V42.0 on Win8'
        },
        {
         browserName: 'internet explorer',
            version: '10.0',
            platform: 'Windows 7',
            name: 'Example using wdio + saucelabs - IE V10.0 on Win7'
        },
        {
            browserName: 'safari',
            version: '8.0',
            platform: 'OS X 10.10',
            name: 'Example using wdio + saucelabs - Safari V8.0 on OSX10.10'
        }
    ],
    //
    // ===================
    // Test Configurations
    // ===================
    // Define all options that are relevant for the WebdriverIO instance here
    //
    // Level of logging verbosity.
    logLevel: 'silent',
    //
    // Enables colors for log output
    coloredLogs: true,
    //
    // Saves a screenshot to a given path if a command fails.
    screenshotPath: './errorShots/',
    //
    // Shorten url command calls by setting a base url. If your url parameter starts with "/"
    // the base url gets prepended.
    baseUrl: 'http://localhost',
    //
    // Default timeout for all waitForXXX commands.
    waitforTimeout: 10000,
    //
    // Initialise the browser instance with a WebdriverIO plugin. The object should have the
    // plugin name as key and the desired plugin options as property. Make sure you have
    // the plugin installed before running any tests. The following plugins are currently
    // available:
    // WebdriverCSS: https://github.com/webdriverio/webdrivercss
    // WebdriverRTC: https://github.com/webdriverio/webdriverrtc
    // Browserevent: https://github.com/webdriverio/browserevent
    // plugins: {
    //     webdrivercss: {
    //         screenshotRoot: 'my-shots',
    //         failedComparisonsRoot: 'diffs',
    //         misMatchTolerance: 0.05,
    //         screenWidth: [320,480,640,1024]
    //     },
    //     webdriverrtc: {},
    //     browserevent: {}
    // },
    //
    // Framework you want to run your specs with.
    // The following are supported: mocha, jasmine and cucumber
    // see also: http://webdriver.io/guide/testrunner/frameworks.html
    //
    // Make sure you have the node package for the specific framework installed before running
    // any tests. If not please install the following package:
    // Mocha: `$ npm install mocha`
    // Jasmine: `$ npm install jasmine`
    // Cucumber: `$ npm install cucumber`
    framework: 'mocha',
    //
    // Test reporter for stdout.
    // The following are supported: dot (default), spec and xunit
    // see also: http://webdriver.io/guide/testrunner/reporters.html
    reporter: 'dot',

    //
    // =====
    // Hooks
    // =====
    // Run functions before or after the test. If one of them return with a promise, WebdriverIO
    // will wait until that promise got resolved to continue.
    // see also: http://webdriver.io/guide/testrunner/hooks.html
    //
    // Gets executed before all workers get launched.
    onPrepare: function() {
        // do something
    },
    //
    // Gets executed before test execution begins. At this point you will have access to all global
    // variables like `browser`. It is the perfect place to define custom commands.
    before: function() {
        // do something
    },
    //
    // Gets executed after all tests are done. You still have access to all global variables from
    // the test.
    after: function() {
        // do something
    },
    //
    // Gets executed after all workers got shut down and the process is about to exit. It is not
    // possible to defer the end of the process using a promise.
    onComplete: function() {
        // do something
    }
};<|endoftext|>


<commit_before>$(function() {

    $("input,textarea").jqBootstrapValidation({
        preventSubmit: true,
        submitError: function($form, event, errors) {
        },
        submitSuccess: function($form, event) {
            var firstHackathon;
            $("#Field6").is(':checked') ? firstHackathon = true : firstHackathon = false;

            $.ajax({
                url:    "./scripts/register.php",
                type:   "POST",
                data:   {
                    firstName:  $('#Field1').val(),
                    lastName:  $('#Field2').val(),
                    email:  $('#Field3').val(),
                    school:  $('#Field4').val(),
                    resume: $('#Field5').val(),
                    first: firstHackathon

                },
                success: function(data) {
                    $('#success').append('
Thanks for registering, '+$('#Field1').val()+'!
').hide().fadeIn(750));;
                }
            });
        },
        filter: function() {
            return $(this).is(":visible");
        },
    });

    $("a[data-toggle=\"tab\"]").click(function(e) {
        e.preventDefault();
        $(this).tab("show");
    });
});

$('#name').focus(function() {
    $('#success').html('');
});<commit_msg>Submitting form<commit_after>$(function() {

    $("input,textarea").jqBootstrapValidation({
        preventSubmit: true,
        submitError: function($form, event, errors) {
        },
        submitSuccess: function($form, event) {
            var firstHackathon;
            $("#Field6").is(':checked') ? firstHackathon = true : firstHackathon = false;

            console.log($('#Field1').val());

            $.ajax({
                url:    "./scripts/register.php",
                type:   "POST",
                data:   {
                    firstName:  $('#Field1').val(),
                    lastName:  $('#Field2').val(),
                    email:  $('#Field3').val(),
                    school:  $('#Field4').val(),
                    resume: $('#Field5').val(),
                    first: firstHackathon

                },
                success: function(data) {
                    $('#success').append('
Thanks for registering, '+$('#Field1').val()+'!
').hide().fadeIn(750));;
                }
            });
        },
        filter: function() {
            return $(this).is(":visible");
        },
    });

    $("a[data-toggle=\"tab\"]").click(function(e) {
        e.preventDefault();
        $(this).tab("show");
    });
});

$('#name').focus(function() {
    $('#success').html('');
});<|endoftext|>


<commit_before>/* eslint max-len: 0 */
import React from 'react';
import { Link } from 'routes';
import { Autobind } from 'es-decorators';
import classnames from 'classnames';

// Redux
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';
import { toggleModal } from 'redactions/modal';
import { setUser } from 'redactions/user';
import { setRouter } from 'redactions/routes';

// Layout
import Page from 'components/app/layout/Page';
import Head from 'components/app/layout/head';
import Header from 'components/splash/layout/Header';

// Components
import Spinner from 'components/ui/Spinner';
import SplashDetailModal from 'components/modal/SplashDetailModal';
import Modal from 'components/ui/Modal';

// -------PANORAMAS------------
const PANORAMAS = [
  {
    name: 'coral',
    default: 'bleached',
    backgroundSound: 'https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/sounds/CoralBleachBackgroundSound.mp3',
    options: [
      {
        name: 'healthy',
        label: 'Healthy',
        image: 'https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/images/healthy-optimized.jpg',
        markup: ''
      },
      {
        name: 'bleached',
        label: 'Bleached',
        image: 'https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/images/bleached-optimized.jpg',
        markup:
What might resemble a beautiful snowfall is actually a destructive stress response known as coral bleaching, which occurred in Airport Reef in 2015. Prolonged exposure to warmer ocean temperatures can cause corals to expel their symbiotic algae (which gives color to corals and nourishes them through photosynthesis), leaving the corals’ white skeletons visible. Some corals are able to bounce back from a bleaching event if water temperatures decrease fast enough. In a warming ocean, however, corals will have less time to recover between bleaching events, and widespread die-off could occur.\nPhoto date: February 2, 2015
,
        intro: null,
        hotspots: [
          {
            title: 'Coral bleaching on the rise',
            id: 'coral_bleaching_on_the_rise',
            position: '0 2 -12',
            rotation: "0 0 0",
            markup:

                  Since the 1980s, warmer ocean temperatures have contributed to more frequent and more harmful coral bleaching events around the world. From 1980 to 1997, some 370 incidents of coral bleaching and disease were reported. From 1998 to 2010, that number exploded to more than 3,700. (This jump mostly reflects the destructive effect of rising ocean temperatures, though it should be noted that growing awareness, monitoring, and communication of coral bleaching as an issue also played a role.)

                  The spike in 1998, which represents the first global coral bleaching event, was abnormally high; but, as the graph shows, the frequency and severity of coral bleaching events dramatically increased in the following years as well.

                  What happened in 2002 and 2005?

                  Warm ocean temperatures in 2002 caused widespread bleaching, hitting the area around the Great Barrier Reef the hardest. More than half of the Great Barrier Reef’s corals bleached that year.

                  Another spike in 2005 was attributed to an underwater heat wave in the Caribbean, leaving up to 40 percent of reefs bleached there.

                  Global coral bleaching events

First Event (1998): In 1997, an unusually strong El Niño followed by a La Niña dramatically changed global ocean surface temperatures. Exacerbated by the general effects of global warming, these temperature changes led to the first mass coral bleaching in 1998. An estimated 16 percent of coral died in 1998 alone.

Second Event (2010): 2010 set a new record for the hottest year, surpassing 1998. Warm ocean temperatures and a moderate El Niño caused another global bleaching event, affecting reefs in every ocean basin.

Third Event (2014-2017): This has been the longest and most widespread global coral bleaching event to date. From 2014 to 2017, coral reefs around the world experienced higher-than-normal ocean temperatures, fueled by a partial El Niño in 2014-15 and worsened by a strong El Niño and a La Niña in the following years. Reefs in American Samoa (the location of Airport Reef, seen here) and the Great Barrier Reef were heavily affected in 2015 and again in early 2017, leaving the majority of coral bleached.

,
            image: '../../static/images/splash/coral_bleaching_on_the_rise.png',
            imageSelected: '../../static/images/splash/coral_bleaching_on_the_rise_active.png'
          },
          {
            title: 'Coral bleaching up close',
            id: 'coral_bleaching_up_close',
            position: '0 2 16',
            rotation: "0 180 0",
            markup:

                When researchers at the Queensland University of Technology in Australia put corals in tanks and turned up the heat by several degrees, the corals began violently spewing out the algae Symbiodinium in a matter of hours. It’s essentially coral bleaching on fast-forward. The university captured the process in this time-lapse video.

                Normally symbiotic, Symbiodinium actually becomes toxic to corals at higher temperatures; the process on display in this video (called pulsed inflation) is a defense mechanism. It may protect them in the short term, but corals need this algae to recolonize quickly, because they rely on the sugar the algae produce for nourishment. If temperatures remain high over time, the Symbiodinium will not return, leaving the corals’ white skeletons exposed and the animals defenseless against diseases and other stressors.

,
            image: '../../static/images/splash/coral_bleaching_up_close.png',
            imageSelected: '../../static/images/splash/coral_bleaching_up_close_active.png'
          }
        ]
      },
      {
        name: 'dead',
        label: 'Dead',
        image: 'https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/images/dead-optimized.jpg',
        markup: ''
      }
    ]
  }
];

class SplashDetail extends Page {
  static async getInitialProps({ asPath, pathname, query, req, store, isServer }) {
    const { user } = isServer ? req : store.getState();
    const url = { asPath, pathname, query };
    await store.dispatch(setUser(user));
    store.dispatch(setRouter(url));

    // --- Set initial modal ----
    if (true) {
      const options = {
        children: SplashDetailModal,
        childrenProps: {
          text: 'sal;sajktlksa'
        }
      };
      store.dispatch(toggleModal(true, options));
      console.log('hey!');
    }
    // -------------------------
    return { user, isServer, url };
  }

  constructor(props) {
    super(props);
    const panorama = PANORAMAS.find(p => p.name === props.url.query.id);
    const selectedPanorama = panorama.options.find(e => e.name === panorama.default);
    const earthMode = props.url.query.earthMode;

    this.state = {
      skyLoading: false,
      panorama,
      selectedPanorama,
      showDragHelp: true,
      soundActivated: true,
      selectedHotspot: null,
      earthMode,
      mouseHovering: false,
      modalOpen: false
    };
  }

  componentDidMount() {
    const { selectedPanorama } = this.state;

    this.panoramaSky = document.getElementById('panorama-sky');
    this.panoramaSky.addEventListener('materialtextureloaded', this.handleImageLoaded);
    document.addEventListener('mousedown', this.hideDragHelp);

    selectedPanorama.hotspots.forEach((hotspot) => {
      const elem = document.getElementById(hotspot.id);
      elem.addEventListener('click', () => this.handleSelectedHostpot(hotspot));
      elem.addEventListener('mouseenter', () => this.handleMouseOverHotspot(hotspot));
      elem.addEventListener('mouseleave', () => this.handleMouseLeavesHotspot(hotspot))
    });

    const options = {
      children: SplashDetailModal,
      childrenProps: {
        text: 'sal;sajktlksa'
      }
    };
    this.props.toggleModal(true, options);
    console.log('ho!');
  }

  componentWillReceiveProps(newProps) {
    if (this.state.modalOpen !== newProps.modal.open) {
      this.setState({ modalOpen: newProps.modal.open });
    }
  }

  @Autobind
  handlePanoramaChange(event) {
    const { panorama } = this.state;
    const radioButtonId = event.target.getAttribute('id');
    this.setState({
      selectedPanorama: panorama.options.find(e => e.name === radioButtonId),
      skyLoading: true
    });
  }

  @Autobind
  handleImageLoaded() {
    this.setState({ skyLoading: false });
  }

  @Autobind
  hideDragHelp() {
    this.setState({ showDragHelp: false });
    document.removeEventListener('mousedown', this.hideDragHelp);
  }

  @Autobind
  handleSoundChange() {
    this.setState({
      soundActivated: !this.state.soundActivated
    });
  }

  handleSelectedHostpot(hotspot) {
    this.setState({ selectedHotspot: hotspot });
  }
  handleMouseOverHotspot(hotspot) {
    this.setState({ mouseHovering: true });
  }
  handleMouseLeavesHotspot(hotspot) {
    this.setState({ mouseHovering: false });
  }

  @Autobind
  handleCloseRightMenu() {
    this.setState({ selectedHotspot: null });
  }

  render() {
    const { modal } = this.props;
    const {
      selectedPanorama,
      skyLoading,
      panorama,
      showDragHelp,
      soundActivated,
      selectedHotspot,
      earthMode,
      mouseHovering
    } = this.state;
    const skyImage = selectedPanorama && selectedPanorama.image;
    const intro = selectedPanorama && selectedPanorama.intro;
    const markup = selectedPanorama && selectedPanorama.markup;
    const hotspots = selectedPanorama && selectedPanorama.hotspots;
    const options = panorama && panorama.options;
    const backgroundSound = panorama.backgroundSound;

    const pageClass = classnames({
      'p-splash-detail': true,
      '-hovering': mouseHovering
    });

    return (

        {selectedHotspot &&

{selectedHotspot.title}

                {selectedHotspot.markup}

        }

          <Spinner isLoading={skyLoading} className="-light" />

              Scenario

              {options && options.map(elem => (

                  <input type="radio" id={elem.name} checked={selectedPanorama.name === elem.name} onChange={this.handlePanoramaChange} />
                  {elem.label}

              ))
              }

                <input type="checkbox" id="soundCheckbox" checked={soundActivated} onChange={this.handleSoundChange}/>
                Sound

            {options &&

                {options && options.map(elem => (

                ))
                }

            }

            { /* 360-degree image */ }
            {!earthMode &&

            }
            {earthMode &&

            }

            { /* Background sound */ }
            {backgroundSound && soundActivated &&
              <audio
                src={backgroundSound}
                autoPlay
                loop
                preload
              >
                <track kind="captions" /> { /* TO-DO add captions for deaf users */ }
              </audio>
            }

            {intro && showDragHelp &&
              <a-entity
                id="intro"
                position="0 2 -10"
                geometry="primitive: plane; height: 10; width: 10"
                material={`shader: flat; src: ${intro}; transparent: true`}
              />
            }

            { /* Hotspots */ }
            {hotspots && hotspots.map(elem => (
              <a-entity
                id={elem.id}
                position={elem.position}
                rotation={elem.rotation}
                key={elem.title}
                geometry="primitive: plane; height: 4; width: 6"
                material={`shader: flat; src: ${(selectedHotspot && selectedHotspot.id === elem.id) ? elem.imageSelected : elem.image}; transparent: true`}
              />
            ))}

            { /* Camera */ }

        <Modal
          open={this.state.modalOpen}
          options={modal.options}
          className="no-borders"
          loading={modal.loading}
          toggleModal={this.props.toggleModal}
          setModalOptions={this.props.setModalOptions}
        />

    );
  }
}

const mapStateToProps = state => ({
  modal: state.modal
});

const mapDispatchToProps = {
  toggleModal
};

export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(SplashDetail);
<commit_msg>remove use of Autobind<commit_after>/* eslint max-len: 0 */
import React from 'react';
import { Link } from 'routes';
import classnames from 'classnames';

// Redux
import withRedux from 'next-redux-wrapper';
import { initStore } from 'store';
import { toggleModal } from 'redactions/modal';
import { setUser } from 'redactions/user';
import { setRouter } from 'redactions/routes';

// Layout
import Page from 'components/app/layout/Page';
import Head from 'components/app/layout/head';
import Header from 'components/splash/layout/Header';

// Components
import Spinner from 'components/ui/Spinner';
import SplashDetailModal from 'components/modal/SplashDetailModal';
import Modal from 'components/ui/Modal';

// -------PANORAMAS------------
const PANORAMAS = [
  {
    name: 'coral',
    default: 'bleached',
    backgroundSound: 'https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/sounds/CoralBleachBackgroundSound.mp3',
    options: [
      {
        name: 'healthy',
        label: 'Healthy',
        image: 'https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/images/healthy-optimized.jpg',
        markup: ''
      },
      {
        name: 'bleached',
        label: 'Bleached',
        image: 'https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/images/bleached-optimized.jpg',
        intro:
What might resemble a beautiful snowfall is actually a destructive stress response known as coral bleaching, which occurred in Airport Reef in 2015. Prolonged exposure to warmer ocean temperatures can cause corals to expel their symbiotic algae (which gives color to corals and nourishes them through photosynthesis), leaving the corals’ white skeletons visible. Some corals are able to bounce back from a bleaching event if water temperatures decrease fast enough. In a warming ocean, however, corals will have less time to recover between bleaching events, and widespread die-off could occur.\nPhoto date: February 2, 2015
,
        hotspots: [
          {
            title: 'Coral bleaching on the rise',
            id: 'coral_bleaching_on_the_rise',
            position: '0 2 -12',
            rotation: "0 0 0",
            markup:

                  Since the 1980s, warmer ocean temperatures have contributed to more frequent and more harmful coral bleaching events around the world. From 1980 to 1997, some 370 incidents of coral bleaching and disease were reported. From 1998 to 2010, that number exploded to more than 3,700. (This jump mostly reflects the destructive effect of rising ocean temperatures, though it should be noted that growing awareness, monitoring, and communication of coral bleaching as an issue also played a role.)

                  The spike in 1998, which represents the first global coral bleaching event, was abnormally high; but, as the graph shows, the frequency and severity of coral bleaching events dramatically increased in the following years as well.

                  What happened in 2002 and 2005?

                  Warm ocean temperatures in 2002 caused widespread bleaching, hitting the area around the Great Barrier Reef the hardest. More than half of the Great Barrier Reef’s corals bleached that year.

                  Another spike in 2005 was attributed to an underwater heat wave in the Caribbean, leaving up to 40 percent of reefs bleached there.

                  Global coral bleaching events

First Event (1998): In 1997, an unusually strong El Niño followed by a La Niña dramatically changed global ocean surface temperatures. Exacerbated by the general effects of global warming, these temperature changes led to the first mass coral bleaching in 1998. An estimated 16 percent of coral died in 1998 alone.

Second Event (2010): 2010 set a new record for the hottest year, surpassing 1998. Warm ocean temperatures and a moderate El Niño caused another global bleaching event, affecting reefs in every ocean basin.

Third Event (2014-2017): This has been the longest and most widespread global coral bleaching event to date. From 2014 to 2017, coral reefs around the world experienced higher-than-normal ocean temperatures, fueled by a partial El Niño in 2014-15 and worsened by a strong El Niño and a La Niña in the following years. Reefs in American Samoa (the location of Airport Reef, seen here) and the Great Barrier Reef were heavily affected in 2015 and again in early 2017, leaving the majority of coral bleached.

,
            image: '../../static/images/splash/coral_bleaching_on_the_rise.png',
            imageSelected: '../../static/images/splash/coral_bleaching_on_the_rise_active.png'
          },
          {
            title: 'Coral bleaching up close',
            id: 'coral_bleaching_up_close',
            position: '0 2 16',
            rotation: "0 180 0",
            markup:

                When researchers at the Queensland University of Technology in Australia put corals in tanks and turned up the heat by several degrees, the corals began violently spewing out the algae Symbiodinium in a matter of hours. It’s essentially coral bleaching on fast-forward. The university captured the process in this time-lapse video.

                Normally symbiotic, Symbiodinium actually becomes toxic to corals at higher temperatures; the process on display in this video (called pulsed inflation) is a defense mechanism. It may protect them in the short term, but corals need this algae to recolonize quickly, because they rely on the sugar the algae produce for nourishment. If temperatures remain high over time, the Symbiodinium will not return, leaving the corals’ white skeletons exposed and the animals defenseless against diseases and other stressors.

,
            image: '../../static/images/splash/coral_bleaching_up_close.png',
            imageSelected: '../../static/images/splash/coral_bleaching_up_close_active.png'
          }
        ]
      },
      {
        name: 'dead',
        label: 'Dead',
        image: 'https://s3.amazonaws.com/wri-api-backups/resourcewatch/staging/images/dead-optimized.jpg',
        markup: ''
      }
    ]
  }
];

class SplashDetail extends Page {
  constructor(props) {
    super(props);
    const panorama = PANORAMAS.find(p => p.name === props.url.query.id);
    const selectedPanorama = panorama.options.find(e => e.name === panorama.default);
    const earthMode = props.url.query.earthMode;

    this.state = {
      skyLoading: false,
      panorama,
      selectedPanorama,
      soundActivated: true,
      selectedHotspot: null,
      earthMode,
      mouseHovering: false,
      modalOpen: false
    };

    // --------------- Bindings -----------------------
    this.handlePanoramaChange = this.handlePanoramaChange.bind(this);
    this.handleImageLoaded = this.handleImageLoaded.bind(this);
    this.handleSoundChange = this.handleSoundChange.bind(this);
    this.handleCloseRightMenu = this.handleCloseRightMenu.bind(this);
    // ------------------------------------------------
  }

  componentDidMount() {
    const { selectedPanorama } = this.state;

    this.panoramaSky = document.getElementById('panorama-sky');
    this.panoramaSky.addEventListener('materialtextureloaded', this.handleImageLoaded);

    selectedPanorama.hotspots.forEach((hotspot) => {
      const elem = document.getElementById(hotspot.id);
      elem.addEventListener('click', () => this.handleSelectedHostpot(hotspot));
      elem.addEventListener('mouseenter', () => this.handleMouseOverHotspot(hotspot));
      elem.addEventListener('mouseleave', () => this.handleMouseLeavesHotspot(hotspot))
    });

    const options = {
      children: SplashDetailModal,
      childrenProps: {
        text: selectedPanorama.markup
      }
    };
    this.props.toggleModal(true, options);
  }

  componentWillReceiveProps(newProps) {
    if (this.state.modalOpen !== newProps.modal.open) {
      this.setState({ modalOpen: newProps.modal.open });
    }
  }

  /**
  * UI Event handlers
  * - handlePanoramaChange
  * - handleImageLoaded
  * - handleSoundChange
  * - handleSelectedHostpot
  * - handleMouseOverHotspot
  * - handleMouseLeavesHotspot
  * - handleCloseRightMenu
  */
  handlePanoramaChange(event) {
    const { panorama } = this.state;
    const radioButtonId = event.target.getAttribute('id');
    this.setState({
      selectedPanorama: panorama.options.find(e => e.name === radioButtonId),
      skyLoading: true
    });
  }

  handleImageLoaded() {
    this.setState({ skyLoading: false });
  }

  handleSoundChange() {
    this.setState({
      soundActivated: !this.state.soundActivated
    });
  }

  handleSelectedHostpot(hotspot) {
    this.setState({ selectedHotspot: hotspot });
  }
  handleMouseOverHotspot(hotspot) {
    this.setState({ mouseHovering: true });
  }
  handleMouseLeavesHotspot(hotspot) {
    this.setState({ mouseHovering: false });
  }

  handleCloseRightMenu() {
    this.setState({ selectedHotspot: null });
  }

  render() {
    const { modal } = this.props;
    const {
      selectedPanorama,
      skyLoading,
      panorama,
      soundActivated,
      selectedHotspot,
      earthMode,
      mouseHovering
    } = this.state;
    const skyImage = selectedPanorama && selectedPanorama.image;
    const intro = selectedPanorama && selectedPanorama.intro;
    const markup = selectedPanorama && selectedPanorama.markup;
    const hotspots = selectedPanorama && selectedPanorama.hotspots;
    const options = panorama && panorama.options;
    const backgroundSound = panorama.backgroundSound;

    const pageClass = classnames({
      'p-splash-detail': true,
      '-hovering': mouseHovering
    });

    return (

        {selectedHotspot &&

{selectedHotspot.title}

                {selectedHotspot.markup}

        }

          <Spinner isLoading={skyLoading} className="-light" />

              Scenario

              {options && options.map(elem => (

                  <input type="radio" id={elem.name} checked={selectedPanorama.name === elem.name} onChange={this.handlePanoramaChange} />
                  {elem.label}

              ))
              }

                <input type="checkbox" id="soundCheckbox" checked={soundActivated} onChange={this.handleSoundChange}/>
                Sound

            {options &&

                {options && options.map(elem => (

                ))
                }

            }

            { /* 360-degree image */ }
            {!earthMode &&

            }
            {earthMode &&

            }

            { /* Background sound */ }
            {backgroundSound && soundActivated &&
              <audio
                src={backgroundSound}
                autoPlay
                loop
                preload
              >
                <track kind="captions" /> { /* TO-DO add captions for deaf users */ }
              </audio>
            }

            { /* Hotspots */ }
            {hotspots && hotspots.map(elem => (
              <a-entity
                id={elem.id}
                position={elem.position}
                rotation={elem.rotation}
                key={elem.title}
                geometry="primitive: plane; height: 4; width: 6"
                material={`shader: flat; src: ${(selectedHotspot && selectedHotspot.id === elem.id) ? elem.imageSelected : elem.image}; transparent: true`}
              />
            ))}

            { /* Camera */ }

        <Modal
          open={this.state.modalOpen}
          options={modal.options}
          className="no-borders"
          loading={modal.loading}
          toggleModal={this.props.toggleModal}
          setModalOptions={this.props.setModalOptions}
        />

    );
  }
}

const mapStateToProps = state => ({
  modal: state.modal
});

const mapDispatchToProps = {
  toggleModal
};

export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(SplashDetail);
<|endoftext|>


<commit_before>/**
 * @module ol/control/Zoom
 */
import Control from './Control.js';
import EventType from '../events/EventType.js';
import {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';
import {easeOut} from '../easing.js';

/**
 * @typedef {Object} Options
 * @property {number} [duration=250] Animation duration in milliseconds.
 * @property {string} [className='ol-zoom'] CSS class name.
 * @property {string|HTMLElement} [zoomInLabel='+'] Text label to use for the zoom-in
 * button. Instead of text, also an element (e.g. a `span` element) can be used.
 * @property {string|HTMLElement} [zoomOutLabel='-'] Text label to use for the zoom-out button.
 * Instead of text, also an element (e.g. a `span` element) can be used.
 * @property {string} [zoomInTipLabel='Zoom in'] Text label to use for the button tip.
 * @property {string} [zoomOutTipLabel='Zoom out'] Text label to use for the button tip.
 * @property {number} [delta=1] The zoom delta applied on each click.
 * @property {HTMLElement|string} [target] Specify a target if you want the control to be
 * rendered outside of the map's viewport.
 */

/**
 * @classdesc
 * A control with 2 buttons, one for zoom in and one for zoom out.
 * This control is one of the default controls of a map. To style this control
 * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.
 *
 * @api
 */
class Zoom extends Control {
  /**
   * @param {Options=} opt_options Zoom options.
   */
  constructor(opt_options) {
    const options = opt_options ? opt_options : {};

    super({
      element: document.createElement('div'),
      target: options.target,
    });

    const className =
      options.className !== undefined ? options.className : 'ol-zoom';

    const delta = options.delta !== undefined ? options.delta : 1;

    const zoomInLabel =
      options.zoomInLabel !== undefined ? options.zoomInLabel : '+';
    const zoomOutLabel =
      options.zoomOutLabel !== undefined ? options.zoomOutLabel : '\u2212';

    const zoomInTipLabel =
      options.zoomInTipLabel !== undefined ? options.zoomInTipLabel : 'Zoom in';
    const zoomOutTipLabel =
      options.zoomOutTipLabel !== undefined
        ? options.zoomOutTipLabel
        : 'Zoom out';

    const inElement = document.createElement('button');
    inElement.className = className + '-in';
    inElement.setAttribute('type', 'button');
    inElement.title = zoomInTipLabel;
    inElement.appendChild(
      typeof zoomInLabel === 'string'
        ? document.createTextNode(zoomInLabel)
        : zoomInLabel
    );

    inElement.addEventListener(
      EventType.CLICK,
      this.handleClick_.bind(this, delta),
      false
    );

    const outElement = document.createElement('button');
    outElement.className = className + '-out';
    outElement.setAttribute('type', 'button');
    outElement.title = zoomOutTipLabel;
    outElement.appendChild(
      typeof zoomOutLabel === 'string'
        ? document.createTextNode(zoomOutLabel)
        : zoomOutLabel
    );

    outElement.addEventListener(
      EventType.CLICK,
      this.handleClick_.bind(this, -delta),
      false
    );

    const cssClasses =
      className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
    const element = this.element;
    element.className = cssClasses;
    element.appendChild(inElement);
    element.appendChild(outElement);

    /**
     * @type {number}
     * @private
     */
    this.duration_ = options.duration !== undefined ? options.duration : 250;
  }

  /**
   * @param {number} delta Zoom delta.
   * @param {MouseEvent} event The event to handle
   * @private
   */
  handleClick_(delta, event) {
    event.preventDefault();
    this.zoomByDelta_(delta);
  }

  /**
   * @param {number} delta Zoom delta.
   * @private
   */
  zoomByDelta_(delta) {
    const map = this.getMap();
    const view = map.getView();
    if (!view) {
      // the map does not have a view, so we can't act
      // upon it
      return;
    }
    const currentZoom = view.getZoom();
    if (currentZoom !== undefined) {
      const newZoom = view.getConstrainedZoom(currentZoom + delta);
      if (this.duration_ > 0) {
        if (view.getAnimating()) {
          view.cancelAnimations();
        }
        view.animate({
          zoom: newZoom,
          duration: this.duration_,
          easing: easeOut,
        });
      } else {
        view.setZoom(newZoom);
      }
    }
  }
}

export default Zoom;
<commit_msg>add CSS class name support for zoom buttons<commit_after>/**
 * @module ol/control/Zoom
 */
import Control from './Control.js';
import EventType from '../events/EventType.js';
import {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';
import {easeOut} from '../easing.js';

/**
 * @typedef {Object} Options
 * @property {number} [duration=250] Animation duration in milliseconds.
 * @property {string} [className='ol-zoom'] CSS class name.
 * @property {string} [zoomInClassName=className + '-in'] CSS class name for the zoom-in button.
 * @property {string} [zoomOutClassName=className + '-out'] CSS class name for the zoom-out button.
 * @property {string|HTMLElement} [zoomInLabel='+'] Text label to use for the zoom-in
 * button. Instead of text, also an element (e.g. a `span` element) can be used.
 * @property {string|HTMLElement} [zoomOutLabel='-'] Text label to use for the zoom-out button.
 * Instead of text, also an element (e.g. a `span` element) can be used.
 * @property {string} [zoomInTipLabel='Zoom in'] Text label to use for the button tip.
 * @property {string} [zoomOutTipLabel='Zoom out'] Text label to use for the button tip.
 * @property {number} [delta=1] The zoom delta applied on each click.
 * @property {HTMLElement|string} [target] Specify a target if you want the control to be
 * rendered outside of the map's viewport.
 */

/**
 * @classdesc
 * A control with 2 buttons, one for zoom in and one for zoom out.
 * This control is one of the default controls of a map. To style this control
 * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.
 *
 * @api
 */
class Zoom extends Control {
  /**
   * @param {Options=} opt_options Zoom options.
   */
  constructor(opt_options) {
    const options = opt_options ? opt_options : {};

    super({
      element: document.createElement('div'),
      target: options.target,
    });

    const className =
      options.className !== undefined ? options.className : 'ol-zoom';

    const delta = options.delta !== undefined ? options.delta : 1;

    const zoomInClassName =
        options.zoomInClassName !== undefined ? options.zoomInClassName : className + '-in';
    const zoomOutClassName =
        options.zoomOutClassName !== undefined ? options.zoomOutClassName : className + '-out';

    const zoomInLabel =
      options.zoomInLabel !== undefined ? options.zoomInLabel : '+';
    const zoomOutLabel =
      options.zoomOutLabel !== undefined ? options.zoomOutLabel : '\u2212';

    const zoomInTipLabel =
      options.zoomInTipLabel !== undefined ? options.zoomInTipLabel : 'Zoom in';
    const zoomOutTipLabel =
      options.zoomOutTipLabel !== undefined
        ? options.zoomOutTipLabel
        : 'Zoom out';

    const inElement = document.createElement('button');
    inElement.className = zoomInClassName;
    inElement.setAttribute('type', 'button');
    inElement.title = zoomInTipLabel;
    inElement.appendChild(
      typeof zoomInLabel === 'string'
        ? document.createTextNode(zoomInLabel)
        : zoomInLabel
    );

    inElement.addEventListener(
      EventType.CLICK,
      this.handleClick_.bind(this, delta),
      false
    );

    const outElement = document.createElement('button');
    outElement.className = zoomOutClassName;
    outElement.setAttribute('type', 'button');
    outElement.title = zoomOutTipLabel;
    outElement.appendChild(
      typeof zoomOutLabel === 'string'
        ? document.createTextNode(zoomOutLabel)
        : zoomOutLabel
    );

    outElement.addEventListener(
      EventType.CLICK,
      this.handleClick_.bind(this, -delta),
      false
    );

    const cssClasses =
      className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
    const element = this.element;
    element.className = cssClasses;
    element.appendChild(inElement);
    element.appendChild(outElement);

    /**
     * @type {number}
     * @private
     */
    this.duration_ = options.duration !== undefined ? options.duration : 250;
  }

  /**
   * @param {number} delta Zoom delta.
   * @param {MouseEvent} event The event to handle
   * @private
   */
  handleClick_(delta, event) {
    event.preventDefault();
    this.zoomByDelta_(delta);
  }

  /**
   * @param {number} delta Zoom delta.
   * @private
   */
  zoomByDelta_(delta) {
    const map = this.getMap();
    const view = map.getView();
    if (!view) {
      // the map does not have a view, so we can't act
      // upon it
      return;
    }
    const currentZoom = view.getZoom();
    if (currentZoom !== undefined) {
      const newZoom = view.getConstrainedZoom(currentZoom + delta);
      if (this.duration_ > 0) {
        if (view.getAnimating()) {
          view.cancelAnimations();
        }
        view.animate({
          zoom: newZoom,
          duration: this.duration_,
          easing: easeOut,
        });
      } else {
        view.setZoom(newZoom);
      }
    }
  }
}

export default Zoom;
<|endoftext|>


<commit_before>(function(){
    'use strict';

    var
    main = smiliesConfig.main,
    smilies = smiliesConfig.smilies,
    shorts = smiliesConfig.shorts,

    regex = new RegExp(':(' + smilies.join('|') + '):', 'g'),
    template = '',

    escapeRegExp = function(str) {
        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    },

    regExpForShort = function(str) {
        if (/^[a-z]+$/i.test(str)) { // use word boundaries if emoji is letters only
            return new RegExp('\\b'+ str +'\\b', 'gi');
        }
        else {
            return new RegExp(escapeRegExp(str), 'gi');
        }
    },

    templateForSmiley = function(str) {
        return template.replace('$1', str);
    },

    apply = function(input) {
        var output = input.replace(regex, template);

        for (var sm in shorts) {
            if (shorts.hasOwnProperty(sm)) {
                output = output.replace(regExpForShort(sm), templateForSmiley(shorts[sm]));
            }
        }

        return output;
    };

    angular.module('angular-smilies', [])
    /* smilies parser filter */
    .filter('smilies', function() {
        return apply;
    })
    /* smilies parser attribute */
    .directive('smilies', function() {
        return {
            restrict: 'A',
            scope: {
                source: '=smilies'
            },
            link: function($scope, el, attrs) {
                el.html(apply($scope.source));
            }
        };
    })
    /* smilies selector directive */
    .directive('smiliesSelector', ['$timeout', function($timeout) {
        var templateUrl;
        try {
            angular.module('ui.bootstrap.popover');
            templateUrl = 'template/smilies/button-a.html';
        }
        catch(e) {
            try {
                angular.module('mgcrea.ngStrap.popover');
                templateUrl = 'template/smilies/button-b.html';
            }
            catch(e) {
                console.error('No Popover module found');
                return {};
            }
        }

        return {
            restrict: 'A',
            templateUrl: templateUrl,
            scope: {
                source: '=smiliesSelector',
                placement: '@smiliesPlacement',
                title: '@smiliesTitle'
            },
            link: function($scope, el) {
                $scope.smilies = smilies;

                $scope.append = function(smiley) {
                    $scope.source+= ' :'+smiley+': ';

                    $timeout(function() {
                        el.children('i').triggerHandler('click'); // close the popover
                    });
                };
            }
        };

    }])
    /* helper directive for input focusing */
    .directive('focusOnChange', function($timeout) {
        return {
            restrict: 'A',
            link: function($scope, el, attrs) {
                $scope.$watch(attrs.focusOnChange, function() {
                    el[0].focus();
                });
            }
        };
    })
    /* popover template */
    .run(['$templateCache', function($templateCache) {
        // use ng-init because popover-template only accept a variable
        $templateCache.put('template/smilies/button-a.html',
            ''
        );
        $templateCache.put('template/smilies/button-b.html',
            ''
        );
        $templateCache.put('template/smilies/popover-a.html',
            '
'+
              ''+
            '
'
        );
        $templateCache.put('template/smilies/popover-b.html',
            '
'+
                '

'+
                '

'+
                '
'+
                    $templateCache.get('template/smilies/popover-a.html') +
                '
'+
            '
'
        );
    }]);

}());<commit_msg>Remove unused $timout in focusOnChange (#6)<commit_after>(function(){
    'use strict';

    var
    main = smiliesConfig.main,
    smilies = smiliesConfig.smilies,
    shorts = smiliesConfig.shorts,

    regex = new RegExp(':(' + smilies.join('|') + '):', 'g'),
    template = '',

    escapeRegExp = function(str) {
        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    },

    regExpForShort = function(str) {
        if (/^[a-z]+$/i.test(str)) { // use word boundaries if emoji is letters only
            return new RegExp('\\b'+ str +'\\b', 'gi');
        }
        else {
            return new RegExp(escapeRegExp(str), 'gi');
        }
    },

    templateForSmiley = function(str) {
        return template.replace('$1', str);
    },

    apply = function(input) {
        var output = input.replace(regex, template);

        for (var sm in shorts) {
            if (shorts.hasOwnProperty(sm)) {
                output = output.replace(regExpForShort(sm), templateForSmiley(shorts[sm]));
            }
        }

        return output;
    };

    angular.module('angular-smilies', [])
    /* smilies parser filter */
    .filter('smilies', function() {
        return apply;
    })
    /* smilies parser attribute */
    .directive('smilies', function() {
        return {
            restrict: 'A',
            scope: {
                source: '=smilies'
            },
            link: function($scope, el, attrs) {
                el.html(apply($scope.source));
            }
        };
    })
    /* smilies selector directive */
    .directive('smiliesSelector', ['$timeout', function($timeout) {
        var templateUrl;
        try {
            angular.module('ui.bootstrap.popover');
            templateUrl = 'template/smilies/button-a.html';
        }
        catch(e) {
            try {
                angular.module('mgcrea.ngStrap.popover');
                templateUrl = 'template/smilies/button-b.html';
            }
            catch(e) {
                console.error('No Popover module found');
                return {};
            }
        }

        return {
            restrict: 'A',
            templateUrl: templateUrl,
            scope: {
                source: '=smiliesSelector',
                placement: '@smiliesPlacement',
                title: '@smiliesTitle'
            },
            link: function($scope, el) {
                $scope.smilies = smilies;

                $scope.append = function(smiley) {
                    $scope.source+= ' :'+smiley+': ';

                    $timeout(function() {
                        el.children('i').triggerHandler('click'); // close the popover
                    });
                };
            }
        };

    }])
    /* helper directive for input focusing */
    .directive('focusOnChange', function() {
        return {
            restrict: 'A',
            link: function($scope, el, attrs) {
                $scope.$watch(attrs.focusOnChange, function() {
                    el[0].focus();
                });
            }
        };
    })
    /* popover template */
    .run(['$templateCache', function($templateCache) {
        // use ng-init because popover-template only accept a variable
        $templateCache.put('template/smilies/button-a.html',
            ''
        );
        $templateCache.put('template/smilies/button-b.html',
            ''
        );
        $templateCache.put('template/smilies/popover-a.html',
            '
'+
              ''+
            '
'
        );
        $templateCache.put('template/smilies/popover-b.html',
            '
'+
                '

'+
                '

'+
                '
'+
                    $templateCache.get('template/smilies/popover-a.html') +
                '
'+
            '
'
        );
    }]);

}());
<|endoftext|>


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

var MODE_LABELS = {
  0: 'UNKNOWN',
  1: 'NORMAL',
  2: 'MAGIC_WINDOW',
  3: 'VR'
};

function Analytics() {
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-35315454-8', 'auto');
  ga('send', 'pageview');

  this.lastModeChangeTime = window.performance.now();
  this.lastModeLabel = WebVRManager.Modes.UNKNOWN;
}

Analytics.prototype.logModeChanged = function(mode) {
  var modeLabel = MODE_LABELS[mode];
  var lastModeLabel = MODE_LABELS[this.lastMode];

  console.log('Analytics: going from mode %s to %s', lastModeLabel, modeLabel);

  ga('send', 'screenview', {
    appName: 'EmbedVR',
    screenName: modeLabel
  });

  var now = window.performance.now();
  var msSinceLastModeChange = Math.round(now - this.lastModeChangeTime);
  ga('send', 'timing', 'Time spent in mode', lastModeLabel, msSinceLastModeChange);

  this.lastModeChangeTime = now;
  this.lastMode = mode;
}

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

function Analytics() {
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-35315454-8', 'auto');
  ga('send', 'pageview');

  this.lastModeChangeTime = window.performance.now();
  this.lastModeLabel = WebVRManager.Modes.UNKNOWN;
}

Analytics.MODE_LABELS = {
  0: 'UNKNOWN',
  1: 'NORMAL',
  2: 'MAGIC_WINDOW',
  3: 'VR'
};

Analytics.prototype.logModeChanged = function(mode) {
  var modeLabel = Analytics.MODE_LABELS[mode];
  var lastModeLabel = Analytics.MODE_LABELS[this.lastMode];

  console.log('Analytics: going from mode %s to %s', lastModeLabel, modeLabel);

  ga('send', 'screenview', {
    appName: 'EmbedVR',
    screenName: modeLabel
  });

  var now = window.performance.now();
  var msSinceLastModeChange = Math.round(now - this.lastModeChangeTime);
  ga('send', 'timing', 'Time spent in mode', lastModeLabel, msSinceLastModeChange);

  this.lastModeChangeTime = now;
  this.lastMode = mode;
}

window.analytics = new Analytics();
<|endoftext|>


<commit_before>
goog.provide('urlbuilder.Controller');
goog.provide('urlbuilder.UrlComponents');

goog.require('goog.dom');
goog.require('goog.events');
goog.require('urlbuilder.EventHandler');
goog.require('urlbuilder.Ui');
goog.require('urlbuilder.UrlEvent');

/** @typedef {{scheme: string, domain: string, port: string,
      path: string}} */
urlbuilder.UrlComponents;

/**
 * The controller class.
 * @constructor
 */
urlbuilder.Controller = function()
{};

/**
 * Initialize the UI.
 * @private
 */
urlbuilder.Controller.prototype.init = function()
{
  this.initUi_();
  this.initEventHandler_();
  this.initActions_();
};

/**
 * Links the events dispatched by the EventHandler
 * to the Controller functions.
 * @private
 */
urlbuilder.Controller.prototype.initActions_ = function()
{
  this.eventHandler_.addEventListener(
	urlbuilder.EventHandler.EventType.URL, this.onUrlEvent_);
  this.eventHandler_.addEventListener(
	urlbuilder.EventHandler.EventType.FIELD, this.onFieldEvent_);
};

/**
 * Activates the DOM elements listeners.
 * @private
 */
urlbuilder.Controller.prototype.initEventHandler_ = function()
{
  var elements = this.ui_.getTextFields();
  this.eventHandler_ = new urlbuilder.EventHandler(elements);
};

urlbuilder.Controller.prototype.initUi_ = function()
{
  this.ui_ = new urlbuilder.Ui();
};

/**
 * Composes the url into the url text field from the
 * data contained in the other fields.
 * @param {string} url The input url.
 * @private
 */
urlbuilder.Controller.composeUrl_ = function()
{
  // TODO
};

/**
 * Parses a url and splits it into its components.
 * @param {string} url The input url.
 * @return {urlbuilder.UrlComponents} The elements that compose the url.
 * @private
 */
urlbuilder.Controller.parseUrl_ = function(url)
{
  var regExp = new RegExp(urlbuilder.Controller.UrlRegExp);
  var matches = regExp.exec(url);
  console.log(matches);
};

/**
 * Handles a Url event.
 * @param {urlbuilder.UrlEvent} evt The Url event.
 * @private
 */
urlbuilder.Controller.prototype.onUrlEvent_ = function(evt)
{
  var url = evt.url;
  urlbuilder.Controller.parseUrl_(url);
};

/**
 * Handles the event of field modification.
 * @param {goog.events.Event} evt The event.
 * @private
 */
urlbuilder.Controller.prototype.onFieldEvent_ = function(evt)
{};

/**
 * The event handler instance.
 * @type {urlbuilder.EventHandler}
 * @private
 */
urlbuilder.Controller.prototype.eventHandler_ = null;

/**
 * The regular expression used to parse the url.
 * It divides the url into: scheme, subdomain, domain, port,
 * path, query string and fragment string.
 */
urlbuilder.Controller.UrlRegExp = "(([a-z]*)://)?(([a-z]*)?\.?([a-z]*)?\.?([a-z]*)?\.?([a-z]*)?\.?)";

<commit_msg>Add a different regexp for the url<commit_after>
goog.provide('urlbuilder.Controller');
goog.provide('urlbuilder.UrlComponents');

goog.require('goog.dom');
goog.require('goog.events');
goog.require('urlbuilder.EventHandler');
goog.require('urlbuilder.Ui');
goog.require('urlbuilder.UrlEvent');

/** @typedef {{scheme: string, domain: string, port: string,
      path: string}} */
urlbuilder.UrlComponents;

/**
 * The controller class.
 * @constructor
 */
urlbuilder.Controller = function()
{};

/**
 * Initialize the UI.
 * @private
 */
urlbuilder.Controller.prototype.init = function()
{
  this.initUi_();
  this.initEventHandler_();
  this.initActions_();
};

/**
 * Links the events dispatched by the EventHandler
 * to the Controller functions.
 * @private
 */
urlbuilder.Controller.prototype.initActions_ = function()
{
  this.eventHandler_.addEventListener(
	urlbuilder.EventHandler.EventType.URL, this.onUrlEvent_);
  this.eventHandler_.addEventListener(
	urlbuilder.EventHandler.EventType.FIELD, this.onFieldEvent_);
};

/**
 * Activates the DOM elements listeners.
 * @private
 */
urlbuilder.Controller.prototype.initEventHandler_ = function()
{
  var elements = this.ui_.getTextFields();
  this.eventHandler_ = new urlbuilder.EventHandler(elements);
};

urlbuilder.Controller.prototype.initUi_ = function()
{
  this.ui_ = new urlbuilder.Ui();
};

/**
 * Composes the url into the url text field from the
 * data contained in the other fields.
 * @param {string} url The input url.
 * @private
 */
urlbuilder.Controller.composeUrl_ = function()
{
  // TODO
};

/**
 * Parses a url and splits it into its components.
 * @param {string} url The input url.
 * @return {urlbuilder.UrlComponents} The elements that compose the url.
 * @private
 */
urlbuilder.Controller.parseUrl_ = function(url)
{
  var regExp = new RegExp(urlbuilder.Controller.BaseRegExp);
  var matches = regExp.exec(url);
  console.log(matches);
};

/**
 * Handles a Url event.
 * @param {urlbuilder.UrlEvent} evt The Url event.
 * @private
 */
urlbuilder.Controller.prototype.onUrlEvent_ = function(evt)
{
  var url = evt.url;
  urlbuilder.Controller.parseUrl_(url);
};

/**
 * Handles the event of field modification.
 * @param {goog.events.Event} evt The event.
 * @private
 */
urlbuilder.Controller.prototype.onFieldEvent_ = function(evt)
{};

/**
 * The event handler instance.
 * @type {urlbuilder.EventHandler}
 * @private
 */
urlbuilder.Controller.prototype.eventHandler_ = null;

/**
 * The regular expression used to divide the url into
 * schema, host, port, path, query and fragment
 */
urlbuilder.Controller.BaseRegExp = "(([a-z]*)://)?([^\/:]*)(:([0-9]*))?(/([^?#]*)?(\\??([^#]*))?(#?(.*))?)?";

/**
 * The regular expression used to parse the url.
 * It divides the url into: scheme, subdomain, domain, port,
 * path, query string and fragment string.
 */
urlbuilder.Controller.UrlRegExp = "(([a-z]*)://)?(([a-z]*)?\.?([a-z]*)?\.?([a-z]*)?\.?([a-z]*)?\.?)";

<|endoftext|>


<commit_before>// Gruntfile.js
//
//

module.exports = function (grunt) {
  'use strict';

  // Force use of Unix newlines
  grunt.util.linefeed = '\n';

  // Project configuration
  grunt.initConfig({

    // Metadata
    pkg: grunt.file.readJSON('package.json'),

    // Banner task
    //
    banner: '/*!\n' +
              ' * cp-strap theme v<%= pkg.version %>\n' +
              ' * License MIT <%= grunt.template.today("yyyy") %> ABS-org\n' +
              ' */\n',

    // Less task
    //
    less: {
      compile: {
        files: {
          'dist/css/style.css': 'src/stylesheets/style.less'
        }
      }
    },

  });

  // Load multiple grunt tasks using globbing patterns
  require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});

};
<commit_msg>Add dist-stylesheets task<commit_after>// Gruntfile.js
//
//

module.exports = function (grunt) {
  'use strict';

  // Force use of Unix newlines
  grunt.util.linefeed = '\n';

  // Project configuration
  grunt.initConfig({

    // Metadata
    pkg: grunt.file.readJSON('package.json'),

    // Banner task
    //
    banner: '/*!\n' +
              ' * cp-strap theme v<%= pkg.version %>\n' +
              ' * License MIT <%= grunt.template.today("yyyy") %> ABS-org\n' +
              ' */\n',

    // Less task
    //
    less: {
      compile: {
        files: {
          'dist/css/style.css': 'src/stylesheets/style.less'
        }
      }
    },

  });

  // Load multiple grunt tasks using globbing patterns
  require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});

  // CSS distribution task
  grunt.registerTask('dist-stylesheets', ['less', 'usebanner']);

};
<|endoftext|>


<commit_before>export function methods(rationals) {
  const ops = rationals;

  class ImpreciseInteger {
    constructor(value) {
      this.value = value;
    }

    toString() {
      return this.value.toString() + '.0';
    }

    get __typeName() { return 'ImpreciseInteger'; }
  };

  const isInteger = x => {
    const s = Math.abs(x);
    return s % 1 == 0 && s + 1 > s;
  };

  const make = x => isInteger(x) ? new ImpreciseInteger(x) : x;

  const methods = { isReal: { Float: x => true } };

  for (const name of [ 'abs', 'floor', 'ceil', 'sqrt', 'round' ]) {
    methods[name] = {
      Float           : x => make(Math[name](x)),
      Integer         : x => make(Math[name](x)),
      ImpreciseInteger: x => make(Math[name](x.value))
    }
  }

  for (const [op, name] of [
    [x => x                , 'toJS'    ],
    [x => -x               , 'negative'],
    [x => (x > 0) - (x < 0), 'sgn'     ]
  ]) {
    methods[name] = {
      Float           : x => make(op(x)),
      Integer         : x => make(op(x)),
      ImpreciseInteger: x => make(op(x.value))
    }
  }

  for (const [op, name] of [
    [(x, y) => (x > y) - (x < y), 'cmp'  ],
    [(x, y) => x + y            , 'plus' ],
    [(x, y) => x - y            , 'minus'],
    [(x, y) => x * y            , 'times'],
    [(x, y) => x / y            , 'div'  ]
  ]) {
    methods[name] = {
      Float: {
        Float           : (x, y) => make(op(x, y)),
        Integer         : (x, y) => make(op(x, y)),
        ImpreciseInteger: (x, y) => make(op(x, y.value)),
        Fraction        : (x, y) => make(op(x, ops.toJS(y)))
      },
      Integer: {
        Float           : (x, y) => make(op(x, y)),
        ImpreciseInteger: (x, y) => make(op(x, y.value)),
        Fraction        : (x, y) => make(op(x, ops.toJS(y)))
      },
      ImpreciseInteger: {
        Float           : (x, y) => make(op(x.value, y)),
        Integer         : (x, y) => make(op(x.value, y)),
        ImpreciseInteger: (x, y) => make(op(x.value, y.value)),
        Fraction        : (x, y) => make(op(x, ops.toJS(y)))
      },
      Fraction: {
        Float           : (x, y) => make(op(ops.toJS(x), y)),
        Integer         : (x, y) => make(op(ops.toJS(x), y)),
        ImpreciseInteger: (x, y) => make(op(ops.toJS(x), y.value))
      }
    };
  }

  return methods;
}
<commit_msg>fix the toJS() operator for imprecise integers<commit_after>export function methods(rationals) {
  const ops = rationals;

  class ImpreciseInteger {
    constructor(value) {
      this.value = value;
    }

    toString() {
      return this.value.toString() + '.0';
    }

    get __typeName() { return 'ImpreciseInteger'; }
  };

  const isInteger = x => {
    const s = Math.abs(x);
    return s % 1 == 0 && s + 1 > s;
  };

  const make = x => isInteger(x) ? new ImpreciseInteger(x) : x;

  const methods = {
    isReal: {
      Float           : x => true,
      ImpreciseInteger: x => true
    },
    toJS: {
      Float           : x => x,
      ImpreciseInteger: x => x.value
    }
  };

  for (const name of [ 'abs', 'floor', 'ceil', 'sqrt', 'round' ]) {
    methods[name] = {
      Float           : x => make(Math[name](x)),
      Integer         : x => make(Math[name](x)),
      ImpreciseInteger: x => make(Math[name](x.value))
    }
  }

  for (const [op, name] of [
    [x => -x               , 'negative'],
    [x => (x > 0) - (x < 0), 'sgn'     ]
  ]) {
    methods[name] = {
      Float           : x => make(op(x)),
      Integer         : x => make(op(x)),
      ImpreciseInteger: x => make(op(x.value))
    }
  }

  for (const [op, name] of [
    [(x, y) => (x > y) - (x < y), 'cmp'  ],
    [(x, y) => x + y            , 'plus' ],
    [(x, y) => x - y            , 'minus'],
    [(x, y) => x * y            , 'times'],
    [(x, y) => x / y            , 'div'  ]
  ]) {
    methods[name] = {
      Float: {
        Float           : (x, y) => make(op(x, y)),
        Integer         : (x, y) => make(op(x, y)),
        ImpreciseInteger: (x, y) => make(op(x, y.value)),
        Fraction        : (x, y) => make(op(x, ops.toJS(y)))
      },
      Integer: {
        Float           : (x, y) => make(op(x, y)),
        ImpreciseInteger: (x, y) => make(op(x, y.value)),
        Fraction        : (x, y) => make(op(x, ops.toJS(y)))
      },
      ImpreciseInteger: {
        Float           : (x, y) => make(op(x.value, y)),
        Integer         : (x, y) => make(op(x.value, y)),
        ImpreciseInteger: (x, y) => make(op(x.value, y.value)),
        Fraction        : (x, y) => make(op(x, ops.toJS(y)))
      },
      Fraction: {
        Float           : (x, y) => make(op(ops.toJS(x), y)),
        Integer         : (x, y) => make(op(ops.toJS(x), y)),
        ImpreciseInteger: (x, y) => make(op(ops.toJS(x), y.value))
      }
    };
  }

  return methods;
}
<|endoftext|>


<commit_before>const MissingParamError = require('qnode-error').MissingParamError;
const RequestError = require('qnode-error').RequestError;

/**
 * API: add a rule.
 *
 * The rule should be in request body.
 * Example: {
 *      port:  8000,
 *      domain:  "github.com",
 *      name: "My rule name", // optional. assigned by default
 *      path: "/test", // optional. assigned to default path, if not specified
 *      method: "POST", // optional. assigned to default method, if not specified
 *      q: "ip='localhost'", // optional. assigned to default query, if not specified
 *      delay: 200, // optoinal. assigned to default delay, if not specified
 *      delayFix: 16, // optional. assigned to default delayFix, if not specified
 *      response:  // optional. merged with default response
 *      {
 *          status: 403,
 *          type: "application/json",
 *          template:  // exclusive with "body"
 *          {
 *              type: "mustache", // optional. if not specified, assigned to "ejs"
 *                                // if template is text, otherwise to default response.templateType
 *              text: "hi", // optional. if not specified, assigned to "template text not specified"
 *          },
 *          body: // exclusive with "template".
 *                // could be any JSON-stringify-able object, string, or primitive value,
 *                // "no response body specified", if not specified
 *          {
 *          }
 *      }
 * }
 */
class Where {

    init() {
        this._mockServerManager = this._beans.load('MockServerManager');
    }

    async validate(ctx) {
        const req = ctx.request;

        const rule = req.body;
        this._logger.info('rule is requested: %s', rule);

        let port = rule.port;
        if (!port) {
            if (!this._mockServerManager.defaultPort) throw new MissingParamError('port');
            port = this._mockServerManager.defaultPort;
        }

        const mockServer = this._mockServerManager.get(port);
        if (!mockServer) throw new RequestError('MOCK_SERVER_NOT_FOUND', port);

        let domain = rule.domain;
        if (!domain) {
            if (!mockServer.defaultDomain) throw new MissingParamError('domain');
            domain = mockServer.defaultDomain;
        }

        return { domain, rule, mockServer };
    }

    async execute(ctx, { domain, rule, mockServer }) {
        mockServer.putRule(domain, rule);
    }

}

Where.description = 'specifies how mock response when got specific request';
Where.method = 'post';

module.exports = Where;<commit_msg>Improve jsdoc for api/Where<commit_after>const MissingParamError = require('qnode-error').MissingParamError;
const RequestError = require('qnode-error').RequestError;

/**
 * API: add a rule.
 *
 * The rule should be in request body.
 * Example: {
 *      port:  8000, // optional. if has default port, then take it, otherwise, throws error
 *      domain:  "github.com", // optional. if has default domain, then take it, otherwise, throws error
 *      name: "My rule name", // optional. assigned by default
 *      path: "/test", // optional. assigned to default path, if not specified
 *      method: "POST", // optional. assigned to default method, if not specified
 *      q: "ip='localhost'", // optional. assigned to default query, if not specified
 *      delay: 200, // optoinal. assigned to default delay, if not specified
 *      delayFix: 16, // optional. assigned to default delayFix, if not specified
 *      response:  // optional. merged with default response
 *      {
 *          status: 403,
 *          type: "application/json",
 *          template:  // exclusive with "body"
 *          {
 *              type: "mustache", // optional. if not specified, assigned to "ejs"
 *                                // if template is text, otherwise to default response.templateType
 *              text: "hi", // optional. if not specified, assigned to "template text not specified"
 *          },
 *          body: // exclusive with "template".
 *                // could be any JSON-stringify-able object, string, or primitive value,
 *                // "no response body specified", if not specified
 *          {
 *          }
 *      }
 * }
 */
class Where {

    init() {
        this._mockServerManager = this._beans.load('MockServerManager');
    }

    async validate(ctx) {
        const req = ctx.request;

        const rule = req.body;
        this._logger.info('rule is requested: %s', rule);

        let port = rule.port;
        if (!port) {
            if (!this._mockServerManager.defaultPort) throw new MissingParamError('port');
            port = this._mockServerManager.defaultPort;
        }

        const mockServer = this._mockServerManager.get(port);
        if (!mockServer) throw new RequestError('MOCK_SERVER_NOT_FOUND', port);

        let domain = rule.domain;
        if (!domain) {
            if (!mockServer.defaultDomain) throw new MissingParamError('domain');
            domain = mockServer.defaultDomain;
        }

        return { domain, rule, mockServer };
    }

    async execute(ctx, { domain, rule, mockServer }) {
        mockServer.putRule(domain, rule);
    }

}

Where.description = 'specifies how mock response when got specific request';
Where.method = 'post';

module.exports = Where;<|endoftext|>


<commit_before>/*
* Auto Expanding Text Area (1.2.2)
* by Chrys Bader (www.chrysbader.com)
* chrysb@gmail.com
*
* Special thanks to:
* Jake Chapa - jake@hybridstudio.com
* John Resig - jeresig@gmail.com
*
* Copyright (c) 2008 Chrys Bader (www.chrysbader.com)
* Licensed under the GPL (GPL-LICENSE.txt) license.
*
*
* NOTE: This script requires jQuery to work. Download jQuery at www.jquery.com
*
*/

(function(jQuery) {

var self = null;

jQuery.fn.autogrow = function(o)
{
return this.each(function() {
new jQuery.autogrow(this, o);
});
};

    /**
* The autogrow object.
*
* @constructor
* @name jQuery.autogrow
* @param Object e The textarea to create the autogrow for.
* @param Hash o A set of key/value pairs to set as configuration properties.
* @cat Plugins/autogrow
*/

jQuery.autogrow = function (e, o)
{
this.options	= o || {};
this.dummy	= null;
this.interval	= null;
this.line_height	= this.options.lineHeight || parseInt(jQuery(e).css('line-height'));
this.min_height	= this.options.minHeight || parseInt(jQuery(e).css('min-height'));
this.max_height	= this.options.maxHeight || parseInt(jQuery(e).css('max-height'));;
this.textarea	= jQuery(e);

if(this.line_height == NaN)
this.line_height = 0;

// Only one textarea activated at a time, the one being used
this.init();
};

jQuery.autogrow.fn = jQuery.autogrow.prototype = {
    autogrow: '1.2.2'
  };

  jQuery.autogrow.fn.extend = jQuery.autogrow.extend = jQuery.extend;

jQuery.autogrow.fn.extend({

init: function() {
var self = this;
this.textarea.css({overflow: 'hidden', display: 'block'});
this.textarea.bind('focus', function() { self.startExpand() } ).bind('blur', function() { self.stopExpand() });
this.checkExpand();
},

startExpand: function() {
var self = this;
this.interval = window.setInterval(function() {self.checkExpand()}, 400);
},

stopExpand: function() {
clearInterval(this.interval);
},

checkExpand: function() {

if (this.dummy == null)
{
this.dummy = jQuery('

');
this.dummy.css({
'font-size' : this.textarea.css('font-size'),
'font-family': this.textarea.css('font-family'),
'width' : this.textarea.css('width'),
'padding' : this.textarea.css('padding'),
'line-height': this.line_height + 'px',
'overflow-x' : 'hidden',
'position' : 'absolute',
'top' : 0,
'left'	: -9999
}).appendTo('body');
}

// Strip HTML tags
var html = this.textarea.val().replace(/(<|>)/g, '');

// IE is different, as per usual
if ($.browser.msie)
{
html = html.replace(/\n/g, '
new');
}
else
{
html = html.replace(/\n/g, '
new');
}

if (this.dummy.html() != html)
{
this.dummy.html(html);

if (this.max_height > 0 && (this.dummy.height() + this.line_height > this.max_height))
{
this.textarea.css('overflow-y', 'auto');
}
else
{
this.textarea.css('overflow-y', 'hidden');
if (this.textarea.height() < this.dummy.height() + this.line_height || (this.dummy.height() < this.textarea.height()))
{
this.textarea.animate({height: (this.dummy.height() + this.line_height) + 'px'}, 100);
}
}
}
}

});
})(jQuery);
<commit_msg>ie plugin fix<commit_after>/*
* Auto Expanding Text Area (1.2.2)
* by Chrys Bader (www.chrysbader.com)
* chrysb@gmail.com
*
* Special thanks to:
* Jake Chapa - jake@hybridstudio.com
* John Resig - jeresig@gmail.com
*
* Copyright (c) 2008 Chrys Bader (www.chrysbader.com)
* Licensed under the GPL (GPL-LICENSE.txt) license.
*
*
* NOTE: This script requires jQuery to work. Download jQuery at www.jquery.com
*
*/

(function(jQuery) {

var self = null;

jQuery.fn.autogrow = function(o)
{
return this.each(function() {
new jQuery.autogrow(this, o);
});
};

    /**
* The autogrow object.
*
* @constructor
* @name jQuery.autogrow
* @param Object e The textarea to create the autogrow for.
* @param Hash o A set of key/value pairs to set as configuration properties.
* @cat Plugins/autogrow
*/

jQuery.autogrow = function (e, o)
{
this.options	= o || {};
this.dummy	= null;
this.interval	= null;
this.line_height	= this.options.lineHeight || parseInt(jQuery(e).css('line-height'));
this.min_height	= this.options.minHeight || parseInt(jQuery(e).css('min-height'));
this.max_height	= this.options.maxHeight || parseInt(jQuery(e).css('max-height'));;
this.textarea	= jQuery(e);

if(this.line_height == NaN)
this.line_height = 0;

// Only one textarea activated at a time, the one being used
this.init();
};

jQuery.autogrow.fn = jQuery.autogrow.prototype = {
    autogrow: '1.2.2'
  };

  jQuery.autogrow.fn.extend = jQuery.autogrow.extend = jQuery.extend;

jQuery.autogrow.fn.extend({

init: function() {
var self = this;
this.textarea.css({overflow: 'hidden', display: 'block'});
this.textarea.bind('focus', function() { self.startExpand() } ).bind('blur', function() { self.stopExpand() });
this.checkExpand();
},

startExpand: function() {
var self = this;
this.interval = window.setInterval(function() {self.checkExpand()}, 400);
},

stopExpand: function() {
clearInterval(this.interval);
},

checkExpand: function() {

if (this.dummy == null)
{
this.dummy = jQuery('

');
this.dummy.css({
'font-size' : this.textarea.css('font-size'),
'font-family': this.textarea.css('font-family'),
'width' : this.textarea.css('width'),
'padding' : this.textarea.css('padding'),
'line-height': this.line_height + 'px',
'overflow-x' : 'hidden',
'position' : 'absolute',
'top' : 0,
'left'	: -9999
}).appendTo('body');
}

// Strip HTML tags
var html = this.textarea.val().replace(/(<|>)/g, '');

// IE is different, as per usual
//if ($.browser.msie)
// jQuery > 1.8 fix
if (navigator.appName == 'Microsoft Internet Explorer')
{
html = html.replace(/\n/g, '
new');
}
else
{
html = html.replace(/\n/g, '
new');
}

if (this.dummy.html() != html)
{
this.dummy.html(html);

if (this.max_height > 0 && (this.dummy.height() + this.line_height > this.max_height))
{
this.textarea.css('overflow-y', 'auto');
}
else
{
this.textarea.css('overflow-y', 'hidden');
if (this.textarea.height() < this.dummy.height() + this.line_height || (this.dummy.height() < this.textarea.height()))
{
this.textarea.animate({height: (this.dummy.height() + this.line_height) + 'px'}, 100);
}
}
}
}

});
})(jQuery);
<|endoftext|>


<commit_before>"use strict";
var apingApp = angular.module('jtt_aping', [])
    .directive('aping', ['apingDefaultSettings', 'apingUtilityHelper', function (apingDefaultSettings, apingUtilityHelper) {
        return {
            restrict: 'E',
            replace: 'false',
            scope: {
                type: '@',
                items: '@',
                maxItems: '@',
                orderBy: '@',
                orderReverse: '@',
            },
            controller: ['$scope', function ($scope) {
                $scope.results = [];
                this.getAppSettings = function () {
                    return {
                        type: $scope.type || apingDefaultSettings.type,
                        items: $scope.items || apingDefaultSettings.items,
                        maxItems: $scope.maxItems || apingDefaultSettings.maxItems,
                        orderBy: $scope.orderBy || apingDefaultSettings.orderBy,
                        orderReverse: $scope.orderReverse || apingDefaultSettings.orderReverse,
                    };
                };
                this.concatToResults = function (_array) {
                    $scope.results = $scope.results.concat(_array);
                    if(this.getAppSettings().orderBy) {
                        $scope.results.sort(apingUtilityHelper.sortArrayByProperty(this.getAppSettings().orderBy));
                        if(this.getAppSettings().orderReverse === true || this.getAppSettings().orderReverse == "true") {
                            $scope.results.reverse();
                        }
                    }
                    if(this.getAppSettings().maxItems > 0 && $scope.results.length > this.getAppSettings().maxItems) {
                        $scope.results = $scope.results.splice(0,this.getAppSettings().maxItems);
                    }
                    $scope.$broadcast('resultMerged');
                };
                this.apply = function () {
                    $scope.$apply();
                }
            }],
            templateUrl: function (elem, attrs) {
                return attrs.templateUrl || apingDefaultSettings.templateUrl;
            }
        };
    }
    ]);<commit_msg>added new event listener "apiNG.load.more"<commit_after>"use strict";
var apingApp = angular.module('jtt_aping', [])
    .directive('aping', ['apingDefaultSettings', 'apingUtilityHelper', function (apingDefaultSettings, apingUtilityHelper) {
        return {
            restrict: 'E',
            replace: 'false',
            scope: {
                type: '@',
                items: '@',
                maxItems: '@',
                orderBy: '@',
                orderReverse: '@',
            },
            controller: ['$scope', function ($scope) {
                $scope.results = [];
                this.getAppSettings = function () {
                    return {
                        type: $scope.type || apingDefaultSettings.type,
                        items: $scope.items || apingDefaultSettings.items,
                        maxItems: $scope.maxItems || apingDefaultSettings.maxItems,
                        orderBy: $scope.orderBy || apingDefaultSettings.orderBy,
                        orderReverse: $scope.orderReverse || apingDefaultSettings.orderReverse,
                    };
                };
                this.concatToResults = function (_array) {
                    $scope.results = $scope.results.concat(_array);
                    if(this.getAppSettings().orderBy) {
                        $scope.results.sort(apingUtilityHelper.sortArrayByProperty(this.getAppSettings().orderBy));
                        if(this.getAppSettings().orderReverse === true || this.getAppSettings().orderReverse == "true") {
                            $scope.results.reverse();
                        }
                    }
                    if(this.getAppSettings().maxItems > 0 && $scope.results.length > this.getAppSettings().maxItems) {
                        $scope.results = $scope.results.splice(0,this.getAppSettings().maxItems);
                    }
                    $scope.$broadcast('resultMerged');
                };
                this.apply = function () {
                    $scope.$apply();
                };

                $scope.$on('apiNG.load.more', function(ev, args){
                    console.log('apiNG.load.more fired');
                    console.log(ev);
                    console.log(args);
                });
            }],
            templateUrl: function (elem, attrs) {
                return attrs.templateUrl || apingDefaultSettings.templateUrl;
            }
        };
    }
    ]);<|endoftext|>