<commit_before>'use strict';

const { expect } = require('chai');
const { Linter } = require('eslint');
const times = require('ramda/src/times');
const toPairs = require('ramda/src/toPairs');
const fromPairs = require('ramda/src/fromPairs');
const { runBenchmark, cpuSpeed, getNodeVersionMultiplier } = require('./measure');
const mochaPlugin = require('../');

const recommendedRules = mochaPlugin.configs.recommended.rules;

function lintManyFilesWithAllRecommendedRules({ numberOfFiles }) {
    const linter = new Linter();

    linter.defineRules(mochaPlugin.rules);

    const config = {
        rules: fromPairs(toPairs(recommendedRules).map(([ ruleName, ruleSettings ]) => {
            const [ , ruleNameWithoutPrefix ] = ruleName.split('/');

            return [ ruleNameWithoutPrefix, ruleSettings ];
        })),
        parserOptions: {
            ecmaVersion: 2018
        }
    };

    times((index) => {
        const codeToLint = `
            'use strict';
            const assert = require('assert');
            const sinon = require('sinon');
            const sut = require('./sut');

            describe('SUT ${index}', function () {
                let fooStub;

                before(() => {
                    fooStub = sinon.stub(sut, 'foo');
                });

                after(() => {
                    fooStub.restore();
                });

                beforeEach(function (done) {
                    done();
                });

                afterEach(() => {
                    fooStub.reset();
                });

                it('should work', async function () {
                    const bar = {};

                    await sut(bar);

                    assert(fooStub.callCount === 42);
                });

                describe('nested suite', async () => {
                    beforeEach(async function () {
                        await sleep(200);
                    });

                    xit('doesn’t work yet', function () {
                        sut();
                    });
                });

                context('more context', function () {
                    it.only('only here it works', () => {
                        sut();
                        assert(true);
                    });
                });
            });
        `;

        linter.verify(codeToLint, config);
    }, numberOfFiles);
}

describe('runtime', () => {
    it('should not take longer as the defined budget to lint many files with the recommended config', () => {
        const nodeVersionMultiplier = getNodeVersionMultiplier();
        const budget = 7000000 / cpuSpeed * nodeVersionMultiplier;

        const { medianDuration } = runBenchmark(() => {
            lintManyFilesWithAllRecommendedRules({ numberOfFiles: 350 });
        }, 5);

        expect(medianDuration).to.be.below(budget);
    });

    it('should not consume more memory as the defined budget to lint many files with the recommended config', () => {
        const budget = 3000000;

        const { medianMemory } = runBenchmark(() => {
            lintManyFilesWithAllRecommendedRules({ numberOfFiles: 350 });
        }, 5);

        expect(medianMemory).to.be.below(budget);
    });
});
<commit_msg>Enable all rules during runtime benchmark<commit_after>'use strict';

const { expect } = require('chai');
const { Linter } = require('eslint');
const times = require('ramda/src/times');
const toPairs = require('ramda/src/toPairs');
const fromPairs = require('ramda/src/fromPairs');
const {
    runBenchmark,
    cpuSpeed,
    getNodeVersionMultiplier
} = require('./measure');
const mochaPlugin = require('../');

const allRules = mochaPlugin.configs.all.rules;

function lintManyFilesWithAllRecommendedRules({ numberOfFiles }) {
    const linter = new Linter();

    linter.defineRules(mochaPlugin.rules);

    const config = {
        rules: fromPairs(
            toPairs(allRules).map(([ ruleName, ruleSettings ]) => {
                const [ , ruleNameWithoutPrefix ] = ruleName.split('/');

                return [ ruleNameWithoutPrefix, ruleSettings ];
            })
        ),
        parserOptions: {
            ecmaVersion: 2018
        }
    };

    times((index) => {
        const codeToLint = `
            'use strict';
            const assert = require('assert');
            const sinon = require('sinon');
            const sut = require('./sut');

            describe('SUT ${index}', function () {
                let fooStub;

                before(() => {
                    fooStub = sinon.stub(sut, 'foo');
                });

                after(() => {
                    fooStub.restore();
                });

                beforeEach(function (done) {
                    done();
                });

                afterEach(() => {
                    fooStub.reset();
                });

                it('should work', async function () {
                    const bar = {};

                    await sut(bar);

                    assert(fooStub.callCount === 42);
                });

                describe('nested suite', async () => {
                    beforeEach(async function () {
                        await sleep(200);
                    });

                    xit('doesn’t work yet', function () {
                        sut();
                    });
                });

                context('more context', function () {
                    it.only('only here it works', () => {
                        sut();
                        assert(true);
                    });
                });
            });
        `;

        linter.verify(codeToLint, config);
    }, numberOfFiles);
}

describe('runtime', () => {
    it('should not take longer as the defined budget to lint many files with the recommended config', () => {
        const nodeVersionMultiplier = getNodeVersionMultiplier();
        const budget = 7000000 / cpuSpeed * nodeVersionMultiplier;

        const { medianDuration } = runBenchmark(() => {
            lintManyFilesWithAllRecommendedRules({ numberOfFiles: 350 });
        }, 5);

        expect(medianDuration).to.be.below(budget);
    });

    it('should not consume more memory as the defined budget to lint many files with the recommended config', () => {
        const budget = 3000000;

        const { medianMemory } = runBenchmark(() => {
            lintManyFilesWithAllRecommendedRules({ numberOfFiles: 350 });
        }, 5);

        expect(medianMemory).to.be.below(budget);
    });
});
<|endoftext|>


<commit_before>// Copyright 2014-2020, University of Colorado Boulder

/**
 * ToggleSwitch is a switch for toggling between 2 values, similar to iOS' UISwitch, used in iOS `'Settings' app.
 *
 * Interaction behavior is as follows:
 * Drag the thumb to change the value, or click anywhere to toggle the value.
 * If you click without dragging, it's a toggle.
 * If you drag but don't cross the midpoint of the track, then it's a toggle.
 * If you drag past the midpoint of the track, releasing the thumb snaps to whichever end the thumb is closest to.
 * If you drag the thumb far enough to the side (outside of the switch), it will immediately toggle the model behavior.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 * @author Jonathan Olson (PhET Interactive Simulations)
 */

import Action from '../../axon/js/Action.js';
import Dimension2 from '../../dot/js/Dimension2.js';
import Utils from '../../dot/js/Utils.js';
import Vector2 from '../../dot/js/Vector2.js';
import Shape from '../../kite/js/Shape.js';
import merge from '../../phet-core/js/merge.js';
import DragListener from '../../scenery/js/listeners/DragListener.js';
import Node from '../../scenery/js/nodes/Node.js';
import Rectangle from '../../scenery/js/nodes/Rectangle.js';
import LinearGradient from '../../scenery/js/util/LinearGradient.js';
import EventType from '../../tandem/js/EventType.js';
import PhetioObject from '../../tandem/js/PhetioObject.js';
import Tandem from '../../tandem/js/Tandem.js';
import EnabledComponent from './EnabledComponent.js';
import sun from './sun.js';

// constants
const DEFAULT_SIZE = new Dimension2( 60, 30 );

/**
 * @mixes EnabledComponent
 */
class ToggleSwitch extends Node {

  /**
   * @param {Property.<*>} property
   * @param {*} leftValue - value when the switch is in the left position
   * @param {*} rightValue - value when the switch is in the right position
   * @param {Object} [options]
   */
  constructor( property, leftValue, rightValue, options ) {

    options = merge( {

      size: DEFAULT_SIZE, // if you want the thumb to be a circle, use width that is 2x height
      cursor: 'pointer',

      // controls the behavior of when model value changes occur during dragging (if any)
      // null (default: triggers model changes when thumb is dragged far enough to the side, similar to iOS)
      // true: triggers model changes whenever the thumb crosses sides
      // false: only trigger model changes until release
      toggleWhileDragging: null,

      // number of view-space units the drag needs to cover to be considered a "drag" instead of a "click/tap"
      dragThreshold: 3,

      // number of thumb-widths outside the normal range past where the model value will change
      toggleThreshold: 1,

      // thumb
      thumbFill: null, // {Color|string} thumb fill, default computed below
      thumbStroke: 'black',
      thumbTouchAreaXDilation: 8,
      thumbTouchAreaYDilation: 8,
      thumbMouseAreaXDilation: 0,
      thumbMouseAreaYDilation: 0,

      // track
      trackFillLeft: null, // {Color|string} track fill when property.value == leftValue, default computed below
      trackFillRight: null, // {Color|string} track fill when property.value == rightValue, default computed below
      trackStroke: 'black',

      // phet-io
      tandem: Tandem.REQUIRED,
      phetioEventType: EventType.USER,
      phetioReadOnly: PhetioObject.DEFAULT_OPTIONS.phetioReadOnly
    }, options );

    PhetioObject.mergePhetioComponentOptions( { visibleProperty: { phetioFeatured: true } }, options );

    // Default track fills
    let defaultTrackFill = null;
    if ( !options.trackFillLeft || !options.trackFillRight ) {
      defaultTrackFill = new LinearGradient( 0, 0, 0, options.size.height )
        .addColorStop( 0, 'rgb( 40, 40, 40 )' )
        .addColorStop( 1, 'rgb( 200, 200, 200 )' );
    }
    options.trackFillLeft = options.trackFillLeft || defaultTrackFill;
    options.trackFillRight = options.trackFillRight || defaultTrackFill;

    // Default thumb fill
    options.thumbFill = options.thumbFill ||
                        new LinearGradient( 0, 0, 0, options.size.height )
                          .addColorStop( 0, 'white' )
                          .addColorStop( 1, 'rgb( 200, 200, 200 )' );

    super();

    this.initializeEnabledComponent( options );

    const cornerRadius = options.size.height / 2;

    // track that the thumb slides in
    const trackNode = new Rectangle( 0, 0, options.size.width, options.size.height, cornerRadius, cornerRadius, {
      stroke: options.trackStroke,
      cachedPaints: [ options.trackFillLeft, options.trackFillRight ]
    } );
    this.addChild( trackNode );

    // thumb (aka knob)
    const thumbNode = new Rectangle( 0, 0, 0.5 * options.size.width, options.size.height, cornerRadius, cornerRadius, {
      fill: options.thumbFill,
      stroke: options.thumbStroke
    } );
    this.addChild( thumbNode );

    // thumb touchArea
    if ( options.thumbTouchAreaXDilation || options.thumbTouchAreaYDilation ) {
      thumbNode.touchArea = Shape.roundRect(
        -options.thumbTouchAreaXDilation, -options.thumbTouchAreaYDilation,
        ( 0.5 * options.size.width ) + ( 2 * options.thumbTouchAreaXDilation ),
        options.size.height + ( 2 * options.thumbTouchAreaYDilation ), cornerRadius, cornerRadius );
    }

    // thumb mouseArea
    if ( options.thumbMouseAreaXDilation || options.thumbMouseAreaYDilation ) {
      thumbNode.mouseArea = Shape.roundRect(
        -options.thumbMouseAreaXDilation, -options.thumbMouseAreaYDilation,
        ( 0.5 * options.size.width ) + ( 2 * options.thumbMouseAreaXDilation ),
        options.size.height + ( 2 * options.thumbMouseAreaYDilation ), cornerRadius, cornerRadius );
    }

    // move thumb and fill track
    const update = value => {
      if ( value === leftValue ) {
        thumbNode.left = 0;
        trackNode.fill = options.trackFillLeft;
      }
      else {
        thumbNode.right = options.size.width;
        trackNode.fill = options.trackFillRight;
      }
    };

    // sync with property, must be unlinked in dispose
    property.link( update );

    // thumb interactivity
    const dragThresholdSquared = options.dragThreshold * options.dragThreshold; // comparing squared magnitudes is a bit faster
    const accumulatedDelta = new Vector2( 0, 0 ); // stores how far we are from where our drag started, in our local coordinate frame
    let passedDragThreshold = false; // whether we have dragged far enough to be considered for "drag" behavior (pick closest side), or "tap" behavior (toggle)

    // Action that is performed when the switch is toggled.
    // Toggles the Property value and sends a phet-io message with the old and new values.
    const toggleAction = new Action( value => {
      property.value = value;
    }, {
      parameters: [ { validValues: [ leftValue, rightValue ], phetioPrivate: true } ],
      tandem: options.tandem.createTandem( 'toggleAction' ),
      phetioDocumentation: 'Occurs when the switch is toggled via user interaction',
      phetioReadOnly: options.phetioReadOnly,
      phetioEventType: EventType.USER
    } );

    // Gets the value that corresponds to the current thumb position.
    const thumbPositionToValue = () => ( thumbNode.centerX < trackNode.centerX ) ? leftValue : rightValue;

    const dragListener = new DragListener( {
      tandem: options.tandem.createTandem( 'dragListener' ),

      // Only touch to snag when moving the thumb (don't snag on the track itself),
      // but still support presses in the track to toggle the value.
      canStartPress: event => {
        if ( event.type === 'move' || event.type === 'enter' ) {
          return _.includes( event.trail.nodes, thumbNode );
        }
        else {
          return true;
        }
      },

      start: () => {
        // resets our state
        accumulatedDelta.setXY( 0, 0 ); // reset it mutably (less allocation)
        passedDragThreshold = false;
      },

      drag: ( event, listener ) => {

        accumulatedDelta.add( listener.modelDelta );
        passedDragThreshold = passedDragThreshold || ( accumulatedDelta.magnitudeSquared > dragThresholdSquared );

        // center the thumb on the pointer's x-coordinate if possible (but clamp to left and right ends)
        const viewPoint = listener.getCurrentTarget().globalToLocalPoint( event.pointer.point );
        const halfThumbWidth = thumbNode.width / 2;
        thumbNode.centerX = Utils.clamp( viewPoint.x, halfThumbWidth, options.size.width - halfThumbWidth );

        // whether the thumb is dragged outside of the possible range far enough beyond our threshold to potentially
        // trigger an immediate model change
        const isDraggedOutside = viewPoint.x < ( 1 - 2 * options.toggleThreshold ) * halfThumbWidth ||
                                 viewPoint.x > ( -1 + 2 * options.toggleThreshold ) * halfThumbWidth + options.size.width;

        // value that corresponds to the current thumb position
        const value = thumbPositionToValue();

        // track fill changes based on the thumb positions
        trackNode.fill = ( value === leftValue ) ? options.trackFillLeft : options.trackFillRight;

        if ( options.toggleWhileDragging === true || ( isDraggedOutside && options.toggleWhileDragging === null ) ) {

          // Only signify a change if the value actually changed to avoid duplicate messages in the PhET-iO Event
          // stream, see https://github.com/phetsims/phet-io/issues/369
          if ( property.value !== value ) {
            toggleAction.execute( value );
          }
        }
      },

      end: () => {

        // if moved past the threshold, choose value based on the side, otherwise just toggle
        const toggleValue = ( property.value === leftValue ? rightValue : leftValue );
        const value = passedDragThreshold ? thumbPositionToValue() : toggleValue;

        if ( property.value !== value ) {
          toggleAction.execute( value );
        }

        // update the thumb location (sanity check that it's here, only needs to be run if passedDragThreshold===true)
        update( value );
      }
    } );
    this.addInputListener( dragListener );

    this.mutate( options );

    // Add a link to the Property that this switch controls
    this.addLinkedElement( property, {
      tandem: options.tandem.createTandem( 'property' )
    } );

    // @private
    this.disposeToggleSwitch = () => {
      property.unlink( update );
      toggleAction.dispose();
      dragListener.dispose();
      this.disposeEnabledComponent();
    };
  }

  /**
   * @public
   * @override
   */
  dispose() {
    this.disposeToggleSwitch();
    super.dispose();
  }
}

EnabledComponent.mixInto( ToggleSwitch );

sun.register( 'ToggleSwitch', ToggleSwitch );
export default ToggleSwitch;<commit_msg>revert previous commit<commit_after>// Copyright 2014-2020, University of Colorado Boulder

/**
 * ToggleSwitch is a switch for toggling between 2 values, similar to iOS' UISwitch, used in iOS `'Settings' app.
 *
 * Interaction behavior is as follows:
 * Drag the thumb to change the value, or click anywhere to toggle the value.
 * If you click without dragging, it's a toggle.
 * If you drag but don't cross the midpoint of the track, then it's a toggle.
 * If you drag past the midpoint of the track, releasing the thumb snaps to whichever end the thumb is closest to.
 * If you drag the thumb far enough to the side (outside of the switch), it will immediately toggle the model behavior.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 * @author Jonathan Olson (PhET Interactive Simulations)
 */

import Action from '../../axon/js/Action.js';
import Dimension2 from '../../dot/js/Dimension2.js';
import Utils from '../../dot/js/Utils.js';
import Vector2 from '../../dot/js/Vector2.js';
import Shape from '../../kite/js/Shape.js';
import merge from '../../phet-core/js/merge.js';
import DragListener from '../../scenery/js/listeners/DragListener.js';
import Node from '../../scenery/js/nodes/Node.js';
import Rectangle from '../../scenery/js/nodes/Rectangle.js';
import LinearGradient from '../../scenery/js/util/LinearGradient.js';
import EventType from '../../tandem/js/EventType.js';
import PhetioObject from '../../tandem/js/PhetioObject.js';
import Tandem from '../../tandem/js/Tandem.js';
import EnabledComponent from './EnabledComponent.js';
import sun from './sun.js';

// constants
const DEFAULT_SIZE = new Dimension2( 60, 30 );

/**
 * @mixes EnabledComponent
 */
class ToggleSwitch extends Node {

  /**
   * @param {Property.<*>} property
   * @param {*} leftValue - value when the switch is in the left position
   * @param {*} rightValue - value when the switch is in the right position
   * @param {Object} [options]
   */
  constructor( property, leftValue, rightValue, options ) {

    options = merge( {

      size: DEFAULT_SIZE, // if you want the thumb to be a circle, use width that is 2x height
      cursor: 'pointer',

      // controls the behavior of when model value changes occur during dragging (if any)
      // null (default: triggers model changes when thumb is dragged far enough to the side, similar to iOS)
      // true: triggers model changes whenever the thumb crosses sides
      // false: only trigger model changes until release
      toggleWhileDragging: null,

      // number of view-space units the drag needs to cover to be considered a "drag" instead of a "click/tap"
      dragThreshold: 3,

      // number of thumb-widths outside the normal range past where the model value will change
      toggleThreshold: 1,

      // thumb
      thumbFill: null, // {Color|string} thumb fill, default computed below
      thumbStroke: 'black',
      thumbTouchAreaXDilation: 8,
      thumbTouchAreaYDilation: 8,
      thumbMouseAreaXDilation: 0,
      thumbMouseAreaYDilation: 0,

      // track
      trackFillLeft: null, // {Color|string} track fill when property.value == leftValue, default computed below
      trackFillRight: null, // {Color|string} track fill when property.value == rightValue, default computed below
      trackStroke: 'black',

      // phet-io
      tandem: Tandem.REQUIRED,
      phetioEventType: EventType.USER,
      phetioReadOnly: PhetioObject.DEFAULT_OPTIONS.phetioReadOnly
    }, options );

    PhetioObject.mergePhetioComponentOptions( { visibleProperty: { phetioFeatured: true } }, options );

    // Default track fills
    let defaultTrackFill = null;
    if ( !options.trackFillLeft || !options.trackFillRight ) {
      defaultTrackFill = new LinearGradient( 0, 0, 0, options.size.height )
        .addColorStop( 0, 'rgb( 40, 40, 40 )' )
        .addColorStop( 1, 'rgb( 200, 200, 200 )' );
    }
    options.trackFillLeft = options.trackFillLeft || defaultTrackFill;
    options.trackFillRight = options.trackFillRight || defaultTrackFill;

    // Default thumb fill
    options.thumbFill = options.thumbFill ||
                        new LinearGradient( 0, 0, 0, options.size.height )
                          .addColorStop( 0, 'white' )
                          .addColorStop( 1, 'rgb( 200, 200, 200 )' );

    super();

    this.initializeEnabledComponent( options );

    const cornerRadius = options.size.height / 2;

    // track that the thumb slides in
    const trackNode = new Rectangle( 0, 0, options.size.width, options.size.height, cornerRadius, cornerRadius, {
      stroke: options.trackStroke,
      cachedPaints: [ options.trackFillLeft, options.trackFillRight ]
    } );
    this.addChild( trackNode );

    // thumb (aka knob)
    const thumbNode = new Rectangle( 0, 0, 0.5 * options.size.width, options.size.height, cornerRadius, cornerRadius, {
      fill: options.thumbFill,
      stroke: options.thumbStroke
    } );
    this.addChild( thumbNode );

    // thumb touchArea
    if ( options.thumbTouchAreaXDilation || options.thumbTouchAreaYDilation ) {
      thumbNode.touchArea = Shape.roundRect(
        -options.thumbTouchAreaXDilation, -options.thumbTouchAreaYDilation,
        ( 0.5 * options.size.width ) + ( 2 * options.thumbTouchAreaXDilation ),
        options.size.height + ( 2 * options.thumbTouchAreaYDilation ), cornerRadius, cornerRadius );
    }

    // thumb mouseArea
    if ( options.thumbMouseAreaXDilation || options.thumbMouseAreaYDilation ) {
      thumbNode.mouseArea = Shape.roundRect(
        -options.thumbMouseAreaXDilation, -options.thumbMouseAreaYDilation,
        ( 0.5 * options.size.width ) + ( 2 * options.thumbMouseAreaXDilation ),
        options.size.height + ( 2 * options.thumbMouseAreaYDilation ), cornerRadius, cornerRadius );
    }

    // move thumb and fill track
    const update = value => {
      if ( value === leftValue ) {
        thumbNode.left = 0;
        trackNode.fill = options.trackFillLeft;
      }
      else {
        thumbNode.right = options.size.width;
        trackNode.fill = options.trackFillRight;
      }
    };

    // sync with property, must be unlinked in dispose
    property.link( update );

    // thumb interactivity
    const dragThresholdSquared = options.dragThreshold * options.dragThreshold; // comparing squared magnitudes is a bit faster
    const accumulatedDelta = new Vector2( 0, 0 ); // stores how far we are from where our drag started, in our local coordinate frame
    let passedDragThreshold = false; // whether we have dragged far enough to be considered for "drag" behavior (pick closest side), or "tap" behavior (toggle)

    // Action that is performed when the switch is toggled.
    // Toggles the Property value and sends a phet-io message with the old and new values.
    const toggleAction = new Action( value => {
      property.value = value;
    }, {
      parameters: [ { validValues: [ leftValue, rightValue ], phetioPrivate: true } ],
      tandem: options.tandem.createTandem( 'toggleAction' ),
      phetioDocumentation: 'Occurs when the switch is toggled via user interaction',
      phetioReadOnly: options.phetioReadOnly,
      phetioEventType: EventType.USER
    } );

    // Gets the value that corresponds to the current thumb position.
    const thumbPositionToValue = () => ( thumbNode.centerX < trackNode.centerX ) ? leftValue : rightValue;

    const dragListener = new DragListener( {
      tandem: options.tandem.createTandem( 'dragListener' ),

      // Only touch to snag when moving the thumb (don't snag on the track itself),
      // but still support presses in the track to toggle the value.
      canStartPress: event => {
        if ( event.type === 'move' || event.type === 'enter' ) {
          return _.includes( event.trail.nodes, thumbNode );
        }
        else {
          return true;
        }
      },

      start: () => {
        // resets our state
        accumulatedDelta.setXY( 0, 0 ); // reset it mutably (less allocation)
        passedDragThreshold = false;
      },

      drag: ( event, listener ) => {

        accumulatedDelta.add( listener.modelDelta );
        passedDragThreshold = passedDragThreshold || ( accumulatedDelta.magnitudeSquared > dragThresholdSquared );

        // center the thumb on the pointer's x-coordinate if possible (but clamp to left and right ends)
        const viewPoint = listener.getCurrentTarget().globalToLocalPoint( event.pointer.point );
        const halfThumbWidth = thumbNode.width / 2;
        thumbNode.centerX = Utils.clamp( viewPoint.x, halfThumbWidth, options.size.width - halfThumbWidth );

        // whether the thumb is dragged outside of the possible range far enough beyond our threshold to potentially
        // trigger an immediate model change
        const isDraggedOutside = viewPoint.x < ( 1 - 2 * options.toggleThreshold ) * halfThumbWidth ||
                                 viewPoint.x > ( -1 + 2 * options.toggleThreshold ) * halfThumbWidth + options.size.width;

        // value that corresponds to the current thumb position
        const value = thumbPositionToValue();

        // track fill changes based on the thumb positions
        trackNode.fill = ( value === leftValue ) ? options.trackFillLeft : options.trackFillRight;

        if ( options.toggleWhileDragging === true || ( isDraggedOutside && options.toggleWhileDragging === null ) ) {

          // Only signify a change if the value actually changed to avoid duplicate messages in the PhET-iO Event
          // stream, see https://github.com/phetsims/phet-io/issues/369
          if ( property.value !== value ) {
            toggleAction.execute( value );
          }
        }
      },

      end: () => {

        // if moved past the threshold, choose value based on the side, otherwise just toggle
        const toggleValue = ( property.value === leftValue ? rightValue : leftValue );
        const value = passedDragThreshold ? thumbPositionToValue() : toggleValue;

        if ( property.value !== value ) {
          toggleAction.execute( value );
        }

        // update the thumb location (sanity check that it's here, only needs to be run if passedDragThreshold===true)
        update( value );
      }
    } );
    this.addInputListener( dragListener );

    this.mutate( options );

    // Add a link to the Property that this switch controls
    this.addLinkedElement( property, {
      tandem: options.tandem.createTandem( 'property' )
    } );

    // @private
    this.disposeToggleSwitch = () => {
      property.unlink( update );
      toggleAction.dispose();
      dragListener.dispose();
    };
  }

  /**
   * @public
   * @override
   */
  dispose() {
    this.disposeToggleSwitch();
    this.disposeEnabledComponent();
    super.dispose();
  }
}

EnabledComponent.mixInto( ToggleSwitch );

sun.register( 'ToggleSwitch', ToggleSwitch );
export default ToggleSwitch;<|endoftext|>


<commit_before>/*global module: false, require: false, console: false */
'use strict';

var React = require('react');
var _ = require('underscore');
var DataTable = require('react-data-components').DataTable;
var DataGrid = require('react-datagrid');
require('react-datagrid/index.css');
require('react-data-components/css/table-twbs.css');

var VariantTable = React.createClass({
	onSortChange: function (info) {
		var [{prop}] = info, {data} = this.state;
		this.setState({data: _.sortBy(data, r => r[prop])});
	},
	render: function () {
		var {data, ...opts} = this.props,
			columns = [
				{title: 'Gene', prop: 'Gene symbol'},
				{title: '  HGVS  ', prop: 'HGVS'},
				{title: 'Pathogenicity', prop: 'Clinical significance'},
				{title: 'Allele origin', prop: 'Allele origin'},
				{title: 'CVA', prop: 'ClinVarAccession'}
			];
		return (
			<DataTable
				{...opts}
				columns={columns}
				initialData={data}
				initialPageLength={5}
                initialSortBy={{ title: 'Gene', prop: 'Gene', order: 'descending' }}
                pageLengthOptions={[ 10, 50, 100 ]}
                keys={['id']}
            />
		);
	}
});

module.exports = VariantTable;
<commit_msg>add initial page size to 10<commit_after>/*global module: false, require: false, console: false */
'use strict';

var React = require('react');
var _ = require('underscore');
var DataTable = require('react-data-components').DataTable;
var DataGrid = require('react-datagrid');
require('react-datagrid/index.css');
require('react-data-components/css/table-twbs.css');

var VariantTable = React.createClass({
	onSortChange: function (info) {
		var [{prop}] = info, {data} = this.state;
		this.setState({data: _.sortBy(data, r => r[prop])});
	},
	render: function () {
		var {data, ...opts} = this.props,
			columns = [
				{title: 'Gene', prop: 'Gene symbol'},
				{title: '  HGVS  ', prop: 'HGVS'},
				{title: 'Pathogenicity', prop: 'Clinical significance'},
				{title: 'Allele origin', prop: 'Allele origin'},
				{title: 'CVA', prop: 'ClinVarAccession'}
			];
		return (
			<DataTable
				{...opts}
				columns={columns}
				initialData={data}
				initialPageLength={10}
                initialSortBy={{ title: 'Gene', prop: 'Gene', order: 'descending' }}
                pageLengthOptions={[ 10, 50, 100 ]}
                keys={['id']}
            />
		);
	}
});

module.exports = VariantTable;
<|endoftext|>


<commit_before>// Copyright 2014-2017, University of Colorado Boulder

/**
 * XY Data Series
 *
 * @author Sam Reid
 * @author Aadish Gupta
 */
define( function( require ) {
  'use strict';

  // modules
  var Emitter = require( 'AXON/Emitter' );
  var griddle = require( 'GRIDDLE/griddle' );
  var inherit = require( 'PHET_CORE/inherit' );

  // for the uniqueId, see this.uniqueId for information
  var instanceCount = 0;

  function XYDataSeries( options ) {

    options = _.extend( {
      color: 'black',
      lineWidth: 1,
      // size of array to initially allocate for the series, specify expected max in options for best performance
      initialSize: 1000
    }, options );

    // @public (read-only) - each instance is given a uniqueId so that it can be mapped to an XYDataSeriesNode.
    // TODO: When we can use native maps, this should no longer be necessary, see https://github.com/phetsims/tasks/issues/992
    this.uniqueId = instanceCount++;

    this.cleared = new Emitter(); // @public, event emitted when the series is cleared
    this.color = options.color; // @public
    this.lineWidth = options.lineWidth; // @public
    this.listeners = []; // @private

    this.xPoints = new Array( options.initialSize ); // @private
    this.yPoints = new Array( options.initialSize ); // @private

    this.dataSeriesLength = 0; // @private, index to next available slot
  }

  griddle.register( 'XYDataSeries', XYDataSeries );

  return inherit( Object, XYDataSeries, {

    addDataSeriesListener: function( listener ) {
      this.listeners.push( listener );
    },

    removeDataSeriesListener: function( listener ) {
      var index = this.listeners.indexOf( listener );
      if ( index !== -1 ) {
        this.listeners.splice( index, 1 );
      }
    },

    addPoint: function( x, y ) {

      var index = this.dataSeriesLength;

      // point to the next slot
      this.dataSeriesLength++;

      // store the data
      this.xPoints[ index ] = x;
      this.yPoints[ index ] = y;

      // notify listeners - note that the previous data series values can be undefined in the notification
      for ( var i = 0; i < this.listeners.length; i++ ) {
        this.listeners[ i ]( x, y, this.xPoints[ index - 1 ], this.yPoints[ index - 1 ] );
      }

    },

    clear: function() {
      this.dataSeriesLength = 0;
      this.cleared.emit();
    },

    getX: function( index ) {
      if ( index > this.dataSeriesLength - 1 ) {
        throw new Error( 'No Data Point Exist at this index ' + index );
      }
      return this.xPoints[ index ];
    },

    getY: function( index ) {
      if ( index > this.dataSeriesLength - 1 ) {
        throw new Error( 'No Data Point Exist at this index ' + index );
      }
      return this.yPoints[ index ];
    },

    /**
     * @public - getter for the length.  DON'T CHANGE THIS TO AN ES5 GETTER.  That's what is was originally, and it
     * caused poor performance on iPad, see https://github.com/phetsims/neuron/issues/55.
     */
    getLength: function() {
      return this.dataSeriesLength;
    },

    /**
     * @public - getter for all the x points
     */
    getXPoints: function() {
      return this.xPoints;
    },

    /**
     * @public - getter for all the x points
     */
    getYPoints: function() {
      return this.yPoints;
    }

  } );
} );<commit_msg>add removePoint and removePoints functions to XYDataSeries, see #43<commit_after>// Copyright 2014-2017, University of Colorado Boulder

/**
 * XY Data series for a plot. When added to an XYPlot, adding points to the series will allow points to be drawn
 * on the XYPlot.
 *
 * @author Sam Reid
 * @author Aadish Gupta
 * @author Jesse Greenberg
 */
define( function( require ) {
  'use strict';

  // modules
  var Emitter = require( 'AXON/Emitter' );
  var griddle = require( 'GRIDDLE/griddle' );
  var inherit = require( 'PHET_CORE/inherit' );

  // for the uniqueId, see this.uniqueId for information
  var instanceCount = 0;

  function XYDataSeries( options ) {

    options = _.extend( {
      color: 'black',
      lineWidth: 1,

      // size of array to initially allocate for the series, specify expected max in options for best performance
      initialSize: 1000
    }, options );

    // @public (read-only) - each instance is given a uniqueId so that it can be mapped to an XYDataSeriesNode.
    // TODO: When we can use native maps, this should no longer be necessary, see https://github.com/phetsims/tasks/issues/992
    this.uniqueId = instanceCount++;

    this.cleared = new Emitter(); // @public, event emitted when the series is cleared
    this.color = options.color; // @public
    this.lineWidth = options.lineWidth; // @public
    this.listeners = []; // @private

    this.xPoints = new Array( options.initialSize ); // @private
    this.yPoints = new Array( options.initialSize ); // @private

    this.dataSeriesLength = 0; // @private, index to next available slot
  }

  griddle.register( 'XYDataSeries', XYDataSeries );

  return inherit( Object, XYDataSeries, {

    addDataSeriesListener: function( listener ) {
      this.listeners.push( listener );
    },

    removeDataSeriesListener: function( listener ) {
      var index = this.listeners.indexOf( listener );
      if ( index !== -1 ) {
        this.listeners.splice( index, 1 );
      }
    },

    addPoint: function( x, y ) {

      var index = this.dataSeriesLength;

      // point to the next slot
      this.dataSeriesLength++;

      // store the data
      this.xPoints[ index ] = x;
      this.yPoints[ index ] = y;

      this.notifyListeners( index );
    },

    // notify listeners - note that the previous data series values can be undefined in the notification
    notifyListeners: function( index ) {
      const lastIndex = this.dataSeriesLength;
      const lastX = this.xPoints[ lastIndex - 1 ];
      const lastY = this.yPoints[ lastIndex - 1 ];

      const pointBeforeLastX = this.xPoints[ lastIndex - 2 ];
      const pointBeforeLastY = this.yPoints[ lastIndex - 2 ];

      // notify listeners - note that the previous data series values can be undefined in the notification
      for ( var i = 0; i < this.listeners.length; i++ ) {
        this.listeners[ i ]( lastX, lastY, pointBeforeLastX, pointBeforeLastY );
      }
    },

    /**
     * Remove the last point from both x and y data lists. xPoints and yPoints have preallocated sizes, so instead of
     * splicing, we fill in the points at index with 0.
     * @public
     *
     * @param {number} index
     */
    removePoint: function( index ) {

      // previous slot
      this.dataSeriesLength--;

      // remove the point from the array, then splice to end of array to preserve array length for performance during
      // addPoint
      this.xPoints = this.xPoints.concat( this.xPoints.splice( index, 1 ) );
      this.yPoints = this.yPoints.concat( this.yPoints.splice( index, 1 ) );

      this.notifyListeners( this.dataSeriesLength );
    },

    /**
     * Fast way to remove a number of points at once for the series. Listeners are only called once after all points
     * between startIndex and endIndex are removed.
     * @public
     *
     * @param {number} startIndex - index of first point to remove
     * @param {number} endIndex - index of last point to remove
     */
    removePoints: function( startIndex, endIndex ) {
      assert && assert( startIndex < this.xPoints.length, 'startIndex larger than xPoints length' );
      assert && assert( startIndex < this.yPoints.length, 'startIndex larger than yPoints length' );
      assert && assert( endIndex < this.xPoints.length, 'endIndex larger than xPoints length' );
      assert && assert( endIndex < this.yPoints.length, 'endIndex larger than yPoints length' );
      assert && assert( endIndex > startIndex, 'startIndex larger than end index' );

      // just used for sanity checks
      const lengthBeforeRemoval = this.xPoints.length;

      this.xPoints = this.xPoints.concat( this.xPoints.splice( startIndex, endIndex ) );
      this.yPoints = this.yPoints.concat( this.yPoints.splice( startIndex, endIndex ) );

      const numberToRemove = endIndex - startIndex;
      this.dataSeriesLength -= numberToRemove;

      // sanity checks
      assert && assert( this.xPoints.length === this.yPoints.length, 'x and y data should be of the same length' );
      assert && assert( this.xPoints.length === lengthBeforeRemoval, 'data arrays should not change size during point removal' );

      this.notifyListeners( this.dataSeriesLength );
    },

    clear: function() {
      this.dataSeriesLength = 0;
      this.cleared.emit();
    },

    getX: function( index ) {
      if ( index > this.dataSeriesLength - 1 ) {
        throw new Error( 'No Data Point Exist at this index ' + index );
      }
      return this.xPoints[ index ];
    },

    getY: function( index ) {
      if ( index > this.dataSeriesLength - 1 ) {
        throw new Error( 'No Data Point Exist at this index ' + index );
      }
      return this.yPoints[ index ];
    },

    /**
     * @public - getter for the length.  DON'T CHANGE THIS TO AN ES5 GETTER.  That's what is was originally, and it
     * caused poor performance on iPad, see https://github.com/phetsims/neuron/issues/55.
     */
    getLength: function() {
      return this.dataSeriesLength;
    },

    /**
     * @public - getter for all the x points
     */
    getXPoints: function() {
      return this.xPoints;
    },

    /**
     * @public - getter for all the x points
     */
    getYPoints: function() {
      return this.yPoints;
    }

  } );
} );<|endoftext|>


<commit_before>var current = $('.current li');
var arrow_up = $('up-arrow');
var arrow_down = $('down-arrow');
var disp = "flex";
var offset_s = $(window).height()*0.1;
var nav;

function show_nav(new_curr){

      current.css("display","none");
      current = new_curr;
      current.css("display","block");
}

function goDown(){
   if (scrollT < 0) scrollT = 1;
      scrollT+=1;
      if(win_width<600){

        if(scrollT === 3){
           scrollT = 4;
        }

      }

      if(!activelyScrolling) {
        scrollDownTo(scrollT);
      }
}

function goUp(){
      if (scrollT > 9) scrollT = 9;
      if (scrollT <0) scrollT = 2;
      scrollT-=1;
      if(win_width<600){

          if(scrollT === 3){
             scrollT = 2;
          }

      }
      if(!activelyScrolling){
          scrollDownTo(scrollT);
      }
}

function showStuff(){
      nav.css("opacity","1");
      $('.arrow-nav-container').css("display","block");
}

function scrollDownTo(t){
    var html =  $('html,body');

    if(flag_m == 1){
        activelyScrolling = true;
        switch(t){

           case 1:
               html.animate({scrollTop: $('#home').offset().top}, 1000);
               scrollT = 1;

               setTimeout(function(){
                nav.css("opacity","0");
               current.css("display","none");
               $('.arrow-nav-container').css("display","none");
               },500);

                break;
          case 2:
            scrollT = 2;
            arrow_down.css("display",disp);
            if($(window).width()<550){
                html.animate({scrollTop: $('.about-container').offset().top - offset_s}, 500);
            }
            else{
                html.animate({scrollTop: $('#about').offset().top - offset_s}, 500);
            }
            setTimeout(function(){
                showStuff();
                nav.css("opacity","1");
                show_nav(aboutChild);
            },500);
            break;

          case 3:
            scrollT = 3;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('#about').offset().top + $(window).height()-offset_s}, 500);
            current.css("display","none");
            current = aboutChild;
            current.css("display","block");
            showStuff();
            break;

          case 4:
            scrollT = 4;
            arrow_down.css("display",disp);
            $('.slider').slider('start');
            html.animate({scrollTop: $('.tech-expo').offset().top -offset_s}, 500);
            current.css("display","none");
            current = aboutChild;
            current.css("display","block");
            showStuff();
            show_nav(techChild);
            break;

          case 5:
            scrollT = 5;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('.events').offset().top -offset_s}, 500);
            showStuff();
            show_nav(eventChild);
            break;
          case 6:
            scrollT = 6;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('.speakers-container').offset().top-offset_s}, 500);
            showStuff();
            show_nav(speakerChild);
            break;
          case 7:
            scrollT = 7;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('#parvah').offset().top - offset_s}, 500);
            showStuff();
            show_nav(parvaahChild);
            break;
          case 8:
            scrollT = 8;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('#sponsors').offset().top - offset_s}, 500);
            showStuff();
            show_nav(sponsorChild);
            break;
          case 9:
            scrollT = 9;
            showStuff();
            arrow_down.css("display","none");
            show_nav(contactChild);
            html.animate({scrollTop: $('#contact').offset().top - offset_s}, 500);
             break;
        }
  }
  else{
        html.animate({scrollTop: $('#events').offset().top - offset_s}, 5);
        scrollT-=1;
  }

  setTimeout(function(){
        activelyScrolling = false; scrollT =t;
  },500);
}
$(document).ready(function(){

      nav = $('nav');
  		aboutChild = $('.current li:nth-child(2)');
      techChild = $('.current li:nth-child(3)')
      eventChild = $('.current li:nth-child(4)');
      speakerChild = $('.current li:nth-child(5)')
      parvaahChild = $('.current li:nth-child(6)');
      sponsorChild = $('.current li:nth-child(7)');
      contactChild = $('.current li:nth-child(8)');
      arrow_up = $('.up-arrow');
      arrow_down = $('.down-arrow');
      current = $('.current li');
      arrow_up = $('.up-arrow');
      arrow_down = $('.down-arrow');

      scrollDownTo(1);

      if ( win.width() > 767) {
            var s = skrollr.init();
      }

      $(".button-collapse").sideNav({
            closeOnClick: true // Closes side-nav on <a> clicks, useful for Angular/Meteor
      });

      $(".parallax").parallax();

      $(".modal-trigger").leanModal({
            dismissible: true, // Modal can be dismissed by clicking outside of the modal
            opacity: 0.5, // Opacity of modal background
            in_duration: 300, // Transition in duration
            out_duration: 200, // Transition out duration
            starting_top: "0%", // Starting top style attribute
            ending_top: "0%", // Ending top style attribute
            ready: function() { $("#modal1").toggleClass("slideOutUp");}, // Callback for Modal open
            complete: function(){$("#modal1").toggleClass("slideOutUp");}// Callback for Modal close
      });

      $('.collapsible').collapsible({});

      $(".slider").slider({
            full_width: true,
            height: (win_height*0.87
      });
      $('.slider2').slider({
          full_width: true,
          height: win_height*0.9
});
      $(".slider").slider("pause");

});

//om click stuff

$(".viewMore").on("click",function(){
        $(".sponsors").toggleClass("more");
        $("#lastYear .container").toggleClass("more");
        $("#thisYear .container").toggleClass("more");
        $("#sponsors").toggleClass("check");
        if($("#sponsors").hasClass("check")){
              flag_m1 = 0;
              $(".viewMore h5").text("View Less");
        }
        else{
              flag_m1 = 1;
              $(".viewMore h5").text("View More");

        }
});

 $(window).on('resize',function(){
    if ( $(window).width() > 767) {
          var s = skrollr.init();
    }

    if(win_width<550){
          offset_s = win_width*0.1;
          $('.about-container').css('display','block');
          $('.social-mobile').css('display','block');
    }
    else{
          $('.social-mobile').css('display','none');
          $('.about-container').css('display','none');
    }

});

//scrolling stuff

$(".down-arrow").on("click",function(){
        goDown();
        return false;
});
$(".up-arrow").on("click",function(){
        goUp();
        return false;
});

 $("#abhiyantriki-logo").on("click",function(){
        scrollDownTo(1);
});

$(".brand-logo").on("click",function(){

        scrollDownTo(1);
});

 $(document).keydown(function(e){
        if (e.keyCode == 40){
               goDown();
               return false
        }
        else if (e.keyCode == 38){

                goUp();
                return false;
        }
});

//mouse wheel
win.bind("mousewheel", function(e){

       if(flag_m1==1){
               if(e.originalEvent.wheelDelta < -119) {

                  goDown();
                  return false;
                }
                else if (e.originalEvent.wheelDelta > 119) {

                  goUp();
                  return false;

              }
       }
});

 //touch pad  scroll

win.bind("wheel", function(e){

      if(flag_m1==1){
             if(e.originalEvent.deltaY < -0.2) {

                goUp();
                return false;
              }
              else if (e.originalEvent.deltaY >=0.2) {

                goDown();
                return false;

              }
      }

});<commit_msg>Final 2.3<commit_after>var current = $('.current li');
var arrow_up = $('up-arrow');
var arrow_down = $('down-arrow');
var disp = "flex";
var offset_s = $(window).height()*0.1;
var nav;

function show_nav(new_curr){

      current.css("display","none");
      current = new_curr;
      current.css("display","block");
}

function goDown(){
   if (scrollT < 0) scrollT = 1;
      scrollT+=1;
      if(win_width<600){

        if(scrollT === 3){
           scrollT = 4;
        }

      }

      if(!activelyScrolling) {
        scrollDownTo(scrollT);
      }
}

function goUp(){
      if (scrollT > 9) scrollT = 9;
      if (scrollT <0) scrollT = 2;
      scrollT-=1;
      if(win_width<600){

          if(scrollT === 3){
             scrollT = 2;
          }

      }
      if(!activelyScrolling){
          scrollDownTo(scrollT);
      }
}

function showStuff(){
      nav.css("opacity","1");
      $('.arrow-nav-container').css("display","block");
}

function scrollDownTo(t){
    var html =  $('html,body');

    if(flag_m == 1){
        activelyScrolling = true;
        switch(t){

           case 1:
               html.animate({scrollTop: $('#home').offset().top}, 1000);
               scrollT = 1;

               setTimeout(function(){
                nav.css("opacity","0");
               current.css("display","none");
               $('.arrow-nav-container').css("display","none");
               },500);

                break;
          case 2:
            scrollT = 2;
            arrow_down.css("display",disp);
            if($(window).width()<550){
                html.animate({scrollTop: $('.about-container').offset().top - offset_s}, 500);
            }
            else{
                html.animate({scrollTop: $('#about').offset().top - offset_s}, 500);
            }
            setTimeout(function(){
                showStuff();
                nav.css("opacity","1");
                show_nav(aboutChild);
            },500);
            break;

          case 3:
            scrollT = 3;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('#about').offset().top + $(window).height()-offset_s}, 500);
            current.css("display","none");
            current = aboutChild;
            current.css("display","block");
            showStuff();
            break;

          case 4:
            scrollT = 4;
            arrow_down.css("display",disp);
            $('.slider').slider('start');
            html.animate({scrollTop: $('.tech-expo').offset().top -offset_s}, 500);
            current.css("display","none");
            current = aboutChild;
            current.css("display","block");
            showStuff();
            show_nav(techChild);
            break;

          case 5:
            scrollT = 5;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('.events').offset().top -offset_s}, 500);
            showStuff();
            show_nav(eventChild);
            break;
          case 6:
            scrollT = 6;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('.speakers-container').offset().top-offset_s}, 500);
            showStuff();
            show_nav(speakerChild);
            break;
          case 7:
            scrollT = 7;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('#parvah').offset().top - offset_s}, 500);
            showStuff();
            show_nav(parvaahChild);
            break;
          case 8:
            scrollT = 8;
            arrow_down.css("display",disp);
            html.animate({scrollTop: $('#sponsors').offset().top - offset_s}, 500);
            showStuff();
            show_nav(sponsorChild);
            break;
          case 9:
            scrollT = 9;
            showStuff();
            arrow_down.css("display","none");
            show_nav(contactChild);
            html.animate({scrollTop: $('#contact').offset().top - offset_s}, 500);
             break;
        }
  }
  else{
        html.animate({scrollTop: $('#events').offset().top - offset_s}, 5);
        scrollT-=1;
  }

  setTimeout(function(){
        activelyScrolling = false; scrollT =t;
  },500);
}
$(document).ready(function(){

      nav = $('nav');
  		aboutChild = $('.current li:nth-child(2)');
      techChild = $('.current li:nth-child(3)')
      eventChild = $('.current li:nth-child(4)');
      speakerChild = $('.current li:nth-child(5)')
      parvaahChild = $('.current li:nth-child(6)');
      sponsorChild = $('.current li:nth-child(7)');
      contactChild = $('.current li:nth-child(8)');
      arrow_up = $('.up-arrow');
      arrow_down = $('.down-arrow');
      current = $('.current li');
      arrow_up = $('.up-arrow');
      arrow_down = $('.down-arrow');

      scrollDownTo(1);

      if ( win.width() > 767) {
            var s = skrollr.init();
      }

      $(".button-collapse").sideNav({
            closeOnClick: true // Closes side-nav on <a> clicks, useful for Angular/Meteor
      });

      $(".parallax").parallax();

      $(".modal-trigger").leanModal({
            dismissible: true, // Modal can be dismissed by clicking outside of the modal
            opacity: 0.5, // Opacity of modal background
            in_duration: 300, // Transition in duration
            out_duration: 200, // Transition out duration
            starting_top: "0%", // Starting top style attribute
            ending_top: "0%", // Ending top style attribute
            ready: function() { $("#modal1").toggleClass("slideOutUp");}, // Callback for Modal open
            complete: function(){$("#modal1").toggleClass("slideOutUp");}// Callback for Modal close
      });

      $('.collapsible').collapsible({});

      $(".slider").slider({
            full_width: true,
            height: win_height*0.87
      });
      $('.slider2').slider({
          full_width: true,
          height: win_height*0.9
});
      $(".slider").slider("pause");

});

//om click stuff

$(".viewMore").on("click",function(){
        $(".sponsors").toggleClass("more");
        $("#lastYear .container").toggleClass("more");
        $("#thisYear .container").toggleClass("more");
        $("#sponsors").toggleClass("check");
        if($("#sponsors").hasClass("check")){
              flag_m1 = 0;
              $(".viewMore h5").text("View Less");
        }
        else{
              flag_m1 = 1;
              $(".viewMore h5").text("View More");

        }
});

 $(window).on('resize',function(){
    if ( $(window).width() > 767) {
          var s = skrollr.init();
    }

    if(win_width<550){
          offset_s = win_width*0.1;
          $('.about-container').css('display','block');
          $('.social-mobile').css('display','block');
    }
    else{
          $('.social-mobile').css('display','none');
          $('.about-container').css('display','none');
    }

});

//scrolling stuff

$(".down-arrow").on("click",function(){
        goDown();
        return false;
});
$(".up-arrow").on("click",function(){
        goUp();
        return false;
});

 $("#abhiyantriki-logo").on("click",function(){
        scrollDownTo(1);
});

$(".brand-logo").on("click",function(){

        scrollDownTo(1);
});

 $(document).keydown(function(e){
        if (e.keyCode == 40){
               goDown();
               return false
        }
        else if (e.keyCode == 38){

                goUp();
                return false;
        }
});

//mouse wheel
win.bind("mousewheel", function(e){

       if(flag_m1==1){
               if(e.originalEvent.wheelDelta < -119) {

                  goDown();
                  return false;
                }
                else if (e.originalEvent.wheelDelta > 119) {

                  goUp();
                  return false;

              }
       }
});

 //touch pad  scroll

win.bind("wheel", function(e){

      if(flag_m1==1){
             if(e.originalEvent.deltaY < -0.2) {

                goUp();
                return false;
              }
              else if (e.originalEvent.deltaY >=0.2) {

                goDown();
                return false;

              }
      }

});<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
/* globals gPinnedLinks */
"use strict";

/**
 * Singleton that keeps track of all blocked links in the grid.
 */
(function(exports) {
  const gBlockedLinks = {
    /**
     * A list of objects that are observing blocked link changes.
     */
    _observers: [],

    /**
     * The cached list of blocked links.
     */
    _links: null,

    /**
     * Registers an object that will be notified when the blocked links change.
     */
    addObserver(aObserver) {
      this._observers.push(aObserver);
    },

    /**
     * The list of blocked links.
     */
    get links() {
      /*if (!this._links) {
        this._links = Storage.get("blockedLinks", {});
      }*/

      return this._links;
    },

    /**
     * Blocks a given link. Adjusts siteMap accordingly, and notifies listeners.
     *
     * @param {Link} aLink The link to block.
     */
    block(aLink) {
      this._callObservers("onLinkBlocked", aLink);
      //this.links[toHash(aLink.url)] = 1;
      this.save();

      // Make sure we unpin blocked links.
      gPinnedLinks.unpin(aLink);
    },

    /**
     * Unblocks a given link. Adjusts siteMap accordingly, and notifies linksteners.
     *
     * @param {Link} aLink The link to unblock.
     */
    unblock(aLink) {
      if (this.isBlocked(aLink)) {
        //delete this.links[toHash(aLink.url)];
        this.save();
        this._callObservers("onLinkUnblocked", aLink);
      }
    },

    /**
     * Saves the current list of blocked links.
     */
    save() {
      console.log("beep");
      //Storage.set("blockedLinks", this.links);
    },

    /**
     * Returns whether a given link is blocked.
     *
     * @param {Link} aLink The link to check.
     */
    isBlocked(aLink) {
      return aLink.url;
      //return (toHash(aLink.url) in this.links);
    },

    /**
     * Checks whether the list of blocked links is empty.
     *
     * @return {Boolean} Whether the list is empty.
     */
    isEmpty() {
      return Object.keys(this.links).length === 0;
    },

    /**
     * Resets the links cache.
     */
    resetCache() {
      this._links = null;
    },

    _callObservers(methodName, ...args) {
      for (let obs of this._observers) {
        if (typeof(obs[methodName]) === "function") {
          try {
            obs[methodName](...args);
          } catch (err) {
            console.error(err);
          }
        }
      }
    }
  };
  exports.gBlockedLinks = gBlockedLinks;
}(window));
<commit_msg>Remove observer functionality for now. This is only used for suggested tiles.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
/* globals gPinnedLinks */
"use strict";

/**
 * Singleton that keeps track of all blocked links in the grid.
 */
(function(exports) {
  const gBlockedLinks = {
    /**
     * The cached list of blocked links.
     */
    _links: null,

    /**
     * The list of blocked links.
     */
    get links() {
      /*if (!this._links) {
        this._links = Storage.get("blockedLinks", {});
      }*/

      return this._links;
    },

    /**
     * Blocks a given link. Adjusts siteMap accordingly, and notifies listeners.
     *
     * @param {Link} aLink The link to block.
     */
    block(aLink) {
      //this.links[toHash(aLink.url)] = 1;
      this.save();

      // Make sure we unpin blocked links.
      gPinnedLinks.unpin(aLink);
    },

    /**
     * Unblocks a given link. Adjusts siteMap accordingly, and notifies linksteners.
     *
     * @param {Link} aLink The link to unblock.
     */
    unblock(aLink) {
      if (this.isBlocked(aLink)) {
        //delete this.links[toHash(aLink.url)];
        this.save();
      }
    },

    /**
     * Saves the current list of blocked links.
     */
    save() {
      console.log("beep");
      //Storage.set("blockedLinks", this.links);
    },

    /**
     * Returns whether a given link is blocked.
     *
     * @param {Link} aLink The link to check.
     */
    isBlocked(aLink) {
      return aLink.url;
      //return (toHash(aLink.url) in this.links);
    },

    /**
     * Checks whether the list of blocked links is empty.
     *
     * @return {Boolean} Whether the list is empty.
     */
    isEmpty() {
      return Object.keys(this.links).length === 0;
    },

    /**
     * Resets the links cache.
     */
    resetCache() {
      this._links = null;
    },
  };
  exports.gBlockedLinks = gBlockedLinks;
}(window));
<|endoftext|>


<commit_before>var Def = require('../core/definition');
var PersistentMask = Def.PersistentMask;
var DontSave = Def.DontSave;
var _isDomNode = require('../core/utils').isDomNode;
var nicifySerialized = require('./serialize-nicify');

function _getType (obj) {
    var p = obj.constructor.prototype;
    if (p.hasOwnProperty('__cid__')) {
        return obj.__cid__;
    }
    if (p.hasOwnProperty('__classname__')) {
        return obj.__classname__;
    }
    return '';
}

var _Serializer = (function () {

    ///**
    // * @param {boolean} [exporting=false] - if true, property with Fire.EditorOnly will be discarded
    // */
    function _Serializer(obj, exporting) {
        this._exporting = exporting;

        this.serializedList = [];  // list of serialized data for all Fire.FObject objs
        this._parsingObjs = [];    // 记录当前引用对象，防止循环引用
        this._parsingData = [];    // 记录当前引用对象的序列化结果
        this._objsToResetId = [];

        _serializeMainObj(this, obj);

        for (var i = 0; i < this._objsToResetId.length; ++i) {
            this._objsToResetId[i].__id__ = undefined;
        }

        this._parsingObjs = null;
        this._parsingData = null;
        this._objsToResetId = null;
    }

    // even array may caused circular reference, so we'd be better check it all the time, 否则就要像unity限制递归层次，有好有坏
    var _checkCircularReference = function (self, obj) {
        var parsingIndex = self._parsingObjs.indexOf(obj);
        var circularReferenced = (parsingIndex !== -1);
        if (circularReferenced) {
            // register new referenced object
            var id = self.serializedList.length;
            obj.__id__ = id;        // we add this prop dynamically to simply lookup whether an obj has been serialized.
                                    // If it will lead to performance degradations in V8, we just need to save ids to another table.
            self._objsToResetId.push(obj);
            var data = self._parsingData[parsingIndex];
            if (Array.isArray(obj) === false) {
                //data.__id__ = id;   // also save id in source data, just for debugging
                var type = _getType(obj);
                if (type) {
                    data.__type__ = type;
                }
            }
            self.serializedList.push(data);
            return data;
        }
    };

    ///**
    // * @param {object} obj - The object to serialize
    // * @param {array|object} data - The array or dict where serialized data to store
    // * @return {object} The reference info used to embed to its container.
    // *                   if the serialized data not contains in serializedList, then return the data directly.
    // */
    var _enumerateObject = function (self, obj, data) {
        if (Array.isArray(obj)) {
            for (var i = 0; i < obj.length; ++i) {
                var item = _serializeField(self, obj[i]);
                if (typeof item !== 'undefined') {     // strip undefined item (dont save)
                    data.push(item);
                }
            }
        }
        else {
            var attrs, propName;
            var klass = obj.constructor;
            var mixinClasses = obj._mixinClasses;
            if (mixinClasses) {
                for (var i = 0; i < mixinClasses.length; i++) {
                    var mixinClass = mixinClasses[i];
                    var props = mixinClass.__props__;
                    if (props) {
                        for (var p2 = 0; p2 < props.length; p2++) {
                            propName = props[p2];
                            attrs = Fire.attr(mixinClass, propName);
                            // assume all prop in __props__ must have attr

                            // skip nonSerialized
                            if (attrs.serializable === false) {
                                continue;
                            }

                            // skip editor only when exporting
                            if (self._exporting && attrs.editorOnly) {
                                continue;
                            }

                            // undefined value (if dont save) will be stripped from JSON
                            data[propName] = _serializeField(self, obj[propName]);
                        }
                    }
                }
            }
            else if (! Fire._isFireClass(klass)) {
                // primitive javascript object
                for (var key in obj) {
                    //Fire.log(key);
                    if ( !obj.hasOwnProperty(key) || (key.charCodeAt(0) === 95 && key.charCodeAt(1) === 95))    // starts with __
                        continue;
                    // undefined value (if dont save) will be stripped from JSON
                    data[key] = _serializeField(self, obj[key]);
                }
            }
            else {
                // normal FireClass

                //if (obj.onBeforeSerialize) {
                //    obj.onBeforeSerialize();
                //}
                var props = klass.__props__;
                if (props) {
                    if (props[props.length - 1] !== '_$erialized') {
                        for (var p = 0; p < props.length; p++) {
                            propName = props[p];
                            attrs = Fire.attr(klass, propName);
                            // assume all prop in __props__ must have attr

                            // skip nonSerialized
                            if (attrs.serializable === false) {
                                continue;
                            }

                            // skip editor only when exporting
                            if (self._exporting && attrs.editorOnly) {
                                continue;
                            }

                            // undefined value (if dont save) will be stripped from JSON
                            data[propName] = _serializeField(self, obj[propName]);
                        }
                    }
                    else {
                        // If is missing script proxy, serialized as original data
                        data.__type__ = obj._$erialized.__type__;
                        _enumerateObject(self, obj._$erialized, data);
                    }
                }
            }
        }
    };

    ///**
    // * serialize any type
    // * @param {*} val - The element to serialize
    // */
    var _serializeField = function (self, val) {
        var type = typeof val;
        if (type === 'object') {
            if (val instanceof FObject) {
                var objFlags = val._objFlags;
                if (objFlags & DontSave) {
                    return undefined;
                }
                else if (self._exporting && (objFlags & EditorOnly)) {
                    return undefined;
                }
            }
            return _serializeObj(self, val);
        }
        else if (type !== 'function') {
            return val;
        }
        else /*function*/ {
            return null;
        }
    };

    ///**
    // * serialize only primitive object type
    // * @param {object} obj - The object to serialize
    // */
    var _serializePrimitiveObj = function (self, obj) {
        var data;
        if (Array.isArray(obj)) {
            data = [];
        }
        else {  // 'object'
            data = {};
            var type = _getType(obj);
            if (type) {
                data.__type__ = type;
            }
        }

        var oldSerializedCount = self.serializedList.length;

        // mark parsing to prevent circular reference
        self._parsingObjs.push(obj);
        self._parsingData.push(data);

        _enumerateObject(self, obj, data);

        self._parsingObjs.pop();
        self._parsingData.pop();

        // check whether obj has been serialized to serializedList,
        // if it is, no need to serialized to data again
        if (self.serializedList.length > oldSerializedCount) {
            var index = self.serializedList.indexOf(data, oldSerializedCount);
            if (index !== -1) {
                return { __id__: index };
            }
        }

        // inline
        return data;
    };

    ///**
    // * serialize object
    // * @param {object} obj - The object to serialize
    // */
    var _serializeObj = function (self, obj) {
        //Fire.log(obj);
        if (!obj) {
            return null;
        }

        // has been serialized ?
        var id = obj.__id__;
        if (typeof id !== 'undefined') {
            return { __id__: id }; // no need to parse again
        }

        if (obj instanceof FObject) {
            // FObject
            if ( !obj.isValid ) {
                return null;
            }
            var uuid = obj._uuid;
            if (uuid) {
                // Asset
                return { __uuid__: uuid };
            }

            // assign id for FObject
            id = self.serializedList.length;
            obj.__id__ = id;        // we add this prop dynamically to simply lookup whether an obj has been serialized.
                                    // If it will lead to performance degradations in V8, we just need to save ids to another table.
            self._objsToResetId.push(obj);

            // get FObject data
            var data = {};
            self.serializedList.push(data);

            var type = _getType(obj);
            if (type) {
                data.__type__ = type;
            }
            if (! obj._serialize) {
                _enumerateObject(self, obj, data);
                data._objFlags &= PersistentMask;
            }
            else {
                //obj._objFlags &= PersistentMask;
                data.content = obj._serialize(self._exporting);
            }

            return { __id__: id };
        }
        else if (_isDomNode(obj)) {
            // raw obj
            //Fire.warn("" + obj + " won't be serialized");
            return null;
        }
        else {
            // check circular reference if primitive object
            // 对于原生javascript类型，只做循环引用的保护，
            // 并不保证同个对象的多处引用反序列化后仍然指向同一个对象。
            // 如果有此需求，应该继承自FObject
            var referencedData = _checkCircularReference(self, obj);
            if (referencedData) {
                // already referenced
                id = obj.__id__;
                return { __id__: id };
            }
            else {
                return _serializePrimitiveObj(self, obj);
            }
        }
    };

    ///**
    // * serialize main object
    // * 这个方法主要是对 main object 做特殊处理，虽然和 _serializeObj 很接近，但为了
    // * 避免增加 _serializeObj 的额外开销并不和它合并到一起。
    // * @param {object} obj - The object to serialize
    // */
    var _serializeMainObj = function (self, obj) {
        if (obj instanceof FObject) {
            var uuid = obj._uuid;
            if (typeof uuid !== 'undefined') {
                // force Asset serializable, or _serializeObj will just return { __uuid__: ... }
                obj._uuid = null;
            }

            _serializeObj(self, obj);

            if (typeof uuid !== 'undefined') {
                // restore uuid
                obj._uuid = uuid;
            }
        }
        else if (typeof obj === 'object' && obj) {
            if (_isDomNode(obj)) {
                Fire.warn("" + obj + " won't be serialized");
                self.serializedList.push(null);
                return;
            }

            var data;
            if (Array.isArray(obj)) {
                data = [];
            }
            else {
                data = {};
                var type = _getType(obj);
                if (type) {
                    data.__type__ = type;
                }
            }

            obj.__id__ = 0;
            self._objsToResetId.push(obj);
            self.serializedList.push(data);
            _enumerateObject(self, obj, data);
        }
        else {
            self.serializedList.push(_serializeObj(self, obj));
        }
    };

    return _Serializer;
})();

/**
 * @module Editor
 */
/**
 * Serialize Fire.Asset to a json string
 * @method serialize
 * @param {Asset} obj - The object to serialize
 * @param {object} [options=null]
 * @return {string|object} The json string to represent the object or json object if dontStringify is true
 */
Editor.serialize = function (obj, options) {
    var exporting = (options && options.exporting);
    // indicates whether needs to convert the result by JSON.stringify, default is true
    var stringify = (options && 'stringify' in options) ? options.stringify : true;
    var minify = (options && 'minify' in options) ? options.minify : false;
    var nicify = minify || (options && options.nicify);

    var serializer = new _Serializer(obj, exporting);
    var serializedList = serializer.serializedList;

    if (nicify) {
        nicifySerialized(serializedList);
    }

    var serializedData = serializedList.length === 1 ? serializedList[0] : serializedList;
    if (stringify === false) {
        return serializedData;
    }
    else {
        return JSON.stringify(serializedData, null, minify ? 0 : 2);
    }
};

/**
 * Create a pseudo object which will be force serialized as a reference to any asset by specified uuid.
 * @method serialize.asAsset
 * @param {string} uuid
 * @return {Asset}
 */
Editor.serialize.asAsset = function (uuid) {
    if ( !uuid ) {
        Fire.error('[Editor.serialize.asAsset] The uuid must be non-nil!');
    }
    var pseudoAsset = new Asset();
    pseudoAsset._uuid = uuid;
    return pseudoAsset;
};

/**
 * Set the asset's name directly in JSON object
 * @method serialize.setName
 * @param {object} jsonObj
 * @param {string} name
 */
Editor.serialize.setName = function (jsonObj, name) {
    if ( Array.isArray(jsonObj) ) {
        jsonObj[0]._name = name;
    }
    else {
        jsonObj._name = name;
    }
};

module.exports = Editor.serialize;
<commit_msg>fix _isDomNode in core level<commit_after>var Def = require('../core/definition');
var PersistentMask = Def.PersistentMask;
var DontSave = Def.DontSave;
var _isDomNode = require('../core/utils').isDomNode;
var nicifySerialized = require('./serialize-nicify');

function _getType (obj) {
    var p = obj.constructor.prototype;
    if (p.hasOwnProperty('__cid__')) {
        return obj.__cid__;
    }
    if (p.hasOwnProperty('__classname__')) {
        return obj.__classname__;
    }
    return '';
}

var _Serializer = (function () {

    ///**
    // * @param {boolean} [exporting=false] - if true, property with Fire.EditorOnly will be discarded
    // */
    function _Serializer(obj, exporting) {
        this._exporting = exporting;

        this.serializedList = [];  // list of serialized data for all Fire.FObject objs
        this._parsingObjs = [];    // 记录当前引用对象，防止循环引用
        this._parsingData = [];    // 记录当前引用对象的序列化结果
        this._objsToResetId = [];

        _serializeMainObj(this, obj);

        for (var i = 0; i < this._objsToResetId.length; ++i) {
            this._objsToResetId[i].__id__ = undefined;
        }

        this._parsingObjs = null;
        this._parsingData = null;
        this._objsToResetId = null;
    }

    // even array may caused circular reference, so we'd be better check it all the time, 否则就要像unity限制递归层次，有好有坏
    var _checkCircularReference = function (self, obj) {
        var parsingIndex = self._parsingObjs.indexOf(obj);
        var circularReferenced = (parsingIndex !== -1);
        if (circularReferenced) {
            // register new referenced object
            var id = self.serializedList.length;
            obj.__id__ = id;        // we add this prop dynamically to simply lookup whether an obj has been serialized.
                                    // If it will lead to performance degradations in V8, we just need to save ids to another table.
            self._objsToResetId.push(obj);
            var data = self._parsingData[parsingIndex];
            if (Array.isArray(obj) === false) {
                //data.__id__ = id;   // also save id in source data, just for debugging
                var type = _getType(obj);
                if (type) {
                    data.__type__ = type;
                }
            }
            self.serializedList.push(data);
            return data;
        }
    };

    ///**
    // * @param {object} obj - The object to serialize
    // * @param {array|object} data - The array or dict where serialized data to store
    // * @return {object} The reference info used to embed to its container.
    // *                   if the serialized data not contains in serializedList, then return the data directly.
    // */
    var _enumerateObject = function (self, obj, data) {
        if (Array.isArray(obj)) {
            for (var i = 0; i < obj.length; ++i) {
                var item = _serializeField(self, obj[i]);
                if (typeof item !== 'undefined') {     // strip undefined item (dont save)
                    data.push(item);
                }
            }
        }
        else {
            var attrs, propName;
            var klass = obj.constructor;
            var mixinClasses = obj._mixinClasses;
            if (mixinClasses) {
                for (var i = 0; i < mixinClasses.length; i++) {
                    var mixinClass = mixinClasses[i];
                    var props = mixinClass.__props__;
                    if (props) {
                        for (var p2 = 0; p2 < props.length; p2++) {
                            propName = props[p2];
                            attrs = Fire.attr(mixinClass, propName);
                            // assume all prop in __props__ must have attr

                            // skip nonSerialized
                            if (attrs.serializable === false) {
                                continue;
                            }

                            // skip editor only when exporting
                            if (self._exporting && attrs.editorOnly) {
                                continue;
                            }

                            // undefined value (if dont save) will be stripped from JSON
                            data[propName] = _serializeField(self, obj[propName]);
                        }
                    }
                }
            }
            else if (! Fire._isFireClass(klass)) {
                // primitive javascript object
                for (var key in obj) {
                    //Fire.log(key);
                    if ( !obj.hasOwnProperty(key) || (key.charCodeAt(0) === 95 && key.charCodeAt(1) === 95))    // starts with __
                        continue;
                    // undefined value (if dont save) will be stripped from JSON
                    data[key] = _serializeField(self, obj[key]);
                }
            }
            else {
                // normal FireClass

                //if (obj.onBeforeSerialize) {
                //    obj.onBeforeSerialize();
                //}
                var props = klass.__props__;
                if (props) {
                    if (props[props.length - 1] !== '_$erialized') {
                        for (var p = 0; p < props.length; p++) {
                            propName = props[p];
                            attrs = Fire.attr(klass, propName);
                            // assume all prop in __props__ must have attr

                            // skip nonSerialized
                            if (attrs.serializable === false) {
                                continue;
                            }

                            // skip editor only when exporting
                            if (self._exporting && attrs.editorOnly) {
                                continue;
                            }

                            // undefined value (if dont save) will be stripped from JSON
                            data[propName] = _serializeField(self, obj[propName]);
                        }
                    }
                    else {
                        // If is missing script proxy, serialized as original data
                        data.__type__ = obj._$erialized.__type__;
                        _enumerateObject(self, obj._$erialized, data);
                    }
                }
            }
        }
    };

    ///**
    // * serialize any type
    // * @param {*} val - The element to serialize
    // */
    var _serializeField = function (self, val) {
        var type = typeof val;
        if (type === 'object') {
            if (val instanceof FObject) {
                var objFlags = val._objFlags;
                if (objFlags & DontSave) {
                    return undefined;
                }
                else if (self._exporting && (objFlags & EditorOnly)) {
                    return undefined;
                }
            }
            return _serializeObj(self, val);
        }
        else if (type !== 'function') {
            return val;
        }
        else /*function*/ {
            return null;
        }
    };

    ///**
    // * serialize only primitive object type
    // * @param {object} obj - The object to serialize
    // */
    var _serializePrimitiveObj = function (self, obj) {
        var data;
        if (Array.isArray(obj)) {
            data = [];
        }
        else {  // 'object'
            data = {};
            var type = _getType(obj);
            if (type) {
                data.__type__ = type;
            }
        }

        var oldSerializedCount = self.serializedList.length;

        // mark parsing to prevent circular reference
        self._parsingObjs.push(obj);
        self._parsingData.push(data);

        _enumerateObject(self, obj, data);

        self._parsingObjs.pop();
        self._parsingData.pop();

        // check whether obj has been serialized to serializedList,
        // if it is, no need to serialized to data again
        if (self.serializedList.length > oldSerializedCount) {
            var index = self.serializedList.indexOf(data, oldSerializedCount);
            if (index !== -1) {
                return { __id__: index };
            }
        }

        // inline
        return data;
    };

    ///**
    // * serialize object
    // * @param {object} obj - The object to serialize
    // */
    var _serializeObj = function (self, obj) {
        //Fire.log(obj);
        if (!obj) {
            return null;
        }

        // has been serialized ?
        var id = obj.__id__;
        if (typeof id !== 'undefined') {
            return { __id__: id }; // no need to parse again
        }

        if (obj instanceof FObject) {
            // FObject
            if ( !obj.isValid ) {
                return null;
            }
            var uuid = obj._uuid;
            if (uuid) {
                // Asset
                return { __uuid__: uuid };
            }

            // assign id for FObject
            id = self.serializedList.length;
            obj.__id__ = id;        // we add this prop dynamically to simply lookup whether an obj has been serialized.
                                    // If it will lead to performance degradations in V8, we just need to save ids to another table.
            self._objsToResetId.push(obj);

            // get FObject data
            var data = {};
            self.serializedList.push(data);

            var type = _getType(obj);
            if (type) {
                data.__type__ = type;
            }
            if (! obj._serialize) {
                _enumerateObject(self, obj, data);
                data._objFlags &= PersistentMask;
            }
            else {
                //obj._objFlags &= PersistentMask;
                data.content = obj._serialize(self._exporting);
            }

            return { __id__: id };
        }
        else if (_isDomNode && _isDomNode(obj)) {
            // raw obj
            //Fire.warn("" + obj + " won't be serialized");
            return null;
        }
        else {
            // check circular reference if primitive object
            // 对于原生javascript类型，只做循环引用的保护，
            // 并不保证同个对象的多处引用反序列化后仍然指向同一个对象。
            // 如果有此需求，应该继承自FObject
            var referencedData = _checkCircularReference(self, obj);
            if (referencedData) {
                // already referenced
                id = obj.__id__;
                return { __id__: id };
            }
            else {
                return _serializePrimitiveObj(self, obj);
            }
        }
    };

    ///**
    // * serialize main object
    // * 这个方法主要是对 main object 做特殊处理，虽然和 _serializeObj 很接近，但为了
    // * 避免增加 _serializeObj 的额外开销并不和它合并到一起。
    // * @param {object} obj - The object to serialize
    // */
    var _serializeMainObj = function (self, obj) {
        if (obj instanceof FObject) {
            var uuid = obj._uuid;
            if (typeof uuid !== 'undefined') {
                // force Asset serializable, or _serializeObj will just return { __uuid__: ... }
                obj._uuid = null;
            }

            _serializeObj(self, obj);

            if (typeof uuid !== 'undefined') {
                // restore uuid
                obj._uuid = uuid;
            }
        }
        else if (typeof obj === 'object' && obj) {
            if (_isDomNode && _isDomNode(obj)) {
                Fire.warn("" + obj + " won't be serialized");
                self.serializedList.push(null);
                return;
            }

            var data;
            if (Array.isArray(obj)) {
                data = [];
            }
            else {
                data = {};
                var type = _getType(obj);
                if (type) {
                    data.__type__ = type;
                }
            }

            obj.__id__ = 0;
            self._objsToResetId.push(obj);
            self.serializedList.push(data);
            _enumerateObject(self, obj, data);
        }
        else {
            self.serializedList.push(_serializeObj(self, obj));
        }
    };

    return _Serializer;
})();

/**
 * @module Editor
 */
/**
 * Serialize Fire.Asset to a json string
 * @method serialize
 * @param {Asset} obj - The object to serialize
 * @param {object} [options=null]
 * @return {string|object} The json string to represent the object or json object if dontStringify is true
 */
Editor.serialize = function (obj, options) {
    var exporting = (options && options.exporting);
    // indicates whether needs to convert the result by JSON.stringify, default is true
    var stringify = (options && 'stringify' in options) ? options.stringify : true;
    var minify = (options && 'minify' in options) ? options.minify : false;
    var nicify = minify || (options && options.nicify);

    var serializer = new _Serializer(obj, exporting);
    var serializedList = serializer.serializedList;

    if (nicify) {
        nicifySerialized(serializedList);
    }

    var serializedData = serializedList.length === 1 ? serializedList[0] : serializedList;
    if (stringify === false) {
        return serializedData;
    }
    else {
        return JSON.stringify(serializedData, null, minify ? 0 : 2);
    }
};

/**
 * Create a pseudo object which will be force serialized as a reference to any asset by specified uuid.
 * @method serialize.asAsset
 * @param {string} uuid
 * @return {Asset}
 */
Editor.serialize.asAsset = function (uuid) {
    if ( !uuid ) {
        Fire.error('[Editor.serialize.asAsset] The uuid must be non-nil!');
    }
    var pseudoAsset = new Asset();
    pseudoAsset._uuid = uuid;
    return pseudoAsset;
};

/**
 * Set the asset's name directly in JSON object
 * @method serialize.setName
 * @param {object} jsonObj
 * @param {string} name
 */
Editor.serialize.setName = function (jsonObj, name) {
    if ( Array.isArray(jsonObj) ) {
        jsonObj[0]._name = name;
    }
    else {
        jsonObj._name = name;
    }
};

module.exports = Editor.serialize;
<|endoftext|>