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

/**
 * The protractor node is a circular device for measuring angles. In this sim it is used for measuring the angle of the
 * incident, reflected and refracted light.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chandrashekar Bemagoni (Actual Concepts)
 */

import Property from '../../axon/js/Property.js';
import Shape from '../../kite/js/Shape.js';
import sceneryPhet from '../../scenery-phet/js/sceneryPhet.js';
import protractorImage from '../../scenery-phet/mipmaps/protractor_png.js';
import SimpleDragHandler from '../../scenery/js/input/SimpleDragHandler.js';
import Image from '../../scenery/js/nodes/Image.js';
import Node from '../../scenery/js/nodes/Node.js';
import Path from '../../scenery/js/nodes/Path.js';

class ProtractorNode extends Node {

  /**
   * @param {Property.<boolean>} showProtractorProperty - controls the protractor visibility
   * @param {boolean} rotatable - can be rotated
   * @param {Object} [options]
   */
  constructor( showProtractorProperty, rotatable, options ) {

    super();

    this.showProtractorProperty = showProtractorProperty; // @public (read-only)

    // @public (read-only)- the image node
    this.protractorImageNode = new Image( protractorImage, { pickable: false } );

    showProtractorProperty.linkAttribute( this, 'visible' );
    this.addChild( this.protractorImageNode );

    // Use nicknames for the protractor image width and height to make the layout code easier to understand
    const w = this.protractorImageNode.getWidth();
    const h = this.protractorImageNode.getHeight();

    /**
     * Creates the outer rim shape of the protractor, used for the outer rim shape as well as the full shape with
     * the interior middle bar.
     * @returns {Shape}
     */
    const createOuterRimShape = () => new Shape()
      .moveTo( w, h / 2 )
      .ellipticalArc( w / 2, h / 2, w / 2, h / 2, 0, 0, Math.PI, true )
      .lineTo( w * 0.2, h / 2 )
      .ellipticalArc( w / 2, h / 2, w * 0.3, h * 0.3, 0, Math.PI, 0, false )
      .lineTo( w, h / 2 )
      .ellipticalArc( w / 2, h / 2, w / 2, h / 2, 0, 0, Math.PI, false )
      .lineTo( w * 0.2, h / 2 )
      .ellipticalArc( w / 2, h / 2, w * 0.3, h * 0.3, 0, Math.PI, 0, true );

    // shape for the outer ring of the protractor, must match the image.
    this.outerRimShape = createOuterRimShape();

    this.fullShape = createOuterRimShape()
      .rect( w * 0.2, h / 2, w * 0.6, h * 0.15 );

    this.mouseArea = this.fullShape;
    this.touchArea = this.fullShape;
    this.cursor = 'pointer';

    if ( rotatable ) {
      this.protractorAngleProperty = new Property( 0.0 );

      // add a mouse listener for rotating when the rotate shape (the outer ring in the 'prism' screen is dragged)
      const rotatePath = new Path( this.outerRimShape, {
        pickable: true,
        cursor: 'pointer'
      } );
      this.addChild( rotatePath );

      // rotate listener
      let start;
      rotatePath.addInputListener( new SimpleDragHandler( {
        start: event => {
          start = this.globalToParentPoint( event.pointer.point );
        },
        drag: event => {

          // compute the change in angle based on the new drag event
          const end = this.globalToParentPoint( event.pointer.point );
          const centerX = this.getCenterX();
          const centerY = this.getCenterY();
          const startAngle = Math.atan2( centerY - start.y, centerX - start.x );
          const angle = Math.atan2( centerY - end.y, centerX - end.x );

          // rotate the protractor model
          this.protractorAngleProperty.value += angle - startAngle;
          start = end;
        }
      } ) );

      // update the protractor angle
      this.protractorAngleProperty.link( angle => {
        this.rotateAround( this.center, angle - this.getRotation() );
      } );
      this.barPath = new Path( new Shape().rect( w * 0.2, h / 2, w * 0.6, h * 0.15 ) );
      this.addChild( this.barPath );
    }
    this.mutate( options );
  }

  // @public
  // Reset the rotation of the ProtractorNode
  reset() {
    this.protractorAngleProperty && this.protractorAngleProperty.reset();
  }
}

sceneryPhet.register( 'ProtractorNode', ProtractorNode );

export default ProtractorNode;<commit_msg>use ProtractorNode.protractorImage in toolbox, https://github.com/phetsims/scenery-phet/issues/609<commit_after>// Copyright 2015-2020, University of Colorado Boulder

/**
 * The protractor node is a circular device for measuring angles. In this sim it is used for measuring the angle of the
 * incident, reflected and refracted light.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Chandrashekar Bemagoni (Actual Concepts)
 */

import Property from '../../axon/js/Property.js';
import Shape from '../../kite/js/Shape.js';
import sceneryPhet from '../../scenery-phet/js/sceneryPhet.js';
import protractorImage from '../../scenery-phet/mipmaps/protractor_png.js';
import SimpleDragHandler from '../../scenery/js/input/SimpleDragHandler.js';
import Image from '../../scenery/js/nodes/Image.js';
import Node from '../../scenery/js/nodes/Node.js';
import Path from '../../scenery/js/nodes/Path.js';

class ProtractorNode extends Node {

  /**
   * @param {Property.<boolean>} showProtractorProperty - controls the protractor visibility
   * @param {boolean} rotatable - can be rotated
   * @param {Object} [options]
   */
  constructor( showProtractorProperty, rotatable, options ) {

    super();

    this.showProtractorProperty = showProtractorProperty; // @public (read-only)

    // @public (read-only)- the image node
    this.protractorImageNode = new Image( protractorImage, { pickable: false } );

    showProtractorProperty.linkAttribute( this, 'visible' );
    this.addChild( this.protractorImageNode );

    // Use nicknames for the protractor image width and height to make the layout code easier to understand
    const w = this.protractorImageNode.getWidth();
    const h = this.protractorImageNode.getHeight();

    /**
     * Creates the outer rim shape of the protractor, used for the outer rim shape as well as the full shape with
     * the interior middle bar.
     * @returns {Shape}
     */
    const createOuterRimShape = () => new Shape()
      .moveTo( w, h / 2 )
      .ellipticalArc( w / 2, h / 2, w / 2, h / 2, 0, 0, Math.PI, true )
      .lineTo( w * 0.2, h / 2 )
      .ellipticalArc( w / 2, h / 2, w * 0.3, h * 0.3, 0, Math.PI, 0, false )
      .lineTo( w, h / 2 )
      .ellipticalArc( w / 2, h / 2, w / 2, h / 2, 0, 0, Math.PI, false )
      .lineTo( w * 0.2, h / 2 )
      .ellipticalArc( w / 2, h / 2, w * 0.3, h * 0.3, 0, Math.PI, 0, true );

    // shape for the outer ring of the protractor, must match the image.
    this.outerRimShape = createOuterRimShape();

    this.fullShape = createOuterRimShape()
      .rect( w * 0.2, h / 2, w * 0.6, h * 0.15 );

    this.mouseArea = this.fullShape;
    this.touchArea = this.fullShape;
    this.cursor = 'pointer';

    if ( rotatable ) {
      this.protractorAngleProperty = new Property( 0.0 );

      // add a mouse listener for rotating when the rotate shape (the outer ring in the 'prism' screen is dragged)
      const rotatePath = new Path( this.outerRimShape, {
        pickable: true,
        cursor: 'pointer'
      } );
      this.addChild( rotatePath );

      // rotate listener
      let start;
      rotatePath.addInputListener( new SimpleDragHandler( {
        start: event => {
          start = this.globalToParentPoint( event.pointer.point );
        },
        drag: event => {

          // compute the change in angle based on the new drag event
          const end = this.globalToParentPoint( event.pointer.point );
          const centerX = this.getCenterX();
          const centerY = this.getCenterY();
          const startAngle = Math.atan2( centerY - start.y, centerX - start.x );
          const angle = Math.atan2( centerY - end.y, centerX - end.x );

          // rotate the protractor model
          this.protractorAngleProperty.value += angle - startAngle;
          start = end;
        }
      } ) );

      // update the protractor angle
      this.protractorAngleProperty.link( angle => {
        this.rotateAround( this.center, angle - this.getRotation() );
      } );
      this.barPath = new Path( new Shape().rect( w * 0.2, h / 2, w * 0.6, h * 0.15 ) );
      this.addChild( this.barPath );
    }
    this.mutate( options );
  }

  // @public
  // Reset the rotation of the ProtractorNode
  reset() {
    this.protractorAngleProperty && this.protractorAngleProperty.reset();
  }
}

ProtractorNode.protractorImage = protractorImage;

sceneryPhet.register( 'ProtractorNode', ProtractorNode );

export default ProtractorNode;<|endoftext|>


<commit_before>var definition = require('./definition');

function initialDeps(req, res, next, err) {
    var deps = [
        definition.initial('ALL', /.*/, 'req', req),
        definition.initial('ALL', /.*/, 'res', res),
    ];
    if (next) {
        deps.push(definition.initial('ALL', /.*/, 'next', next));
    }
    if (err) {
        deps.push(definition.initial('ALL', /.*/, 'err', err));
    }
    return deps;
}

module.exports = initialDeps;
<commit_msg>Remove if check for 'next' in initialDeps utility<commit_after>var definition = require('./definition');

function initialDeps(req, res, next, err) {
    var deps = [
        definition.initial('ALL', /.*/, 'req', req),
        definition.initial('ALL', /.*/, 'res', res),
    ];
    deps.push(definition.initial('ALL', /.*/, 'next', next));
    if (err) {
        deps.push(definition.initial('ALL', /.*/, 'err', err));
    }
    return deps;
}

module.exports = initialDeps;
<|endoftext|>


<commit_before>'use strict';

var Promise = require('../ext/promise');
var exec    = Promise.denodeify(require('child_process').exec);
var chalk   = require('chalk');
var ui      = require('../ui');

module.exports = function runCommand(command, startedMsg) {
  return function() {
    ui.write('\n');
    ui.pleasantProgress.start(startedMsg);

    return exec(command, { maxBuffer: 1000 * 1024 }).then(function() {
      ui.write(chalk.green('done'));
    }, error);
  };
};

function error(err) {
  ui.write('\n' + chalk.red(err) + '\n');
}

<commit_msg>update run command error message<commit_after>'use strict';

var Promise = require('../ext/promise');
var exec    = Promise.denodeify(require('child_process').exec);
var chalk   = require('chalk');
var ui      = require('../ui');

module.exports = function runCommand(command, startedMsg) {
  return function() {
    ui.write('\n');
    ui.pleasantProgress.start(startedMsg);

    return exec(command, { maxBuffer: 1000 * 1024 }).then(function() {
      ui.write(chalk.green('done'));
    }, error);
  };
};

function error(err) {
  ui.write(chalk.red('\nError thrown while running shell command\n\n'));
  ui.write(err);
}

<|endoftext|>


<commit_before>import {
  fetchPortalDataAndAuthFirestore,
  updateReportSettings,
  updateFeedbackSettings,
  updateQuestionFeedbacks,
  updateActivityFeedbacks,
  fetchRubric
} from "./api";
import { getFirestore } from "./db";

// In some cases callApi returns a promise which might throw an error when it is
// being resolved. In other cases callApi will throw an error directly before it
// returns the promise
function handleApiError(action, next, error) {
  const actionType = action.type;
  const apiType = action.callAPI.type;
  const errorAction = action.callAPI.errorAction;

  // Log this error to the console in addtion to dispatching the errorAction
  // In chrome this log message includes both the stack trace from the error
  // object as well as the stack trace of the console state. Both can be useful
  console.error(`error calling API: ${apiType} during action: ${actionType} (error below)\n`, error);
  if ((error.name === "APIError") && errorAction) {
    next(errorAction(error.response));
    return;
  }
  if ((error instanceof TypeError) && errorAction) {
    // This happens when there is a network error while fetching
    // Use a fake error code 599 so the errorAction code can render something informative
    const response = {
      url: apiType,
      status: 599,
      statusText: error.message,
    };
    next(errorAction(response));
    return;
  }
}

// This middleware is executed only if action includes .callAPI object.
// It calls API action defined in callAPI.type.
// If action succeeds and callAPI.successAction is defined, it will be called with response.
// If action fails and callAPI.errorAction is defined, it will be called with the error response object.
export default store => next => action => {
  if (action.callAPI) {
    const state = store.getState();
    const { type, data, successAction, errorAction} = action.callAPI;
    try {
      callApi(type, data, state)
        // Try to catch errors from the promise returned by callApi
        // The order here is important. In some cases the successAction causes its
        // own error, we don't want to handle that here because we'd incorrectly
        // be reporting the action type and api type
        .catch(error => handleApiError(action, next, error))
        .then(response => successAction && next(successAction(response)));
    } catch (error) {
      // Some callApi functions throw errors during setup, before they
      // return a promise this catch here handles that case.
      handleApiError(action, next, error);
    }
  }
  return next(action);
};

export const API_UPDATE_QUESTION_FEEDBACK = "updateQuestionFeedback";
export const API_UPDATE_ACTIVITY_FEEDBACK = "updateActivityFeedback";
export const API_UPDATE_REPORT_SETTINGS = "updateReportSettings";
export const API_UPDATE_FEEDBACK_SETTINGS = "updateFeedbackSettings";
export const API_FETCH_PORTAL_DATA_AND_AUTH_FIRESTORE = "fetchPortalDataAndAuthFirestore";
export const API_FETCH_RUBRIC = "fetchRubric";

function callApi(type, data, state) {
  switch (type) {
    case API_FETCH_PORTAL_DATA_AND_AUTH_FIRESTORE:
      // Make sure firestore db is ready before fetching data
      return getFirestore().then(() => fetchPortalDataAndAuthFirestore());
    case API_UPDATE_REPORT_SETTINGS:
      return updateReportSettings(data, state.get("report").toJS());
    case API_UPDATE_FEEDBACK_SETTINGS:
      return updateFeedbackSettings(data, state.get("report").toJS());
    case API_UPDATE_QUESTION_FEEDBACK:
      return updateQuestionFeedbacks(data, state.get("report").toJS());
    case API_UPDATE_ACTIVITY_FEEDBACK:
      return updateActivityFeedbacks(data, state.get("report").toJS());
    case API_FETCH_RUBRIC:
      return fetchRubric(data);
  }
}
<commit_msg>fix a linting error, and improve comment grammar.<commit_after>import {
  fetchPortalDataAndAuthFirestore,
  updateReportSettings,
  updateFeedbackSettings,
  updateQuestionFeedbacks,
  updateActivityFeedbacks,
  fetchRubric
} from "./api";
import { getFirestore } from "./db";

// In some cases callApi returns a promise which might throw an error when it is
// being resolved. In other cases callApi will throw an error directly before it
// returns the promise
function handleApiError(action, next, error) {
  const actionType = action.type;
  const apiType = action.callAPI.type;
  const errorAction = action.callAPI.errorAction;

  // Log this error to the console in addtion to dispatching the errorAction
  // In chrome this log message includes both the stack trace from the error
  // object as well as the stack trace of the console state. Both can be useful
  console.error(`error calling API: ${apiType} during action: ${actionType} (error below)\n`, error);
  if ((error.name === "APIError") && errorAction) {
    next(errorAction(error.response));
    return;
  }
  if ((error instanceof TypeError) && errorAction) {
    // This happens when there is a network error while fetching
    // Use a fake error code 599 so the errorAction code can render something informative
    const response = {
      url: apiType,
      status: 599,
      statusText: error.message,
    };
    next(errorAction(response));
    return;
  }
}

// This middleware is executed only if action includes .callAPI object.
// It calls API action defined in callAPI.type.
// If action succeeds and callAPI.successAction is defined, it will be called with response.
// If action fails and callAPI.errorAction is defined, it will be called with the error response object.
export default store => next => action => {
  if (action.callAPI) {
    const state = store.getState();
    const { type, data, successAction } = action.callAPI;
    try {
      callApi(type, data, state)
        // Try to catch errors from the promise returned by callApi
        // The order here is important. In some cases the successAction causes its
        // own error, we don't want to handle that here because we'd incorrectly
        // be reporting the action type and api type
        .catch(error => handleApiError(action, next, error))
        .then(response => successAction && next(successAction(response)));
    } catch (error) {
      // Some callApi functions throw errors during setup, before they
      // return a promise. This catch here handles that case.
      handleApiError(action, next, error);
    }
  }
  return next(action);
};

export const API_UPDATE_QUESTION_FEEDBACK = "updateQuestionFeedback";
export const API_UPDATE_ACTIVITY_FEEDBACK = "updateActivityFeedback";
export const API_UPDATE_REPORT_SETTINGS = "updateReportSettings";
export const API_UPDATE_FEEDBACK_SETTINGS = "updateFeedbackSettings";
export const API_FETCH_PORTAL_DATA_AND_AUTH_FIRESTORE = "fetchPortalDataAndAuthFirestore";
export const API_FETCH_RUBRIC = "fetchRubric";

function callApi(type, data, state) {
  switch (type) {
    case API_FETCH_PORTAL_DATA_AND_AUTH_FIRESTORE:
      // Make sure firestore db is ready before fetching data
      return getFirestore().then(() => fetchPortalDataAndAuthFirestore());
    case API_UPDATE_REPORT_SETTINGS:
      return updateReportSettings(data, state.get("report").toJS());
    case API_UPDATE_FEEDBACK_SETTINGS:
      return updateFeedbackSettings(data, state.get("report").toJS());
    case API_UPDATE_QUESTION_FEEDBACK:
      return updateQuestionFeedbacks(data, state.get("report").toJS());
    case API_UPDATE_ACTIVITY_FEEDBACK:
      return updateActivityFeedbacks(data, state.get("report").toJS());
    case API_FETCH_RUBRIC:
      return fetchRubric(data);
  }
}
<|endoftext|>


<commit_before>CT = {

    taskId: '',
    taskIndex: '',
    tabId: '',
    tab: '',
    tabActive: '',
    prevTabIndex: [],
    inputFocus: false,

    start() {
        say.m('CT.start()')

        CT.prevTabIndex = []

        CT.selectFirstTabOnStart()

        CT.taskId = tabState.selectedTask
        CT.add5()
        CT.loadTasks()
        CT.render()
        CT.events()
    },
    events() {
        say.m('CT.events()')

        document.getElementById('collection-tabs').addEventListener('click', function (e) {
            CT.goToCollection(e)
        })

        document.querySelector('.page-tabs').addEventListener('click', function (e) {
            CT.remoteClassEditing()
        })

        let taskName = document.querySelectorAll('.task-action-container .task-name')
        for (var i = 0; i < taskName.length; i++) {
            taskName[i].addEventListener('click', function (event) {
                CT.overviewTaskNameClickE(event)
            })
            taskName[i].addEventListener('keydown', function (e) {
                CT.overviewTaskNameClickEnterE(e)
            })
        }

    },

    goToCollection(e) {
        say.m('CT.goToCollection(e):')

        // click on collection tabs
        try {
            if (e.target.parentNode.parentNode.id == 'collection-tabs') {
                if (e.target.parentNode.className.indexOf("active-tab") == -1) {
                    tabState.selectedTask = e.target.parentNode.dataset.taskId.trim()
                    switchToTask(e.target.parentNode.dataset.taskId.trim())
                    sessionRestore.save()
                    CT.render()
                    for (let i = 0; i < tabState.tasks.length; i++) {
                        if (tabState.tasks[i].id == tabState.selectedTask) {
                            if (tabState.tasks[i].name == null) {
                                document.querySelector('.active-tab input').disabled = false
                                // document.querySelector('.active-tab input').focus()
                                document.querySelector('.active-tab input').select()
                                document.querySelector('.active-tab').className += ' editing'
                                // CT.inputFocus = true
                                document.querySelector('.active-tab').addEventListener('blur', function () {
                                    CT.remoteClassEditing()
                                }, true);
                            }
                        }
                    }
                } else {
                    document.querySelector('.active-tab input').disabled = false
                    // document.querySelector('.active-tab input').focus()
                    document.querySelector('.active-tab input').select()
                    document.querySelector('.active-tab').className += ' editing'
                    // CT.inputFocus = true
                    document.querySelector('.active-tab').addEventListener('blur', function () {
                        CT.remoteClassEditing()
                    }, true);
                }
            }

        } catch (e) {
        }

        // edit name collection tabs
        document.querySelector('.active-tab input').addEventListener('keydown', function (e) {
            if (e.which == 13) {
                for (let i = 0; i < tabState.tasks.length; i++) {
                    if (tabState.tasks[i].id == e.target.getAttribute('data-id')) {
                        tabState.tasks[i].name = e.target.value
                    }
                }
                sessionRestore.save()
                CT.render()
            }
        })

        eventEmitter.emit('goToCollection')
    },
    goToCollectionID(id) {
        say.m('CT.goToCollectionID(id): ' + id)

        let index = CT.getIndexFromIdTaskId(id)
        if (index == 0) {
            switchToTask(tabState.tasks[index].id)
        } else {
            switchToTask(tabState.tasks[index - 1].id)
        }

        CT.render()
    },
    getIndexFromIdTaskId(id) {
        say.m('CT.getIndexFromIdTaskId(id): ' + id)

        let index = ''

        for (let i = 0; i < tabState.tasks.length; i++) {
            console.log(tabState.tasks[i].id)
            if (tabState.tasks[i].id == id) {
                index = i
            }
        }

        console.log('id: ' + id, 'index: ' + index)
        return index
    },
    remoteClassEditing() {
        say.m('CT.remoteClassEditing()')

        if (document.querySelector('.active-tab ').className.indexOf("editing") != -1) {
            document.querySelector('.active-tab ').classList.remove("editing");
            CT.remoteClassEditing()
        }
    },
    getDataFromE(e) {
        say.m('CT.getDataFromE(e)' + e)

        if (e.target.type == 'text') {
            CT.taskId = e.target.parentElement.dataset.taskId
            CT.taskIndex = e.target.parentElement.dataset.index
        } else {
            CT.taskId = e.target.dataset.taskId
            CT.taskIndex = e.target.dataset.index
        }

        CT.tabId = tabState.tasks[CT.taskIndex].tabs[0].id

        CT.tab = document.querySelector('[data-tab="' + CT.taskIndex + '"]')
        CT.tabActive = document.querySelector('.active-tab.collection-tab')

        CT.prevTabIndex.push(CT.taskIndex) // history tabs

        tabState.selectedTask = tabState.tasks[CT.prevTabIndex[CT.prevTabIndex.length - 1]].id

    },
    selectFirstTabOnStart() {
        tabState.selectedTask = tabState.tasks[0].id
        switchToTask(tabState.selectedTask)
        sessionRestore.save()
    },
    loadTasks() {
        tasks.get().forEach(function (task, index) {
            var el = getTaskElement(task, index)
            taskContainer.appendChild(el)
            taskOverlay.dragula.containers.push(el.getElementsByClassName('task-tabs-container')[0])
        })
    },
    clickOnFirstCollection() {
        document.querySelector('[data-task-id="' + tasks.get()[0].id + ' "]').click()
    },
    add5() {
        if (tabState.tasks.length < 5) {
            let id = tabState.selectedTask
            for (let i = tabState.tasks.length; i != 5; i++) {
                tasks.add()
            }
        }
    },
    overviewTaskNameClickEnterE(e) {
        say.m('CT.overviewTaskNameClickEnterE()')

        let id = e.target.parentElement.parentElement.getAttribute('data-task')
        let eTarget = e.target
        let eVal = e.target.value
        if (e.which == 13) {
            CT.render()
            for (let i = 0; i < tasks.get().length; i++) {
                if (tasks.get()[i].id == id) {
                    if (i <= 5) {
                        document.querySelector(`[data-index="${i}"]`).click()
                    }
                }
            }
        }
    },
    overviewTaskNameClickE(e) {
        say.m('CT.overviewTaskNameClickE()')

        let id = e.target.parentElement.parentElement.getAttribute('data-task')
        for (let i = 0; i < tasks.get().length; i++) {
            if (tasks.get()[i].id == id) {
                if (i <= 5) {
                    CT.collectionTopClickOnCollectionTab(i)
                    CT.collectionLeftFocusOnCollectionTabInput(id)
                }
            }
        }
    },

    collectionTopClickOnCollectionTab(index) {
        document.querySelector(`[data-index="${index}"]`).click()
    },
    collectionTopRemoveBGSelectedAll() {
        let elems = document.querySelectorAll(".active-tab");
        for (var i = 0; i < elems.length; i++)
            elems[i].classList.remove('active-tab');
    },
    collectionTopAddBGSelected(index) {
        CT.collectionTopRemoveBGSelectedAll()
        document.querySelector(`[data-index="${index}"]`).classList.add('active-tab')
    },
    collectionTopAddBGSelectedById(id_) {
        CT.collectionTopRemoveBGSelectedAll()
        document.querySelector(`[data-task-id="${id_} "]`).classList.add('active-tab')
    },
    collectionLeftFocusOnCollectionTabInput(id) {
        document.querySelector(`[data-task="${id}"] input`).focus()
    },

    render() {
        say.m('CT.render()')

        if (CT.inputFocus == false) {
            let collectionTabsHTML = []
            for (let i = 0; i < tabState.tasks.length; i++) {
                let val = tabState.tasks[i].name
                if (val == null || val == 'null')
                    val = ''
                let title = `<input placeholder="●●●" type="text" class="collectionTabInput" data-id="${tabState.tasks[i].id}" value="${val}" disabled="true">` || `<input type="text" placeholder="●●●" class="collectionTabInput" data-id="${tabState.tasks[i].id}" value="${val}"  disabled="true"> <svg width="23.9px" height="5.6px">23.9 5.6 <use xlink:href="icons/svg/miniature-controls.svg#ellipsis-big"></use></svg>`

                collectionTabsHTML.push('
' + title + '
')
                // collectionTabsHTML.push('
' + title + '
')
            }
            document.getElementById('collection-tabs').innerHTML = collectionTabsHTML.join('')

            CT.renderOverlay()

            eventEmitter.emit('render')

        }
    },
    renderOverlay() {
        say.m('CT.renderOverlay()')

        eventEmitter.emit('renderOverlay')

        if (taskOverlay.inputFocus) {
            if (document.querySelector('#task-overlay').getAttribute('hidden') == null)
                taskOverlay.show()
        }

        eventEmitter.emit('render')

    }

}
CT.start()

<commit_msg>Adding a collection page. Two cases.<commit_after>CT = {

    taskId: '',
    taskIndex: '',
    tabId: '',
    tab: '',
    tabActive: '',
    prevTabIndex: [],
    inputFocus: false,

    start() {
        say.m('CT.start()')

        CT.prevTabIndex = []

        CT.selectFirstTabOnStart()

        CT.taskId = tabState.selectedTask
        CT.add5()
        CT.loadTasks()
        CT.render()
        CT.events()
    },
    events() {
        say.m('CT.events()')

        document.getElementById('collection-tabs').addEventListener('click', function (e) {
            CT.goToCollection(e)
        })

        document.querySelector('.page-tabs').addEventListener('click', function (e) {
            CT.remoteClassEditing()
        })

        let taskName = document.querySelectorAll('.task-action-container .task-name')
        for (var i = 0; i < taskName.length; i++) {
            taskName[i].addEventListener('click', function (event) {
                CT.overviewTaskNameClickE(event)
            })
            taskName[i].addEventListener('keydown', function (e) {
                CT.overviewTaskNameClickEnterE(e)
            })
        }

    },

    goToCollection(e) {
        say.m('CT.goToCollection(e):')
        CT.addCollectionTab()
        // click on collection tabs
        try {
            if (e.target.parentNode.parentNode.id == 'collection-tabs') {
                if (e.target.parentNode.className.indexOf("active-tab") == -1) {
                    tabState.selectedTask = e.target.parentNode.dataset.taskId.trim()
                    switchToTask(e.target.parentNode.dataset.taskId.trim())
                    sessionRestore.save()
                    CT.render()
                    for (let i = 0; i < tabState.tasks.length; i++) {
                        if (tabState.tasks[i].id == tabState.selectedTask) {
                            if (tabState.tasks[i].name == null) {
                                CT.addClassEditing()
                                CT.addCollectionTab()
                                document.querySelector('.active-tab').addEventListener('blur', function () {
                                    CT.remoteClassEditing()
                                }, true);
                            }
                        }
                    }
                } else {
                    CT.addClassEditing()
                    CT.addCollectionTab()
                    document.querySelector('.active-tab').addEventListener('blur', function () {
                        CT.remoteClassEditing()
                    }, true);
                }
            }

        } catch (e) {
        }

        // edit name collection tabs
        document.querySelector('.active-tab input').addEventListener('keydown', function (e) {
            if (e.which == 13) {
                for (let i = 0; i < tabState.tasks.length; i++) {
                    if (tabState.tasks[i].id == e.target.getAttribute('data-id')) {
                        tabState.tasks[i].name = e.target.value
                    }
                }
                sessionRestore.save()
                CT.render()
            }
        })

        eventEmitter.emit('goToCollection')
    },
    goToCollectionID(id) {
        say.m('CT.goToCollectionID(id): ' + id)

        let index = CT.getIndexFromIdTaskId(id)
        if (index == 0) {
            switchToTask(tabState.tasks[index].id)
        } else {
            switchToTask(tabState.tasks[index - 1].id)
        }

        CT.render()
    },
    getIndexFromIdTaskId(id) {
        say.m('CT.getIndexFromIdTaskId(id): ' + id)

        let index = ''

        for (let i = 0; i < tabState.tasks.length; i++) {
            console.log(tabState.tasks[i].id)
            if (tabState.tasks[i].id == id) {
                index = i
            }
        }

        console.log('id: ' + id, 'index: ' + index)
        return index
    },
    addClassEditing() {
        document.querySelector('.active-tab input').disabled = false
        document.querySelector('.active-tab input').select()
        document.querySelector('.active-tab').className += ' editing'
    },
    remoteClassEditing() {
        say.m('CT.remoteClassEditing()')

        if (document.querySelector('.active-tab ').className.indexOf("editing") != -1) {
            document.querySelector('.active-tab ').classList.remove("editing");
            CT.remoteClassEditing()
        }
    },
    getDataFromE(e) {
        say.m('CT.getDataFromE(e)' + e)

        if (e.target.type == 'text') {
            CT.taskId = e.target.parentElement.dataset.taskId
            CT.taskIndex = e.target.parentElement.dataset.index
        } else {
            CT.taskId = e.target.dataset.taskId
            CT.taskIndex = e.target.dataset.index
        }

        CT.tabId = tabState.tasks[CT.taskIndex].tabs[0].id

        CT.tab = document.querySelector('[data-tab="' + CT.taskIndex + '"]')
        CT.tabActive = document.querySelector('.active-tab.collection-tab')

        CT.prevTabIndex.push(CT.taskIndex) // history tabs

        tabState.selectedTask = tabState.tasks[CT.prevTabIndex[CT.prevTabIndex.length - 1]].id

    },
    selectFirstTabOnStart() {
        tabState.selectedTask = tabState.tasks[0].id
        switchToTask(tabState.selectedTask)
        sessionRestore.save()
    },
    loadTasks() {
        tasks.get().forEach(function (task, index) {
            var el = getTaskElement(task, index)
            taskContainer.appendChild(el)
            taskOverlay.dragula.containers.push(el.getElementsByClassName('task-tabs-container')[0])
        })
    },
    clickOnFirstCollection() {
        document.querySelector('[data-task-id="' + tasks.get()[0].id + ' "]').click()
    },
    add5() {
        if (tabState.tasks.length < 5) {
            let id = tabState.selectedTask
            for (let i = tabState.tasks.length; i != 5; i++) {
                tasks.add()
            }
        }
    },
    overviewTaskNameClickEnterE(e) {
        say.m('CT.overviewTaskNameClickEnterE()')

        let id = e.target.parentElement.parentElement.getAttribute('data-task')
        let eTarget = e.target
        let eVal = e.target.value
        if (e.which == 13) {
            CT.render()
            for (let i = 0; i < tasks.get().length; i++) {
                if (tasks.get()[i].id == id) {
                    if (i <= 5) {
                        document.querySelector(`[data-index="${i}"]`).click()
                    }
                }
            }
        }
    },
    overviewTaskNameClickE(e) {
        say.m('CT.overviewTaskNameClickE()')

        let id = e.target.parentElement.parentElement.getAttribute('data-task')
        for (let i = 0; i < tasks.get().length; i++) {
            if (tasks.get()[i].id == id) {
                if (i <= 5) {
                    CT.collectionTopClickOnCollectionTab(i)
                    CT.collectionLeftFocusOnCollectionTabInput(id)
                }
            }
        }
    },

    collectionTopClickOnCollectionTab(index) {
        document.querySelector(`[data-index="${index}"]`).click()
    },
    collectionTopRemoveBGSelectedAll() {
        let elems = document.querySelectorAll(".active-tab");
        for (var i = 0; i < elems.length; i++)
            elems[i].classList.remove('active-tab');
    },
    collectionTopAddBGSelected(index) {
        CT.collectionTopRemoveBGSelectedAll()
        document.querySelector(`[data-index="${index}"]`).classList.add('active-tab')
    },
    collectionTopAddBGSelectedById(id_) {
        CT.collectionTopRemoveBGSelectedAll()
        document.querySelector(`[data-task-id="${id_} "]`).classList.add('active-tab')
    },
    collectionLeftFocusOnCollectionTabInput(id) {
        document.querySelector(`[data-task="${id}"] input`).focus()
    },
    addCollectionTab() {
        say.m('CT.addCollectionTab()')

        let thereIsCollection = false
        for (let i = 0; i < tabState.tasks.length; i++) {
            if (tabState.tasks[i].id == tabState.selectedTask) {
                for (let j = 0; j < tabState.tasks[i].tabs.length; j++) {
                    if (tabState.tasks[i].tabs[j].title == 'Collection') {
                        thereIsCollection = true
                    }

                }
                if (tabState.tasks[i].tabs.length == 2) {
                    for (let j = 0; j < tabState.tasks[i].tabs.length; j++) {
                        if (tabState.tasks[i].tabs[j].title == 'DuckDuckGo') {
                            destroyTab(tabState.tasks[i].tabs[j].id)
                        }

                    }
                }
            }

        }
        if (thereIsCollection == false && document.querySelector('.active-tab ').className.indexOf("editing") != -1) {
            addTab(tabs.add({
                url: 'file:///' + __dirname + '/pages/collection/index.html',
                title: 'Collection'
            }, tabs[0]), {enterEditMode: false})
            CT.addClassEditing()
        }

    },

    render() {
        say.m('CT.render()')

        if (CT.inputFocus == false) {
            let collectionTabsHTML = []
            for (let i = 0; i < tabState.tasks.length; i++) {
                let val = tabState.tasks[i].name
                if (val == null || val == 'null')
                    val = ''
                let title = `<input placeholder="●●●" type="text" class="collectionTabInput" data-id="${tabState.tasks[i].id}" value="${val}" disabled="true">` || `<input type="text" placeholder="●●●" class="collectionTabInput" data-id="${tabState.tasks[i].id}" value="${val}"  disabled="true"> <svg width="23.9px" height="5.6px">23.9 5.6 <use xlink:href="icons/svg/miniature-controls.svg#ellipsis-big"></use></svg>`

                collectionTabsHTML.push('
' + title + '
')
                // collectionTabsHTML.push('
' + title + '
')
            }
            document.getElementById('collection-tabs').innerHTML = collectionTabsHTML.join('')

            CT.renderOverlay()

            eventEmitter.emit('render')

        }
    },
    renderOverlay() {
        say.m('CT.renderOverlay()')

        eventEmitter.emit('renderOverlay')

        if (taskOverlay.inputFocus) {
            if (document.querySelector('#task-overlay').getAttribute('hidden') == null)
                taskOverlay.show()
        }

        eventEmitter.emit('render')

    }

}
CT.start()

<|endoftext|>


<commit_before>'use strict';

var DEBUG = false;
var LOADING_ICON_CLASS_NAME = 'kindlish-loading-icon';
var debug = DEBUG ? console.log.bind(console) : (function() {});

debug('kindlish start');

var port = chrome.extension.connect();
var mapAsinToPlaceholders = {};

chrome.extension.sendMessage({action: 'isAccepted'}, function(isAccepted) {
  // Confirm that user already accepted EULA
  if (!isAccepted) {
    return; // do nothing
  }

  port.onMessage.addListener(onRecievedMessage);
  addKindleButtons(document);
  observePager();
  observeAutoPagerize();
});

function addKindleButtons(rootNode) {
  // for design since 2014
  addKindleButtonsToLinks(
    rootNode.querySelectorAll('a[id^=itemName_][href^="/dp/"], td a[href^="/dp/"]'));

  // for design until 2013 (may work)
  addKindleButtonsToLinks(
    rootNode.querySelectorAll('.itemWrapper .productTitle a[href^="/dp/"]'));
}

function addKindleButtonsToLinks(linksToProduct) {
  var asins = [];

  debug(linksToProduct);

  Array.prototype.forEach.call(linksToProduct, function(linkToProduct) {
    if (linkToProduct.hasAttribute('data-found-by-find-ebook-edition')) {
      return;
    }
    // mark as found
    linkToProduct.setAttribute('data-found-by-find-ebook-edition', '');

    var asin = extractAsinFromLink(linkToProduct);
    if (!asin) {
      return; // ignore links not having asin
    }

    asins.push(asin);

    var loadingIcon = createLoadingIcon();
    if (linkToProduct.getAttribute('target')) {
      // preserve target attribute to use later if exists
      loadingIcon.setAttribute('data-target', linkToProduct.getAttribute('target'));
    }
    getParentOfButton(linkToProduct).appendChild(loadingIcon);

    mapAsinToPlaceholders[asin] = loadingIcon;
  });

  if (asins.length) {
    debug('sending from content');
    debug(asins);
    port.postMessage({'asins': asins, 'hostname': location.hostname});
  }
}

function onRecievedMessage(response) {
  if (response.error) {
    debug('error');
    onError(response);
  } else {
    debug('success');
    debug(response.items);
    onRecievedKindleEditions(response.items);
  }
}

function onError(response) {
  response.asins.forEach(function(asin) {
    var placeholder = mapAsinToPlaceholders[item.asin];

    var spanError = document.createElement('span');
    spanError.innerText = chrome.i18n.getMessage('errorAPI');
    spanError.setAttribute('style', 'color: #ccc');

    placeholder.parentNode.replaceChild(spanError, placeholder);
  });
}

function onRecievedKindleEditions(items) {
  items.forEach(function(item) {
    var placeholder = mapAsinToPlaceholders[item.asin];
    if (item.kindle) {
      var button = createKindleButton(item, placeholder.getAttribute('data-target'));
      placeholder.parentNode.replaceChild(button, placeholder);
    } else {
      placeholder.parentNode.removeChild(placeholder);
    }
  });
}

// ---- Observers ----

function observePager() {
  var wrapperObserver = new MutationObserver(function(mutations) {
    debug('mutations-wrapper');
    debug(mutations);
    mutations.forEach(function(mutation) {
      if (mutation.type == 'childList') {
        Array.prototype.forEach.call(mutation.addedNodes, function(addedNode) {
          debug(addedNode);
          // items are lazy loaded. So observe addedNode recursively by itemObserver
          itemObserver.disconnect();
          itemObserver.observe(addedNode, {childList: true, subtree: true});
        });
      }
    });
  });

  wrapperObserver.observe(document.querySelector('#item-page-wrapper'), {childList: true});

  var itemObserver = new MutationObserver(function(mutations) {
    debug('mutations-item');
    debug(mutations);
    mutations.forEach(function(mutation) {
      if (mutation.type == 'childList') {
        Array.prototype.forEach.call(mutation.addedNodes, function(addedNode) {
          debug(addedNode);
          if (addedNode.nodeType == 1 && addedNode.tagName == 'DIV') {
            // only when node is TAG, because sometimes TextNode is added
            addKindleButtons(addedNode);
          }
        });
      }
    });
  });
}

// currently this does not work
function observeAutoPagerize() {
  var observer = new MutationObserver(function(mutations) {
    debug('mutations-autopagerize');
    debug(mutations);
    mutations.forEach(function(mutation) {
      if (mutation.type == 'childList') {
        Array.prototype.forEach.call(mutation.addedNodes, function(addedNode) {
          debug(addedNode);
          addKindleButtons(addedNode);
        });
      }
    });
  });

  var containers = document.querySelectorAll('table.wlrdZeroTable');
  var targetOfAutopagerized = containers[containers.length - 1];
  if (targetOfAutopagerized) {
    observer.observe(targetOfAutopagerized.parentNode, {childList: true});
  }
}

// ---- Utils ----

function extractAsinFromLink(linkToProduct) {
  var match = linkToProduct.getAttribute('href').match(/\/dp\/(\w+)\//);
  return match[1];
}

// return the parent node where kindle button should be appended
function getParentOfButton(linkToProduct) {
  var parent = linkToProduct.parentNode;
  if (parent.classList.contains('clip-text')) {
    // return parentNode because button is not shown when the button is clip-text's child
    parent = parent.parentNode;
  }
  return parent;
}

function createLoadingIcon() {
  var loadingIcon = document.createElement('img');
  loadingIcon.setAttribute('src', chrome.extension.getURL('img/loading_icon.gif'));
  loadingIcon.setAttribute('class', LOADING_ICON_CLASS_NAME);
  return loadingIcon;
}

function createKindleButton(item, target) {
  var a = document.createElement('a');
  a.setAttribute('href', item.kindle.url);
  if (target) {
    a.setAttribute('target', target);
  }
  var img = document.createElement('img');
  var buttonFilename = 'img/kindle_button_' + chrome.i18n.getMessage('buttonLang') + '.png';
  img.setAttribute('src', chrome.extension.getURL(buttonFilename));
  img.alt = chrome.i18n.getMessage('buttonAlt');
  a.appendChild(img);

  return a;
}
<commit_msg>Fix error handling<commit_after>'use strict';

var DEBUG = false;
var LOADING_ICON_CLASS_NAME = 'kindlish-loading-icon';
var debug = DEBUG ? console.log.bind(console) : (function() {});

debug('kindlish start');

var port = chrome.extension.connect();
var mapAsinToPlaceholders = {};

chrome.extension.sendMessage({action: 'isAccepted'}, function(isAccepted) {
  // Confirm that user already accepted EULA
  if (!isAccepted) {
    return; // do nothing
  }

  port.onMessage.addListener(onRecievedMessage);
  addKindleButtons(document);
  observePager();
  observeAutoPagerize();
});

function addKindleButtons(rootNode) {
  // for design since 2014
  addKindleButtonsToLinks(
    rootNode.querySelectorAll('a[id^=itemName_][href^="/dp/"], td a[href^="/dp/"]'));

  // for design until 2013 (may work)
  addKindleButtonsToLinks(
    rootNode.querySelectorAll('.itemWrapper .productTitle a[href^="/dp/"]'));
}

function addKindleButtonsToLinks(linksToProduct) {
  var asins = [];

  debug(linksToProduct);

  Array.prototype.forEach.call(linksToProduct, function(linkToProduct) {
    if (linkToProduct.hasAttribute('data-found-by-find-ebook-edition')) {
      return;
    }
    // mark as found
    linkToProduct.setAttribute('data-found-by-find-ebook-edition', '');

    var asin = extractAsinFromLink(linkToProduct);
    if (!asin) {
      return; // ignore links not having asin
    }

    asins.push(asin);

    var loadingIcon = createLoadingIcon();
    if (linkToProduct.getAttribute('target')) {
      // preserve target attribute to use later if exists
      loadingIcon.setAttribute('data-target', linkToProduct.getAttribute('target'));
    }
    getParentOfButton(linkToProduct).appendChild(loadingIcon);

    mapAsinToPlaceholders[asin] = loadingIcon;
  });

  if (asins.length) {
    debug('sending from content');
    debug(asins);
    port.postMessage({'asins': asins, 'hostname': location.hostname});
  }
}

function onRecievedMessage(response) {
  if (response.error) {
    debug('error');
    onError(response);
  } else {
    debug('success');
    debug(response.items);
    onRecievedKindleEditions(response.items);
  }
}

function onError(response) {
  response.asins.forEach(function(asin) {
    var placeholder = mapAsinToPlaceholders[asin];

    var spanError = document.createElement('span');
    spanError.innerText = chrome.i18n.getMessage('errorAPI');
    spanError.setAttribute('style', 'color: #ccc');

    placeholder.parentNode.replaceChild(spanError, placeholder);
  });
}

function onRecievedKindleEditions(items) {
  items.forEach(function(item) {
    var placeholder = mapAsinToPlaceholders[item.asin];
    if (item.kindle) {
      var button = createKindleButton(item, placeholder.getAttribute('data-target'));
      placeholder.parentNode.replaceChild(button, placeholder);
    } else {
      placeholder.parentNode.removeChild(placeholder);
    }
  });
}

// ---- Observers ----

function observePager() {
  var wrapperObserver = new MutationObserver(function(mutations) {
    debug('mutations-wrapper');
    debug(mutations);
    mutations.forEach(function(mutation) {
      if (mutation.type == 'childList') {
        Array.prototype.forEach.call(mutation.addedNodes, function(addedNode) {
          debug(addedNode);
          // items are lazy loaded. So observe addedNode recursively by itemObserver
          itemObserver.disconnect();
          itemObserver.observe(addedNode, {childList: true, subtree: true});
        });
      }
    });
  });

  wrapperObserver.observe(document.querySelector('#item-page-wrapper'), {childList: true});

  var itemObserver = new MutationObserver(function(mutations) {
    debug('mutations-item');
    debug(mutations);
    mutations.forEach(function(mutation) {
      if (mutation.type == 'childList') {
        Array.prototype.forEach.call(mutation.addedNodes, function(addedNode) {
          debug(addedNode);
          if (addedNode.nodeType == 1 && addedNode.tagName == 'DIV') {
            // only when node is TAG, because sometimes TextNode is added
            addKindleButtons(addedNode);
          }
        });
      }
    });
  });
}

// currently this does not work
function observeAutoPagerize() {
  var observer = new MutationObserver(function(mutations) {
    debug('mutations-autopagerize');
    debug(mutations);
    mutations.forEach(function(mutation) {
      if (mutation.type == 'childList') {
        Array.prototype.forEach.call(mutation.addedNodes, function(addedNode) {
          debug(addedNode);
          addKindleButtons(addedNode);
        });
      }
    });
  });

  var containers = document.querySelectorAll('table.wlrdZeroTable');
  var targetOfAutopagerized = containers[containers.length - 1];
  if (targetOfAutopagerized) {
    observer.observe(targetOfAutopagerized.parentNode, {childList: true});
  }
}

// ---- Utils ----

function extractAsinFromLink(linkToProduct) {
  var match = linkToProduct.getAttribute('href').match(/\/dp\/(\w+)\//);
  return match[1];
}

// return the parent node where kindle button should be appended
function getParentOfButton(linkToProduct) {
  var parent = linkToProduct.parentNode;
  if (parent.classList.contains('clip-text')) {
    // return parentNode because button is not shown when the button is clip-text's child
    parent = parent.parentNode;
  }
  return parent;
}

function createLoadingIcon() {
  var loadingIcon = document.createElement('img');
  loadingIcon.setAttribute('src', chrome.extension.getURL('img/loading_icon.gif'));
  loadingIcon.setAttribute('class', LOADING_ICON_CLASS_NAME);
  return loadingIcon;
}

function createKindleButton(item, target) {
  var a = document.createElement('a');
  a.setAttribute('href', item.kindle.url);
  if (target) {
    a.setAttribute('target', target);
  }
  var img = document.createElement('img');
  var buttonFilename = 'img/kindle_button_' + chrome.i18n.getMessage('buttonLang') + '.png';
  img.setAttribute('src', chrome.extension.getURL(buttonFilename));
  img.alt = chrome.i18n.getMessage('buttonAlt');
  a.appendChild(img);

  return a;
}
<|endoftext|>


<commit_before>YUI.add('moodle-core-blocks', function(Y) {

    var AJAXURL = '/lib/ajax/blocks.php',
    CSS = {
        BLOCK : 'block',
        BLOCKREGION : 'block-region',
        BLOCKADMINBLOCK : 'block_adminblock',
        EDITINGMOVE : 'editing_move',
        HEADER : 'header',
        LIGHTBOX : 'lightbox',
        PAGECONTENT : 'page-content',
        REGIONCONTENT : 'region-content',
        SKIPBLOCK : 'skip-block',
        SKIPBLOCKTO : 'skip-block-to'
    }

    var DRAGBLOCK = function() {
        DRAGBLOCK.superclass.constructor.apply(this, arguments);
    };
    Y.extend(DRAGBLOCK, M.core.dragdrop, {
        skipnodetop : null,
        skipnodebottom : null,
        dragsourceregion : null,
        initializer : function(params) {
            // Set group for parent class
            this.groups = ['block'];
            this.samenodeclass = CSS.BLOCK;
            this.parentnodeclass = CSS.REGIONCONTENT;

            // Initialise blocks dragging
            var blockregionlist = Y.Node.all('#'+CSS.PAGECONTENT+' div.'+CSS.BLOCKREGION);

            if (blockregionlist.size() === 0) {
                return false;
            }

            // See if we are missing either of block regions,
            // if yes we need to add an empty one to use as target
            if (blockregionlist.size() != this.get('regions').length) {
                var blockregion = Y.Node.create('

')
                    .addClass(CSS.BLOCKREGION);
                var regioncontent = Y.Node.create('

')
                    .addClass(CSS.REGIONCONTENT);
                blockregion.appendChild(regioncontent);

                var regionid = this.get_region_id(blockregionlist.item(0));
                if (regionid === 'post') {
                    // pre block is missing, instert it before post
                    blockregion.setAttrs({id : 'region-pre'});
                    blockregionlist.item(0).insert(blockregion, 'before');
                    blockregionlist.unshift(blockregion);
                } else {
                    // post block is missing, instert it after pre
                    blockregion.setAttrs({id : 'region-post'});
                    blockregionlist.item(0).insert(blockregion, 'after');
                    blockregionlist.push(blockregion);
                }
            }

            blockregionlist.each(function(blockregionnode) {

                // Setting blockregion as droptarget (the case when it is empty)
                // The region-post (the right one)
                // is very narrow, so add extra padding on the left to drop block on it.
                var tar = new Y.DD.Drop({
                    node: blockregionnode.one('div.'+CSS.REGIONCONTENT),
                    groups: this.groups,
                    padding: '40 240 40 240'
                });

                var blocklist = blockregionnode.all('.'+CSS.BLOCK);
                blocklist.each(function(blocknode) {
                    var move = blocknode.one('a.'+CSS.EDITINGMOVE);
                    if (move) {
                        move.remove();
                        blocknode.one('.'+CSS.HEADER).setStyle('cursor', 'move');
                        // Make each div element in the list of blocks draggable
                        var dd = new Y.DD.Drag({
                            node: blocknode,
                            groups: this.groups,
                            // Make each div a Drop target too
                            target: true,
                            handles: ['.'+CSS.HEADER]
                        }).plug(Y.Plugin.DDProxy, {
                            // Don't move the node at the end of the drag
                            moveOnEnd: false
                        }).plug(Y.Plugin.DDConstrained, {
                            // Keep it inside the .course-content
                            constrain: '#'+CSS.PAGECONTENT
                        }).plug(Y.Plugin.DDWinScroll);
                    }
                }, this);
            }, this);
        },

        get_block_id : function(node) {
            return Number(node.get('id').replace(/inst/i, ''));
        },

        get_block_region : function(node) {
            return node.ancestor('div.'+CSS.BLOCKREGION).get('id').replace(/region/i, 'side');
        },

        get_region_id : function(node) {
            return node.get('id').replace(/region-/i, '');
        },

        drag_start : function(e) {
            // Get our drag object
            var drag = e.target;

            // Store the parent node of original drag node (block)
            // we will need it later for show/hide empty regions
            this.dragsourceregion = drag.get('node').ancestor('div.'+CSS.BLOCKREGION);

            // Determine skipnodes and store them
            if (drag.get('node').previous() && drag.get('node').previous().hasClass(CSS.SKIPBLOCK)) {
                this.skipnodetop = drag.get('node').previous();
            }
            if (drag.get('node').next() && drag.get('node').next().hasClass(CSS.SKIPBLOCKTO)) {
                this.skipnodebottom = drag.get('node').next();
            }
        },

        drop_over : function(e) {
            // Get a reference to our drag and drop nodes
            var drag = e.drag.get('node');
            var drop = e.drop.get('node');

            // We need to fix the case when parent drop over event has determined
            // 'goingup' and appended the drag node after admin-block.
            if (drop.hasClass(this.parentnodeclass) && drop.one('.'+CSS.BLOCKADMINBLOCK) && drop.one('.'+CSS.BLOCKADMINBLOCK).next('.'+CSS.BLOCK)) {
                drop.prepend(drag);
            }

            // Block is moved within the same region
            // stop here, no need to modify anything.
            if (this.dragsourceregion.contains(drop)) {
                return false;
            }

            // TODO: Fix this for the case when user drag block towards empty section,
            // then the section appears, then user chnages his mind and moving back to
            // original section. The opposite section remains opened and empty.

            var documentbody = Y.one('body');
            // Moving block towards hidden region-content, display it
            var regionname = this.get_region_id(this.dragsourceregion);
            if (documentbody.hasClass('side-'+regionname+'-only')) {
                documentbody.removeClass('side-'+regionname+'-only');
            }

            // Moving from empty region-content towards the opposite one,
            // hide empty one
            regionname = this.get_region_id(drop.ancestor('div.'+CSS.BLOCKREGION));
            if (this.dragsourceregion.all('.'+CSS.BLOCK).size() == 0) {
                if (!documentbody.hasClass('side-'+regionname+'-only')) {
                    documentbody.addClass('side-'+regionname+'-only');
                }
            }
        },

        drop_end : function(e) {
            // clear variables
            this.skipnodetop = null;
            this.skipnodebottom = null;
            this.dragsourceregion = null;
        },

        drag_dropmiss : function(e) {
            // Missed the target, but we assume the user intended to drop it
            // on the last last ghost node location, e.drag and e.drop should be
            // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
            this.drop_hit(e);
        },

        drop_hit : function(e) {
            var drag = e.drag;
            // Get a reference to our drag node
            var dragnode = drag.get('node');
            var dropnode = e.drop.get('node');

            // Amend existing skipnodes
            if (dragnode.previous() && dragnode.previous().hasClass(CSS.SKIPBLOCK)) {
                // the one that belongs to block below move below
                dragnode.insert(dragnode.previous(), 'after');
            }
            // Move original skipnodes
            if (this.skipnodetop) {
                dragnode.insert(this.skipnodetop, 'before');
            }
            if (this.skipnodebottom) {
                dragnode.insert(this.skipnodebottom, 'after');
            }

            // Add lightbox if it not there
            var lightbox = M.util.add_lightbox(Y, dragnode);

            // Prepare request parameters
            var params = {
                sesskey : M.cfg.sesskey,
                courseid : this.get('courseid'),
                pagelayout : this.get('pagelayout'),
                pagetype : this.get('pagetype'),
                action : 'move',
                bui_moveid : this.get_block_id(dragnode),
                bui_newregion : this.get_block_region(dropnode)
            };

            if (this.get('cmid')) {
                params.cmid = this.get('cmid');
            }

            if (dragnode.next('.'+this.samenodeclass) && !dragnode.next('.'+this.samenodeclass).hasClass(CSS.BLOCKADMINBLOCK)) {
                params.bui_beforeid = this.get_block_id(dragnode.next('.'+this.samenodeclass));
            }

            // Do AJAX request
            Y.io(M.cfg.wwwroot+AJAXURL, {
                method: 'POST',
                data: params,
                on: {
                    start : function(tid) {
                        lightbox.show();
                    },
                    success: function(tid, response) {
                        window.setTimeout(function(e) {
                            lightbox.hide();
                        }, 250);
                        try {
                            var responsetext = Y.JSON.parse(response.responseText);
                            if (responsetext.error) {
                                new M.core.ajaxException(responsetext);
                            }
                        } catch (e) {}
                    },
                    failure: function(tid, response) {
                        this.ajax_failure(response);
                        lightbox.hide();
                    }
                },
                context:this
            });
        }
    }, {
        NAME : 'core-blocks-dragdrop',
        ATTRS : {
            courseid : {
                value : null
            },
            cmid : {
                value : null
            },
            pagelayout : {
                value : null
            },
            pagetype : {
                value : null
            },
            regions : {
                value : null
            }
        }
    });

    M.core_blocks = M.core_blocks || {};
    M.core_blocks.init_dragdrop = function(params) {
        new DRAGBLOCK(params);
    }
}, '@VERSION@', {requires:['base', 'node', 'io', 'dom', 'dd', 'dd-scroll', 'moodle-core-dragdrop', 'moodle-enrol-notification']});

<commit_msg>MDL-33890 Make course blocks less theme dependant<commit_after>YUI.add('moodle-core-blocks', function(Y) {

    var AJAXURL = '/lib/ajax/blocks.php',
    CSS = {
        BLOCK : 'block',
        BLOCKREGION : 'block-region',
        BLOCKADMINBLOCK : 'block_adminblock',
        EDITINGMOVE : 'editing_move',
        HEADER : 'header',
        LIGHTBOX : 'lightbox',
        REGIONCONTENT : 'region-content',
        SKIPBLOCK : 'skip-block',
        SKIPBLOCKTO : 'skip-block-to'
    }

    var DRAGBLOCK = function() {
        DRAGBLOCK.superclass.constructor.apply(this, arguments);
    };
    Y.extend(DRAGBLOCK, M.core.dragdrop, {
        skipnodetop : null,
        skipnodebottom : null,
        dragsourceregion : null,
        initializer : function(params) {
            // Set group for parent class
            this.groups = ['block'];
            this.samenodeclass = CSS.BLOCK;
            this.parentnodeclass = CSS.REGIONCONTENT;

            // Initialise blocks dragging
            // Find all block regions on the page
            var blockregionlist = Y.Node.all('div.'+CSS.BLOCKREGION);

            if (blockregionlist.size() === 0) {
                return false;
            }

            // See if we are missing either of block regions,
            // if yes we need to add an empty one to use as target
            if (blockregionlist.size() != this.get('regions').length) {
                var blockregion = Y.Node.create('

')
                    .addClass(CSS.BLOCKREGION);
                var regioncontent = Y.Node.create('

')
                    .addClass(CSS.REGIONCONTENT);
                blockregion.appendChild(regioncontent);

                var regionid = this.get_region_id(blockregionlist.item(0));
                if (regionid === 'post') {
                    // pre block is missing, instert it before post
                    blockregion.setAttrs({id : 'region-pre'});
                    blockregionlist.item(0).insert(blockregion, 'before');
                    blockregionlist.unshift(blockregion);
                } else {
                    // post block is missing, instert it after pre
                    blockregion.setAttrs({id : 'region-post'});
                    blockregionlist.item(0).insert(blockregion, 'after');
                    blockregionlist.push(blockregion);
                }
            }

            blockregionlist.each(function(blockregionnode) {

                // Setting blockregion as droptarget (the case when it is empty)
                // The region-post (the right one)
                // is very narrow, so add extra padding on the left to drop block on it.
                var tar = new Y.DD.Drop({
                    node: blockregionnode.one('div.'+CSS.REGIONCONTENT),
                    groups: this.groups,
                    padding: '40 240 40 240'
                });

                var blocklist = blockregionnode.all('.'+CSS.BLOCK);
                blocklist.each(function(blocknode) {
                    var move = blocknode.one('a.'+CSS.EDITINGMOVE);
                    if (move) {
                        move.remove();
                        blocknode.one('.'+CSS.HEADER).setStyle('cursor', 'move');
                        // Make each div element in the list of blocks draggable
                        var dd = new Y.DD.Drag({
                            node: blocknode,
                            groups: this.groups,
                            // Make each div a Drop target too
                            target: true,
                            handles: ['.'+CSS.HEADER]
                        }).plug(Y.Plugin.DDProxy, {
                            // Don't move the node at the end of the drag
                            moveOnEnd: false
                        }).plug(Y.Plugin.DDWinScroll);
                    }
                }, this);
            }, this);
        },

        get_block_id : function(node) {
            return Number(node.get('id').replace(/inst/i, ''));
        },

        get_block_region : function(node) {
            return node.ancestor('div.'+CSS.BLOCKREGION).get('id').replace(/region/i, 'side');
        },

        get_region_id : function(node) {
            return node.get('id').replace(/region-/i, '');
        },

        drag_start : function(e) {
            // Get our drag object
            var drag = e.target;

            // Store the parent node of original drag node (block)
            // we will need it later for show/hide empty regions
            this.dragsourceregion = drag.get('node').ancestor('div.'+CSS.BLOCKREGION);

            // Determine skipnodes and store them
            if (drag.get('node').previous() && drag.get('node').previous().hasClass(CSS.SKIPBLOCK)) {
                this.skipnodetop = drag.get('node').previous();
            }
            if (drag.get('node').next() && drag.get('node').next().hasClass(CSS.SKIPBLOCKTO)) {
                this.skipnodebottom = drag.get('node').next();
            }
        },

        drop_over : function(e) {
            // Get a reference to our drag and drop nodes
            var drag = e.drag.get('node');
            var drop = e.drop.get('node');

            // We need to fix the case when parent drop over event has determined
            // 'goingup' and appended the drag node after admin-block.
            if (drop.hasClass(this.parentnodeclass) && drop.one('.'+CSS.BLOCKADMINBLOCK) && drop.one('.'+CSS.BLOCKADMINBLOCK).next('.'+CSS.BLOCK)) {
                drop.prepend(drag);
            }

            // Block is moved within the same region
            // stop here, no need to modify anything.
            if (this.dragsourceregion.contains(drop)) {
                return false;
            }

            // TODO: Hiding-displaying block region only works for base theme blocks
            // (region-pre, region-post) at the moment. It should be improved
            // to work with custom block regions as well.

            // TODO: Fix this for the case when user drag block towards empty section,
            // then the section appears, then user chnages his mind and moving back to
            // original section. The opposite section remains opened and empty.

            var documentbody = Y.one('body');
            // Moving block towards hidden region-content, display it
            var regionname = this.get_region_id(this.dragsourceregion);
            if (documentbody.hasClass('side-'+regionname+'-only')) {
                documentbody.removeClass('side-'+regionname+'-only');
            }

            // Moving from empty region-content towards the opposite one,
            // hide empty one (only for region-pre, region-post areas at the moment).
            regionname = this.get_region_id(drop.ancestor('div.'+CSS.BLOCKREGION));
            if (this.dragsourceregion.all('.'+CSS.BLOCK).size() == 0 && this.dragsourceregion.get('id').match(/(region-pre|region-post)/i)) {
                if (!documentbody.hasClass('side-'+regionname+'-only')) {
                    documentbody.addClass('side-'+regionname+'-only');
                }
            }
        },

        drop_end : function(e) {
            // clear variables
            this.skipnodetop = null;
            this.skipnodebottom = null;
            this.dragsourceregion = null;
        },

        drag_dropmiss : function(e) {
            // Missed the target, but we assume the user intended to drop it
            // on the last last ghost node location, e.drag and e.drop should be
            // prepared by global_drag_dropmiss parent so simulate drop_hit(e).
            this.drop_hit(e);
        },

        drop_hit : function(e) {
            var drag = e.drag;
            // Get a reference to our drag node
            var dragnode = drag.get('node');
            var dropnode = e.drop.get('node');

            // Amend existing skipnodes
            if (dragnode.previous() && dragnode.previous().hasClass(CSS.SKIPBLOCK)) {
                // the one that belongs to block below move below
                dragnode.insert(dragnode.previous(), 'after');
            }
            // Move original skipnodes
            if (this.skipnodetop) {
                dragnode.insert(this.skipnodetop, 'before');
            }
            if (this.skipnodebottom) {
                dragnode.insert(this.skipnodebottom, 'after');
            }

            // Add lightbox if it not there
            var lightbox = M.util.add_lightbox(Y, dragnode);

            // Prepare request parameters
            var params = {
                sesskey : M.cfg.sesskey,
                courseid : this.get('courseid'),
                pagelayout : this.get('pagelayout'),
                pagetype : this.get('pagetype'),
                action : 'move',
                bui_moveid : this.get_block_id(dragnode),
                bui_newregion : this.get_block_region(dropnode)
            };

            if (this.get('cmid')) {
                params.cmid = this.get('cmid');
            }

            if (dragnode.next('.'+this.samenodeclass) && !dragnode.next('.'+this.samenodeclass).hasClass(CSS.BLOCKADMINBLOCK)) {
                params.bui_beforeid = this.get_block_id(dragnode.next('.'+this.samenodeclass));
            }

            // Do AJAX request
            Y.io(M.cfg.wwwroot+AJAXURL, {
                method: 'POST',
                data: params,
                on: {
                    start : function(tid) {
                        lightbox.show();
                    },
                    success: function(tid, response) {
                        window.setTimeout(function(e) {
                            lightbox.hide();
                        }, 250);
                        try {
                            var responsetext = Y.JSON.parse(response.responseText);
                            if (responsetext.error) {
                                new M.core.ajaxException(responsetext);
                            }
                        } catch (e) {}
                    },
                    failure: function(tid, response) {
                        this.ajax_failure(response);
                        lightbox.hide();
                    }
                },
                context:this
            });
        }
    }, {
        NAME : 'core-blocks-dragdrop',
        ATTRS : {
            courseid : {
                value : null
            },
            cmid : {
                value : null
            },
            pagelayout : {
                value : null
            },
            pagetype : {
                value : null
            },
            regions : {
                value : null
            }
        }
    });

    M.core_blocks = M.core_blocks || {};
    M.core_blocks.init_dragdrop = function(params) {
        new DRAGBLOCK(params);
    }
}, '@VERSION@', {requires:['base', 'node', 'io', 'dom', 'dd', 'dd-scroll', 'moodle-core-dragdrop', 'moodle-enrol-notification']});

<|endoftext|>


<commit_before>// Mozilla User Preferences
//dennyhalim.com
//http://kb.mozillazine.org/User.js_file
//http://kb.mozillazine.org/Locking_preferences
//https://developer.mozilla.org/en-US/docs/Mozilla/Preferences/A_brief_guide_to_Mozilla_preferences
pref("app.update.channel", "esr");
user_pref("browser.cache.compression_level", 1);
user_pref("browser.sessionhistory.max_entries", 10);
user_pref("devtools.memory.enabled", false);
user_pref("browser.cache.memory.enable", false);
user_pref("network.cookie.cookieBehavior", 3);
user_pref("network.cookie.lifetimePolicy", 2);
user_pref("privacy.clearOnShutdown.cache", true);
user_pref("privacy.clearOnShutdown.offlineApps", true);
user_pref("privacy.sanitize.pending", "[{\"id\":\"shutdown\",\"itemsToClear\":[\"cache\",\"offlineApps\"],\"options\":{}}]");
//user_pref("privacy.sanitize.pending", "[{\"id\":\"shutdown\",\"itemsToClear\":[\"cache\",\"cookies\",\"offlineApps\",\"formdata\",\"sessions\",\"siteSettings\"],\"options\":{}}]");
user_pref("privacy.sanitize.sanitizeOnShutdown", true);
user_pref("privacy.donottrackheader.enabled", true);
user_pref("privacy.trackingprotection.enabled", true);
user_pref("privacy.trackingprotection.pbmode.enabled", true);
user_pref("dom.webnotifications.enabled", false);
user_pref("dom.webnotifications.serviceworker.enabled", false);
user_pref("dom.serviceWorkers.enabled", false);
user_pref("browser.urlbar.placeholderName", "DuckDuckGo");
user_pref("geo.enabled", false);
user_pref("geo.provider.ms-windows-location", false);
user_pref("geo.provider.use_corelocation", false);
user_pref("geo.provider.use_gpsd", false);
user_pref("toolkit.telemetry.unified", false);
user_pref("toolkit.telemetry.enabled", false);
user_pref("toolkit.telemetry.archive.enabled", false);
user_pref("network.trr.mode", 2);
user_pref("network.trr.uri", "https://doh.cleanbrowsing.org/doh/adult-filter/");  //https://cleanbrowsing.org/dnsoverhttps
user_pref("dom.netinfo.enabled", false);
user_pref("media.video_stats.enabled", false);
//user_pref("dom.maxHardwareConcurrency", 1); //faster on slow devices
user_pref("dom.battery.enabled", false);
user_pref("dom.telephony.enabled", false);
user_pref("beacon.enabled", false);
user_pref("device.sensors.enabled", false);
user_pref("dom.vibrator.enabled", false);
user_pref("dom.enable_resource_timing", false);
<commit_msg>Update firefox-user.js<commit_after>// Mozilla User Preferences
//dennyhalim.com
//http://kb.mozillazine.org/User.js_file
//http://kb.mozillazine.org/Locking_preferences
//https://developer.mozilla.org/en-US/docs/Mozilla/Preferences/A_brief_guide_to_Mozilla_preferences
pref("app.update.channel", "esr");
user_pref("browser.cache.compression_level", 1);
user_pref("browser.sessionhistory.max_entries", 10);
//user_pref("devtools.memory.enabled", false);
user_pref("browser.cache.memory.enable", false); //very usefull if you have < 4GB RAM
user_pref("network.cookie.cookieBehavior", 3);
user_pref("network.cookie.lifetimePolicy", 2);
user_pref("privacy.clearOnShutdown.cache", true);
user_pref("privacy.clearOnShutdown.offlineApps", true);
user_pref("privacy.sanitize.pending", "[{\"id\":\"shutdown\",\"itemsToClear\":[\"cache\",\"offlineApps\"],\"options\":{}}]");
//user_pref("privacy.sanitize.pending", "[{\"id\":\"shutdown\",\"itemsToClear\":[\"cache\",\"cookies\",\"offlineApps\",\"formdata\",\"sessions\",\"siteSettings\"],\"options\":{}}]");
user_pref("privacy.sanitize.sanitizeOnShutdown", true);
user_pref("privacy.donottrackheader.enabled", true);
user_pref("privacy.trackingprotection.enabled", true);
user_pref("privacy.trackingprotection.pbmode.enabled", true);
user_pref("dom.webnotifications.enabled", false);
user_pref("dom.webnotifications.serviceworker.enabled", false);
user_pref("dom.serviceWorkers.enabled", false);
user_pref("browser.urlbar.placeholderName", "DuckDuckGo");
user_pref("geo.enabled", false);
user_pref("geo.provider.ms-windows-location", false);
user_pref("geo.provider.use_corelocation", false);
user_pref("geo.provider.use_gpsd", false);
user_pref("toolkit.telemetry.unified", false);
user_pref("toolkit.telemetry.enabled", false);
user_pref("toolkit.telemetry.archive.enabled", false);
user_pref("network.trr.mode", 2);
user_pref("network.trr.uri", "https://doh.cleanbrowsing.org/doh/adult-filter/");  //https://cleanbrowsing.org/dnsoverhttps
user_pref("dom.netinfo.enabled", false);
user_pref("media.video_stats.enabled", false);
//user_pref("dom.maxHardwareConcurrency", 1); //faster on slow devices
user_pref("dom.battery.enabled", false);
user_pref("dom.telephony.enabled", false);
user_pref("beacon.enabled", false);
user_pref("device.sensors.enabled", false);
user_pref("dom.vibrator.enabled", false);
user_pref("dom.enable_resource_timing", false);
<|endoftext|>


<commit_before>/*!
 * Start Bootstrap - Freelancer v3.3.7+1 (http://startbootstrap.com/template-overviews/freelancer)
 * Copyright 2013-2016 Start Bootstrap
 * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE)
 */
!function(o){"use strict";o(".page-scroll a").bind("click",function(t){var l=o(this);o("html, body").stop().animate({scrollTop:o(l.attr("href")).offset().top-50},1250,"easeInOutExpo"),t.preventDefault()}),o("body").scrollspy({target:".navbar-fixed-top",offset:51}),o(".navbar-collapse ul li a").click(function(){o(".navbar-toggle:visible").click()}),o("#mainNav").affix({offset:{top:100}}),o(function(){o("body").on("input propertychange",".floating-label-form-group",function(t){o(this).toggleClass("floating-label-form-group-with-value",!!o(t.target).val())}).on("focus",".floating-label-form-group",function(){o(this).addClass("floating-label-form-group-with-focus")}).on("blur",".floating-label-form-group",function(){o(this).removeClass("floating-label-form-group-with-focus")})})}(jQuery);<commit_msg>Update freelancer.min.js<commit_after>/*!
 * Start Bootstrap - Freelancer v3.3.7+1 (http://startbootstrap.com/template-overviews/freelancer)
 * Copyright 2013-2016 Start Bootstrap
 * Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE)
 */
!function(o){"use strict";o(".page-scroll a").bind("click",function(t){var l=o(this);o("html, body").stop().animate({scrollTop:o(l.attr("href")).offset().top-50},1250,"easeInOutExpo"),t.preventDefault()}),o("body").scrollspy({target:".navbar-fixed-top",offset:51}),o(".navbar-collapse ul li a").click(function(){o(".navbar-toggle:visible").click()}),o("#mainNav").affix({offset:{top:100}}),o(function(){o("body").on("input propertychange",".floating-label-form-group",function(t){o(this).toggleClass("floating-label-form-group-with-value",!!o(t.target).val())}).on("focus",".floating-label-form-group",function(){o(this).addClass("floating-label-form-group-with-focus")}).on("blur",".floating-label-form-group",function(){o(this).removeClass("floating-label-form-group-with-focus")})})

            $(function() {
    var topBtn = $('#page-top');
    topBtn.hide();
    //スクロールが500に達したらボタン表示
    $(window).scroll(function () {
        if ($(this).scrollTop() > 500) {
            topBtn.fadeIn();
        } else {
            topBtn.fadeOut();
        }
    });
    //スクロールしてトップ
    topBtn.click(function () {
        $('body,html').animate({
            scrollTop: 0
        }, 500);
        return false;
    });
});

            }(jQuery);
<|endoftext|>