<commit_before>/*
Input Mask plugin extentions
http://github.com/RobinHerbots/jquery.inputmask
Copyright (c) 2010 Robin Herbots
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)

Optional extentions on the jquery.inputmask base
*/
(function($) {
    //extra definitions
    $.extend($.inputmask.defaults.definitions, {
        'h': { //hours
            validator: "[01][0-9]|2[0-3]",
            cardinality: 2,
            prevalidator: [{ validator: "[0-2]", cardinality: 1}]
        },
        's': { //seconds || minutes
            validator: "[0-5][0-9]",
            cardinality: 2,
            prevalidator: [{ validator: "[0-5]", cardinality: 1}]
        },
        'd': { //day
            validator: "0[1-9]|[12][0-9]|3[01]",
            cardinality: 2,
            prevalidator: [{ validator: "[0-3]", cardinality: 1}]
        },
        'm': { //month
            validator: "0[1-9]|1[012]",
            cardinality: 2,
            prevalidator: [{ validator: "[01]", cardinality: 1}]
        },
        'y': { //year
            validator: "(19|20)\\d\\d",
            cardinality: 4,
            prevalidator: [
                        { validator: "[12]", cardinality: 1 },
                        { validator: "(19|20)", cardinality: 2 },
                        { validator: "(19|20)\\d", cardinality: 3 }
                        ]
        },
        'A': {
            validator: "[A-Za-z]",
            cardinality: 1,
            casing: "upper"
        }
    });
    //aliases
    $.extend($.inputmask.defaults.aliases, {
        'dd/mm/yyyy': {
            mask: "d/m/y",
            placeholder: "dd/mm/yyyy",
            regex: {
                month: new RegExp("((0[1-9]|[12][0-9])\/(0[1-9]|1[012]))|(30\/(0[13-9]|1[012]))|(31\/(0[13578]|1[02]))"),
                year: new RegExp("(19|20)\\d\\d"),
                daypre: new RegExp("[0-3]"),
                day: new RegExp("0[1-9]|[12][0-9]|3[01]")
            },
            definitions: {
                'd': { //day
                    validator: function(chrs, buffer, pos, strict, opts) {
                        return opts.regex.day.test(chrs);
                    },
                    cardinality: 2,
                    prevalidator: [{ validator: function(chrs, buffer, pos, strict, opts) {
                        var isValid = opts.regex.daypre.test(chrs);
                        if (!strict && !isValid) {
                            isValid = opts.regex.day.test("0" + chrs);
                            if (isValid) {
                                buffer[pos] = "0";
                                pos++;
                                return pos;
                            }
                        }
                        return isValid;
                    }, cardinality: 1}]
                    },
                    'm': { //month
                        validator: function(chrs, buffer, pos, strict, opts) {
                            var dayValue = buffer.join('').substr(0, 3);
                            return opts.regex.month.test(dayValue + chrs);
                        },
                        cardinality: 2,
                        prevalidator: [{ validator: "[01]", cardinality: 1}]
                    },
                    'y': { //year
                        validator: function(chrs, buffer, pos, strict, opts) {
                            if (opts.regex.year.test(chrs)) {
                                var dayMonthValue = buffer.join('').substr(0, 6);
                                if (dayMonthValue != "29/02/")
                                    return true;
                                else {
                                    var year = parseInt(chrs);  //detect leap year
                                    if (year % 4 == 0)
                                        if (year % 100 == 0)
                                        if (year % 400 == 0)
                                        return true;
                                    else return false;
                                    else return true;
                                    else return false;
                                }
                            } else return false;
                        },
                        cardinality: 4,
                        prevalidator: [
                        { validator: "[12]", cardinality: 1 },
                        { validator: "(19|20)", cardinality: 2 },
                        { validator: "(19|20)\\d", cardinality: 3 }
                        ]
                    }
                },
                insertMode: false,
                autoUnmask: false
            },
            'mm/dd/yyyy': {
                mask: "m/d/y",
                placeholder: "mm/dd/yyyy",
                regex: {
                    day: new RegExp("((0[1-9]|1[012])\/(0[1-9]|[12][0-9]))|((0[13-9]|1[012])\/30)|((0[13578]|1[02])\/31)"),
                    daypre: new RegExp("((0[13-9]|1[012])\/[0-3])|(02\/[0-2])"),
                    year: new RegExp("(19|20)\\d\\d")
                },
                definitions: {
                    'd': { //day
                        validator: function(chrs, buffer, pos, strict, opts) {
                            var monthValue = buffer.join('').substr(0, 3);
                            return opts.regex.day.test(monthValue + chrs);
                        },
                        cardinality: 2,
                        prevalidator: [{ validator: function(chrs, buffer, pos, strict, opts) {
                            var monthValue = buffer.join('').substr(0, 3);
                            return opts.regex.daypre.test(monthValue + chrs);
                        },
                            cardinality: 1}]
                        },
                        'y': { //year
                            validator: function(chrs, buffer, pos, strict, opts) {
                                if (opts.regex.year.test(chrs)) {
                                    var monthDayValue = buffer.join('').substr(0, 6);
                                    if (monthDayValue != "02/29/")
                                        return true;
                                    else {
                                        var year = parseInt(chrs);  //detect leap year
                                        if (year % 4 == 0)
                                            if (year % 100 == 0)
                                            if (year % 400 == 0)
                                            return true;
                                        else return false;
                                        else return true;
                                        else return false;
                                    }
                                } else return false;
                            },
                            cardinality: 4,
                            prevalidator: [
                        { validator: "[12]", cardinality: 1 },
                        { validator: "(19|20)", cardinality: 2 },
                        { validator: "(19|20)\\d", cardinality: 3 }
                        ]
                        }
                    },
                    insertMode: false,
                    autoUnmask: false
                },
                'hh:mm:ss': {
                    mask: "h:s:s",
                    autoUnmask: false
                },
                'hh:mm': {
                    mask: "h:s",
                    autoUnmask: false
                },
                'date': {
                    alias: "dd/mm/yyyy" // "mm/dd/yyyy"
                },
                'datetime': {
                    mask: "d/m/y h:s",
                    placeholder: "dd/mm/yyyy hh:mm",
                    regex: {
                        month: new RegExp("((0[1-9]|[12][0-9])\/(0[1-9]|1[012]))|(30\/(0[13-9]|1[012]))|(31\/(0[13578]|1[02]))"),
                        year: new RegExp("(19|20)\\d\\d")
                    },
                    definitions: {
                        'm': { //month
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var dayValue = buffer.join('').substr(0, 3);
                                return opts.regex.month.test(dayValue + chrs);
                            },
                            cardinality: 2,
                            prevalidator: [{ validator: "[01]", cardinality: 1}]
                        },
                        'y': { //year
                            validator: function(chrs, buffer, pos, strict, opts) {
                                if (opts.regex.year.test(chrs)) {
                                    var dayMonthValue = buffer.join('').substr(0, 6);
                                    if (dayMonthValue != "29/02/")
                                        return true;
                                    else {
                                        var year = parseInt(chrs);  //detect leap year
                                        if (year % 4 == 0)
                                            if (year % 100 == 0)
                                            if (year % 400 == 0)
                                            return true;
                                        else return false;
                                        else return true;
                                        else return false;
                                    }
                                } else return false;
                            },
                            cardinality: 4,
                            prevalidator: [
                        { validator: "[12]", cardinality: 1 },
                        { validator: "(19|20)", cardinality: 2 },
                        { validator: "(19|20)\\d", cardinality: 3 }
                        ]
                        }
                    },
                    insertMode: false,
                    autoUnmask: false
                },
                //number aliases by Dean (datimson)
                'decimal': {
                    mask: "~",
                    placeholder: "",
                    repeat: 10,
                    greedy: false,
                    radixPoint: "\.", // | ","
                    regex: {
                        real: function(radixPoint) { return new RegExp("^([\+\-]?[0-9]*[" + radixPoint + "]?[0-9]*)$"); }
                    },
                    definitions: {
                        '~': { //real number
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var myBuffer = buffer.slice();
                                myBuffer.splice(pos, 0, chrs);
                                var test = myBuffer.join('');
                                var isValid = opts.regex.real(opts.radixPoint).test(test);
                                return isValid;
                            },
                            cardinality: 1,
                            prevalidator: null
                        }
                    },
                    insertMode: true
                },
                'non-negative-decimal': {
                    mask: "~",
                    placeholder: "",
                    repeat: 10,
                    greedy: false,
                    radixPoint: "\.", // | ","
                    regex: {
                        decimal: function(radixPoint) { return new RegExp("^([0-9]+[" + radixPoint + "]?[0-9]*)$"); }
                    },
                    definitions: {
                        '~': {
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var myBuffer = buffer.slice();
                                myBuffer.splice(pos, 0, chrs);
                                var test = myBuffer.join('');
                                var isValid = opts.regex.decimal(opts.radixPoint).test(test);
                                return isValid;
                            },
                            cardinality: 1,
                            prevalidator: null
                        }
                    },
                    insertMode: true
                },
                'integer': {
                    mask: "~",
                    placeholder: "",
                    repeat: 10,
                    greedy: false,
                    numericInput: true,
                    regex: {
                        integer: new RegExp("^([\+\-]?[0-9]*)$")
                    },
                    definitions: {
                        '~': {
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var myBuffer = buffer.slice();
                                myBuffer.splice(pos, 0, chrs);
                                var test = myBuffer.join('');
                                var isValid = opts.regex.integer.test(test);
                                return isValid;
                            },
                            cardinality: 1,
                            prevalidator: null
                        }
                    },
                    insertMode: true
                }
            });
        })(jQuery);<commit_msg>add autofill to dd/mm/yyyy & mm/dd/yyyy aliases<commit_after>/*
Input Mask plugin extentions
http://github.com/RobinHerbots/jquery.inputmask
Copyright (c) 2010 Robin Herbots
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)

Optional extentions on the jquery.inputmask base
*/
(function($) {
    //extra definitions
    $.extend($.inputmask.defaults.definitions, {
        'h': { //hours
            validator: "[01][0-9]|2[0-3]",
            cardinality: 2,
            prevalidator: [{ validator: "[0-2]", cardinality: 1}]
        },
        's': { //seconds || minutes
            validator: "[0-5][0-9]",
            cardinality: 2,
            prevalidator: [{ validator: "[0-5]", cardinality: 1}]
        },
        'd': { //day
            validator: "0[1-9]|[12][0-9]|3[01]",
            cardinality: 2,
            prevalidator: [{ validator: "[0-3]", cardinality: 1}]
        },
        'm': { //month
            validator: "0[1-9]|1[012]",
            cardinality: 2,
            prevalidator: [{ validator: "[01]", cardinality: 1}]
        },
        'y': { //year
            validator: "(19|20)\\d\\d",
            cardinality: 4,
            prevalidator: [
                        { validator: "[12]", cardinality: 1 },
                        { validator: "(19|20)", cardinality: 2 },
                        { validator: "(19|20)\\d", cardinality: 3 }
                        ]
        },
        'A': {
            validator: "[A-Za-z]",
            cardinality: 1,
            casing: "upper"
        }
    });
    //aliases
    $.extend($.inputmask.defaults.aliases, {
        'dd/mm/yyyy': {
            mask: "d/m/y",
            placeholder: "dd/mm/yyyy",
            regex: {
            	monthpre: new RegExp("[01]"),
                month: new RegExp("((0[1-9]|[12][0-9])\/(0[1-9]|1[012]))|(30\/(0[13-9]|1[012]))|(31\/(0[13578]|1[02]))"),
                year: new RegExp("(19|20)\\d\\d"),
                daypre: new RegExp("[0-3]"),
                day: new RegExp("0[1-9]|[12][0-9]|3[01]")
            },
            definitions: {
                'd': { //day
                    validator: function(chrs, buffer, pos, strict, opts) {
                        return opts.regex.day.test(chrs);
                    },
                    cardinality: 2,
                    prevalidator: [{ validator: function(chrs, buffer, pos, strict, opts) {
                        var isValid = opts.regex.daypre.test(chrs);
                        if (!strict && !isValid) {
                            isValid = opts.regex.day.test("0" + chrs);
                            if (isValid) {
                                buffer[pos] = "0";
                                pos++;
                                return pos;
                            }
                        }
                        return isValid;
                    }, cardinality: 1}]
                    },
                    'm': { //month
                        validator: function(chrs, buffer, pos, strict, opts) {
                            var dayValue = buffer.join('').substr(0, 3);
                            return opts.regex.month.test(dayValue + chrs);
                        },
                        cardinality: 2,
                        prevalidator: [{ validator: function(chrs, buffer, pos, strict, opts) {
                        var isValid = opts.regex.monthpre.test(chrs);
                        if (!strict && !isValid) {
	                        var dayValue = buffer.join('').substr(0, 3);
                            isValid = opts.regex.month.test(dayValue + "0" + chrs);
                            if (isValid) {
                                buffer[pos] = "0";
                                pos++;
                                return pos;
                            }
                        }
                        return isValid;
                    }, cardinality: 1}]
                    },
                    'y': { //year
                        validator: function(chrs, buffer, pos, strict, opts) {
                            if (opts.regex.year.test(chrs)) {
                                var dayMonthValue = buffer.join('').substr(0, 6);
                                if (dayMonthValue != "29/02/")
                                    return true;
                                else {
                                    var year = parseInt(chrs);  //detect leap year
                                    if (year % 4 == 0)
                                        if (year % 100 == 0)
                                        if (year % 400 == 0)
                                        return true;
                                    else return false;
                                    else return true;
                                    else return false;
                                }
                            } else return false;
                        },
                        cardinality: 4,
                        prevalidator: [
                        { validator: "[12]", cardinality: 1 },
                        { validator: "(19|20)", cardinality: 2 },
                        { validator: "(19|20)\\d", cardinality: 3 }
                        ]
                    }
                },
                insertMode: false,
                autoUnmask: false
            },
            'mm/dd/yyyy': {
                mask: "m/d/y",
                placeholder: "mm/dd/yyyy",
                regex: {
                    day: new RegExp("((0[1-9]|1[012])\/(0[1-9]|[12][0-9]))|((0[13-9]|1[012])\/30)|((0[13578]|1[02])\/31)"),
                    daypre: new RegExp("((0[13-9]|1[012])\/[0-3])|(02\/[0-2])"),
                    month: new RegExp("0[1-9]|1[012]"),
                    monthpre: new RegExp("[01]"),
                    year: new RegExp("(19|20)\\d\\d")
                },
                definitions: {
                    'd': { //day
                        validator: function(chrs, buffer, pos, strict, opts) {
                            var monthValue = buffer.join('').substr(0, 3);
                            return opts.regex.day.test(monthValue + chrs);
                        },
                        cardinality: 2,
                        prevalidator: [{ validator: function(chrs, buffer, pos, strict, opts) {
                            var monthValue = buffer.join('').substr(0, 3);
                            var isValid = opts.regex.daypre.test(monthValue + chrs);
                            if (!strict && !isValid) {
                            	isValid = opts.regex.day.test(monthValue + "0" + chrs);
                            	if (isValid) {
                                	buffer[pos] = "0";
                                	pos++;
                                	return pos;
                            	}
                        	}
                        	return isValid;
                        },
                            cardinality: 1}]
                        },
          			'm': { //month
            				validator: function(chrs, buffer, pos, strict, opts) {
                      			return opts.regex.month.test(chrs);
                    		},
            				cardinality: 2,
            				prevalidator: [{ validator: function(chrs, buffer, pos, strict, opts) {
                        		var isValid = opts.regex.monthpre.test(chrs);
                        		if (!strict && !isValid) {
                            		isValid = opts.regex.month.test("0" + chrs);
                            		if (isValid) {
                                		buffer[pos] = "0";
                                		pos++;
                                		return pos;
                            		}
                        		}
                        		return isValid;
                    		}, cardinality: 1}]
        				},
                    'y': { //year
                            validator: function(chrs, buffer, pos, strict, opts) {
                                if (opts.regex.year.test(chrs)) {
                                    var monthDayValue = buffer.join('').substr(0, 6);
                                    if (monthDayValue != "02/29/")
                                        return true;
                                    else {
                                        var year = parseInt(chrs);  //detect leap year
                                        if (year % 4 == 0)
                                            if (year % 100 == 0)
                                            if (year % 400 == 0)
                                            return true;
                                        else return false;
                                        else return true;
                                        else return false;
                                    }
                                } else return false;
                            },
                            cardinality: 4,
                            prevalidator: [
                        { validator: "[12]", cardinality: 1 },
                        { validator: "(19|20)", cardinality: 2 },
                        { validator: "(19|20)\\d", cardinality: 3 }
                        ]
                        }
                    },
                    insertMode: false,
                    autoUnmask: false
                },
                'hh:mm:ss': {
                    mask: "h:s:s",
                    autoUnmask: false
                },
                'hh:mm': {
                    mask: "h:s",
                    autoUnmask: false
                },
                'date': {
                    alias: "dd/mm/yyyy" // "mm/dd/yyyy"
                },
                'datetime': {
                    mask: "d/m/y h:s",
                    placeholder: "dd/mm/yyyy hh:mm",
                    regex: {
                        month: new RegExp("((0[1-9]|[12][0-9])\/(0[1-9]|1[012]))|(30\/(0[13-9]|1[012]))|(31\/(0[13578]|1[02]))"),
                        year: new RegExp("(19|20)\\d\\d")
                    },
                    definitions: {
                        'm': { //month
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var dayValue = buffer.join('').substr(0, 3);
                                return opts.regex.month.test(dayValue + chrs);
                            },
                            cardinality: 2,
                            prevalidator: [{ validator: "[01]", cardinality: 1}]
                        },
                        'y': { //year
                            validator: function(chrs, buffer, pos, strict, opts) {
                                if (opts.regex.year.test(chrs)) {
                                    var dayMonthValue = buffer.join('').substr(0, 6);
                                    if (dayMonthValue != "29/02/")
                                        return true;
                                    else {
                                        var year = parseInt(chrs);  //detect leap year
                                        if (year % 4 == 0)
                                            if (year % 100 == 0)
                                            if (year % 400 == 0)
                                            return true;
                                        else return false;
                                        else return true;
                                        else return false;
                                    }
                                } else return false;
                            },
                            cardinality: 4,
                            prevalidator: [
                        { validator: "[12]", cardinality: 1 },
                        { validator: "(19|20)", cardinality: 2 },
                        { validator: "(19|20)\\d", cardinality: 3 }
                        ]
                        }
                    },
                    insertMode: false,
                    autoUnmask: false
                },
                //number aliases by Dean (datimson)
                'decimal': {
                    mask: "~",
                    placeholder: "",
                    repeat: 10,
                    greedy: false,
                    radixPoint: "\.", // | ","
                    regex: {
                        real: function(radixPoint) { return new RegExp("^([\+\-]?[0-9]*[" + radixPoint + "]?[0-9]*)$"); }
                    },
                    definitions: {
                        '~': { //real number
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var myBuffer = buffer.slice();
                                myBuffer.splice(pos, 0, chrs);
                                var test = myBuffer.join('');
                                var isValid = opts.regex.real(opts.radixPoint).test(test);
                                return isValid;
                            },
                            cardinality: 1,
                            prevalidator: null
                        }
                    },
                    insertMode: true
                },
                'non-negative-decimal': {
                    mask: "~",
                    placeholder: "",
                    repeat: 10,
                    greedy: false,
                    radixPoint: "\.", // | ","
                    regex: {
                        decimal: function(radixPoint) { return new RegExp("^([0-9]+[" + radixPoint + "]?[0-9]*)$"); }
                    },
                    definitions: {
                        '~': {
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var myBuffer = buffer.slice();
                                myBuffer.splice(pos, 0, chrs);
                                var test = myBuffer.join('');
                                var isValid = opts.regex.decimal(opts.radixPoint).test(test);
                                return isValid;
                            },
                            cardinality: 1,
                            prevalidator: null
                        }
                    },
                    insertMode: true
                },
                'integer': {
                    mask: "~",
                    placeholder: "",
                    repeat: 10,
                    greedy: false,
                    numericInput: true,
                    regex: {
                        integer: new RegExp("^([\+\-]?[0-9]*)$")
                    },
                    definitions: {
                        '~': {
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var myBuffer = buffer.slice();
                                myBuffer.splice(pos, 0, chrs);
                                var test = myBuffer.join('');
                                var isValid = opts.regex.integer.test(test);
                                return isValid;
                            },
                            cardinality: 1,
                            prevalidator: null
                        }
                    },
                    insertMode: true
                }
            });
        })(jQuery);<|endoftext|>


<commit_before>$(document).ready(function() {

    $("#carousel").owlCarousel({

        navigation : false, // Hide next and prev buttons
        slideSpeed : 300,
        paginationSpeed : 400,
        singleItem: true,
        autoHeight : true

        // "singleItem:true" is a shortcut for:
        // items : 1,
        // itemsDesktop : false,
        // itemsDesktopSmall : false,
        // itemsTablet: false,
        // itemsMobile : false

    });

});
<commit_msg>Add autoplay to carousel<commit_after>$(document).ready(function() {

    $("#carousel").owlCarousel({

        autoPlay: 4000,         //Set AutoPlay to 4 seconds
        slideSpeed : 300,
        paginationSpeed : 400,
        singleItem: true,
        navigation : false,     // Hide next and prev buttons
        autoHeight : true

        // "singleItem:true" is a shortcut for:
        // items : 1,
        // itemsDesktop : false,
        // itemsDesktopSmall : false,
        // itemsTablet: false,
        // itemsMobile : false

    });

});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import ReactGA from 'react-ga';

import { BrowserRouter, Route, Switch } from 'react-router-dom';

import 'bulma/css/bulma.min.css';

import Home from './components/Home';
import NavBar from './components/NavBar';
import Footer from './components/Footer';
import './App.css';

class App extends Component {
  componentDidMount() {
    ReactGA.initialize('UA-54114923-3', { debug: true });
    ReactGA.set({ page: window.location.pathname });
    ReactGA.pageview(window.location.pathname);
  }

  render() {
    return (
      <BrowserRouter>

          <NavBar />
          <Switch>
            <Route exact path="/" component={Home} />
          </Switch>

      </BrowserRouter>
    );
  }
}

export default App;
<commit_msg>adding clean URLS for slack invite, slack channel, meetup and happy hour<commit_after>import React, { Component } from 'react';
import ReactGA from 'react-ga';

import { BrowserRouter, Route, Switch } from 'react-router-dom';

import 'bulma/css/bulma.min.css';

import Home from './components/Home';
import NavBar from './components/NavBar';
import Footer from './components/Footer';
import './App.css';

class App extends Component {
  componentDidMount() {
    ReactGA.initialize('UA-54114923-3', { debug: true });
    ReactGA.set({ page: window.location.pathname });
    ReactGA.pageview(window.location.pathname);
  }

  render() {
    return (
      <BrowserRouter>

          <NavBar />
          <Switch>
            <Route exact path="/" component={Home} />
            <Route path='/invite' component={() => window.location = 'http://startupdetroit.herokuapp.com/'}/>
            <Route path='/slack' component={() => window.location = 'https://startupdetroit.slack.com/'}/>
            <Route path='/meetup' component={() => window.location = 'https://www.meetup.com/Startup-Detroit/'}/>
            <Route path='/happyhour' component={() => window.location = 'https://startupdetroit.repurpose.co/'}/>
          </Switch>

      </BrowserRouter>
    );
  }
}

export default App;
<|endoftext|>


<commit_before>/**
 * jquery.textareaHighlighter.js 0.2.6
 * jQuery plugin for highlighting text in textarea.
 *
 * alexandre.kirillov@gmail.com
 * MIT license. http://opensource.org/licenses/MIT
 */
;(function ( $, window, document, undefined ) {
    "use strict";

    /**
     *
     * PLUGIN CORE
     *
     */
    var pluginName = "textareaHighlighter",
        defaults = {
            matches: [
                // {'matchClass': '', 'rule': [], 'maxMatchCnt': 1, 'warningClass': 'warning'}
            ],
            maxlength: -1,
            maxlengthWarning: '',
            maxlengthElement: null,
            isCustomeCss: false,
            debug: false,
            typingDelay: 30
        };

    // constructor
    function Plugin ( element, options ) {
        this.isInited  = false;
        this.element   = element;
        this.$element  = $(this.element);
        this.settings  = $.extend( {}, defaults, this.$element.data(), options );
        this._defaults = defaults;
        this._name     = pluginName;

        this.style = {};
        this.$wrapDiv       = $(document.createElement('div')).addClass('textarea-highlighter-wrap');
        this.$backgroundDiv = $(document.createElement('div'));

        this.init();
    }

    Plugin.prototype = {
        init: function() {
            var _this          = this,
                $this          = this.$element,
                style          = this.style,
                settings       = this.settings,
                $wrapDiv       = this.$wrapDiv,
                $backgroundDiv = this.$backgroundDiv;

            _this.updateStyle();

            $this
                .data('highlighterTimerId', -1)
                // Bind events
                .on('scroll.textarea.highlighter', function(){
                    $backgroundDiv.scrollTop( $this.scrollTop() );
                })
                // ORIGINAL EVENTS
                .on('textarea.highlighter.destroy', function(){
                    _this.destroy();
                })
                .on('textarea.highlighter.update', function(){
                    _this.updateStyle();
                })
                .on('textarea.highlighter.change', function(){
                    _this.change({});
                });

            if (browser.msie) {
                // IE
                $this.on('input.textarea.highlighter keyup.textarea.highlighter', function(e){
                    _this.change(e);
                });
            }
            else {
                // Modern browsers
                $this.on('input.textarea.highlighter', function(e){
                    _this.change(e);
                });
            }

            // insert backgroundDiv
            $this.wrap( $wrapDiv ).before( $backgroundDiv );
            // do initial check for input
            _this.change({});
        },
        updateStyle: function(){
            var _this    = this,
                $this    = this.$element,
                settings = this.settings,
                style    = this.style;

            // textarea style
            this.style = {
                // background   : this.$element.css('background'),
                paddingTop   : parseInt( $this.css('padding-top'), 10 ),
                paddingRight : parseInt( $this.css('padding-right'), 10 ),
                paddingBottom: parseInt( $this.css('padding-bottom'), 10 ),
                paddingLeft  : parseInt( $this.css('padding-left'), 10 ),
            };

            // Hack for firefox, some how width needs to be 2px smallet then the textarea
            // and padding-left needs to be added 1px
            if( browser.firefox ){
                style.paddingRight += 1;
                style.paddingLeft += 1;
            }
            if( browser.iphone ){
                style.paddingRight += 3;
                style.paddingLeft += 3;
            }

            this.$wrapDiv.css({
                'position': 'relative',
                'margin'  : 0
            });
            this.$backgroundDiv.addClass('background-div').addClass( $this.attr('class') ).css({
                'height'        : '100%',
                'color'         : ( settings.debug ) ? '#f00' : 'transparent',
                // 'background'    : ( settings.debug ) ? '#fee' : style.background,
                // 'padding-top'   : style.paddingTop,
                // 'padding-right' : style.paddingRight,
                // 'padding-bottom': style.paddingBottom,
                // 'padding-left'  : style.paddingLeft,
                'position'      : 'absolute',
                'margin'        : '0'
            });
            if (! settings.isCustomeCss) {
                this.$backgroundDiv.css({
                    'padding-top'   : style.paddingTop,
                    'padding-right' : style.paddingRight,
                    'padding-bottom': style.paddingBottom,
                    'padding-left'  : style.paddingLeft,
                    'box-sizing'    : 'border-box',
                    'border-color'  : 'transparent'
                });
            }

            $this.css({
                'color'     : ( settings.debug ) ? 'rgba(0,0,0,0.5)' : 'inherit',
                'position'  : 'relative',
                'background': 'transparent'
            });
        },
        change: function(e){
            var _this = this,
                settings = _this.settings;
            // if arrow keys, don't do anything
            if (/(37|38|39|40)/.test(e.keyCode)) { return true; }

            // check for last update, this is for performace
            if (_this.$element.data('highlighterTimerId') !== -1) {
                clearTimeout( _this.$element.data('highlighterTimerId') );
                _this.$element.data('highlighterTimerId', -1);
            }

            var changeId = setTimeout(function(){
                var textareaText = _this.$element.val(),
                    key, ruleTextList, matchText, spanText, matchTextList = [], matchesList = [],
                    notOverMaxText = '', overMaxText ='', matchClass = '',
                    i, imax, j, jmax, maxSize,
                    maxMatchCnt = 0, maxMatch = null;

                if (0 < settings.maxlength) {
                    // check for max length
                    if ( settings.maxlength < _this.$element.val().length) {
                        matchText = textareaText.slice( settings.maxlength, settings.maxlength + _this.$element.val().length - 1 );
                        overMaxText = ''+ matchText +'';

                    }
                    // update text max length
                    if (settings.maxlengthElement !== null) {
                        maxSize = settings.maxlength - _this.$element.val().length;
                        if (maxSize < 0) {
                            if (! settings.maxlengthElement.hasClass( settings.maxlengthWarning )) {
                                settings.maxlengthElement.addClass( settings.maxlengthWarning );
                            }
                        }
                        else {
                            if (settings.maxlengthElement.hasClass( settings.maxlengthWarning )) {
                                settings.maxlengthElement.removeClass( settings.maxlengthWarning );
                            }
                        }
                        // update max length
                        settings.maxlengthElement.text( maxSize );
                    }

                    notOverMaxText = _this.$element.val().slice( 0, settings.maxlength );
                }
                else {
                    notOverMaxText = textareaText;
                }

                // check for matching words
                for (i = 0, imax = settings.matches.length; i < imax; i++) {
                    maxMatchCnt = 0;

                    // check for max match count
                    if (settings.matches[i].hasOwnProperty('maxMatchCnt')) {
                        maxMatchCnt = settings.matches[i].maxMatchCnt;
                    }

                    // check if match rule is a RegExp
                    if (settings.matches[i].rule instanceof RegExp) {
                        // set matched words array
                        matchesList = notOverMaxText.match( settings.matches[i].rule ) || [];
                    }
                    else {
                        // copy words array
                        matchesList = settings.matches[i].rule;
                    }

                    for (j = 0, jmax = matchesList.length; j < jmax; j++) {
                        // get word to match
                        matchText = matchesList[j];
                        matchClass = '';
                        maxMatch = null;

                        if (maxMatchCnt !== 0 ) {
                            maxMatch = notOverMaxText.match( new RegExp( _escapeRegExp( matchText ), 'g') );
                        }
                        // check if the match count is over max
                        if (maxMatch && maxMatch.length > maxMatchCnt){
                            // check for match class name
                            if (settings.matches[i].hasOwnProperty('warningClass')) {
                                matchClass = settings.matches[i].warningClass;
                            }
                            // update replaced text
                            notOverMaxText = _this.getWrapedText( notOverMaxText, matchTextList, matchText, matchClass );
                        }
                        else {
                            // check if word exists in input text
                            if( notOverMaxText.indexOf( matchText ) !== -1 ){
                                // check for match class name
                                if (settings.matches[i].hasOwnProperty('matchClass')) {
                                    matchClass = settings.matches[i].matchClass;
                                }
                                // update replaced text
                                notOverMaxText = _this.getWrapedText( notOverMaxText, matchTextList, matchText, matchClass );
                            }
                        }
                    }
                }

                // update background div content
                _this.$backgroundDiv.html( notOverMaxText + overMaxText );
                // trigger update event
                _this.$element.trigger('textarea.highlighter.update', {'textList': matchTextList});

                // if not initialize execution the trigger an initialization complete event
                if (!_this.isInited) {
                    _this.isInited = true;
                    _this.$element.trigger('textarea.highlighter.init.complete');
                }
            }, settings.typingDelay);
            // set setTimeout id
            _this.$element.data('highlighterTimerId', changeId);
        },
        getWrapedText: function( text, textList, matchedText, matchClass ){
            textList.push( matchedText );
            return text.replace( new RegExp( _escapeRegExp( matchedText ), 'g'), ''+ matchedText +'' );
        },
        destroy: function(){
            $.data( this.element, "plugin_" + pluginName, false );
            this.$backgroundDiv.remove();
            this.$element
                .off('scroll.textarea.highlighter')
                .off('input.textarea.highlighter keyup.textarea.highlighter')
                .off('textarea.highlighter.destroy')
                .off('textarea.highlighter.update')
                .off('textarea.highlighter.change')
                .css({
                    'color'     : '',
                    'position'  : '',
                    'background': ''
                })
                .unwrap();
        }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[ pluginName ] = function ( options ) {
        return this.each(function(i) {
            if ( ! $.data( this, "plugin_" + pluginName ) ) {
                $.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
            }
        });
    };

    /**
     *
     * HELPER FUNCTIONS
     *
     */
    var _escapeRegExp = function(str){
        return str.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
    };
    // get curretn bworser type
    var browser = (function(){
        var userAgent = navigator.userAgent,
            msie    = /(msie|trident)/i.test( userAgent ),
            chrome  = /chrome/i.test( userAgent ),
            firefox = /firefox/i.test( userAgent ),
            safari  = /safari/i.test( userAgent ) && !chrome,
            iphone  = /iphone/i.test( userAgent );

        if( msie ){ return { msie: true }; }
        if( chrome ){ return { chrome: true }; }
        if( firefox ){ return { firefox: true }; }
        if( iphone ){ return { iphone: true }; }
        if( safari ){ return { safari: true }; }

        return {
            msie   : false,
            chrome : false,
            firefox: false,
            safari : false,
            iphone : false
        };
    }());

})( jQuery, window, document );<commit_msg>add event to debug mode toggle<commit_after>/**
 * jquery.textareaHighlighter.js 0.2.6
 * jQuery plugin for highlighting text in textarea.
 *
 * alexandre.kirillov@gmail.com
 * MIT license. http://opensource.org/licenses/MIT
 */
;(function ( $, window, document, undefined ) {
    "use strict";

    /**
     *
     * PLUGIN CORE
     *
     */
    var pluginName = "textareaHighlighter",
        defaults = {
            matches: [
                // {'matchClass': '', 'rule': [], 'maxMatchCnt': 1, 'warningClass': 'warning'}
            ],
            maxlength: -1,
            maxlengthWarning: '',
            maxlengthElement: null,
            isCustomeCss: false,
            debug: false,
            typingDelay: 30
        };

    // constructor
    function Plugin ( element, options ) {
        this.isInited  = false;
        this.element   = element;
        this.$element  = $(this.element);
        this.settings  = $.extend( {}, defaults, this.$element.data(), options );
        this._defaults = defaults;
        this._name     = pluginName;

        this.style = {};
        this.$wrapDiv       = $(document.createElement('div')).addClass('textarea-highlighter-wrap');
        this.$backgroundDiv = $(document.createElement('div'));

        this.init();
    }

    Plugin.prototype = {
        init: function() {
            var _this          = this,
                $this          = this.$element,
                style          = this.style,
                settings       = this.settings,
                $wrapDiv       = this.$wrapDiv,
                $backgroundDiv = this.$backgroundDiv;

            _this.updateStyle();

            $this
                .data('highlighterTimerId', -1)
                // Bind events
                .on('scroll.textarea.highlighter', function(){
                    $backgroundDiv.scrollTop( $this.scrollTop() );
                })
                // ORIGINAL EVENTS
                .on('textarea.highlighter.destroy', function(){
                    _this.destroy();
                })
                .on('textarea.highlighter.update', function(){
                    _this.updateStyle();
                })
                .on('textarea.highlighter.change', function(){
                    _this.change({});
                })
                // debug mode toggle
                .on('textarea.highlighter.debug.on', function(){
                    _this.debugModeOn();
                })
                .on('textarea.highlighter.debug.off', function(){
                    _this.debugModeOff();
                });

            if (browser.msie) {
                // IE
                $this.on('input.textarea.highlighter keyup.textarea.highlighter', function(e){
                    _this.change(e);
                });
            }
            else {
                // Modern browsers
                $this.on('input.textarea.highlighter', function(e){
                    _this.change(e);
                });
            }

            // insert backgroundDiv
            $this.wrap( $wrapDiv ).before( $backgroundDiv );
            // do initial check for input
            _this.change({});
        },
        updateStyle: function(){
            var _this    = this,
                $this    = this.$element,
                settings = this.settings,
                style    = this.style;

            // textarea style
            this.style = {
                // background   : this.$element.css('background'),
                paddingTop   : parseInt( $this.css('padding-top'), 10 ),
                paddingRight : parseInt( $this.css('padding-right'), 10 ),
                paddingBottom: parseInt( $this.css('padding-bottom'), 10 ),
                paddingLeft  : parseInt( $this.css('padding-left'), 10 ),
            };

            // Hack for firefox, some how width needs to be 2px smallet then the textarea
            // and padding-left needs to be added 1px
            if( browser.firefox ){
                style.paddingRight += 1;
                style.paddingLeft += 1;
            }
            if( browser.iphone ){
                style.paddingRight += 3;
                style.paddingLeft += 3;
            }

            this.$wrapDiv.css({
                'position': 'relative',
                'margin'  : 0
            });
            this.$backgroundDiv.addClass('background-div').addClass( $this.attr('class') ).css({
                'height'        : '100%',
                'color'         : ( settings.debug ) ? '#f00' : 'transparent',
                // 'background'    : ( settings.debug ) ? '#fee' : style.background,
                // 'padding-top'   : style.paddingTop,
                // 'padding-right' : style.paddingRight,
                // 'padding-bottom': style.paddingBottom,
                // 'padding-left'  : style.paddingLeft,
                'position'      : 'absolute',
                'margin'        : '0'
            });
            if (! settings.isCustomeCss) {
                this.$backgroundDiv.css({
                    'padding-top'   : style.paddingTop,
                    'padding-right' : style.paddingRight,
                    'padding-bottom': style.paddingBottom,
                    'padding-left'  : style.paddingLeft,
                    'box-sizing'    : 'border-box',
                    'border-color'  : 'transparent'
                });
            }

            $this.css({
                'color'     : ( settings.debug ) ? 'rgba(0,0,0,0.5)' : 'inherit',
                'position'  : 'relative',
                'background': 'transparent'
            });
        },
        change: function(e){
            var _this = this,
                settings = _this.settings;
            // if arrow keys, don't do anything
            if (/(37|38|39|40)/.test(e.keyCode)) { return true; }

            // check for last update, this is for performace
            if (_this.$element.data('highlighterTimerId') !== -1) {
                clearTimeout( _this.$element.data('highlighterTimerId') );
                _this.$element.data('highlighterTimerId', -1);
            }

            var changeId = setTimeout(function(){
                var textareaText = _this.$element.val(),
                    key, ruleTextList, matchText, spanText, matchTextList = [], matchesList = [],
                    notOverMaxText = '', overMaxText ='', matchClass = '',
                    i, imax, j, jmax, maxSize,
                    maxMatchCnt = 0, maxMatch = null;

                if (0 < settings.maxlength) {
                    // check for max length
                    if ( settings.maxlength < _this.$element.val().length) {
                        matchText = textareaText.slice( settings.maxlength, settings.maxlength + _this.$element.val().length - 1 );
                        overMaxText = ''+ matchText +'';

                    }
                    // update text max length
                    if (settings.maxlengthElement !== null) {
                        maxSize = settings.maxlength - _this.$element.val().length;
                        if (maxSize < 0) {
                            if (! settings.maxlengthElement.hasClass( settings.maxlengthWarning )) {
                                settings.maxlengthElement.addClass( settings.maxlengthWarning );
                            }
                        }
                        else {
                            if (settings.maxlengthElement.hasClass( settings.maxlengthWarning )) {
                                settings.maxlengthElement.removeClass( settings.maxlengthWarning );
                            }
                        }
                        // update max length
                        settings.maxlengthElement.text( maxSize );
                    }

                    notOverMaxText = _this.$element.val().slice( 0, settings.maxlength );
                }
                else {
                    notOverMaxText = textareaText;
                }

                // check for matching words
                for (i = 0, imax = settings.matches.length; i < imax; i++) {
                    maxMatchCnt = 0;

                    // check for max match count
                    if (settings.matches[i].hasOwnProperty('maxMatchCnt')) {
                        maxMatchCnt = settings.matches[i].maxMatchCnt;
                    }

                    // check if match rule is a RegExp
                    if (settings.matches[i].rule instanceof RegExp) {
                        // set matched words array
                        matchesList = notOverMaxText.match( settings.matches[i].rule ) || [];
                    }
                    else {
                        // copy words array
                        matchesList = settings.matches[i].rule;
                    }

                    for (j = 0, jmax = matchesList.length; j < jmax; j++) {
                        // get word to match
                        matchText = matchesList[j];
                        matchClass = '';
                        maxMatch = null;

                        if (maxMatchCnt !== 0 ) {
                            maxMatch = notOverMaxText.match( new RegExp( _escapeRegExp( matchText ), 'g') );
                        }
                        // check if the match count is over max
                        if (maxMatch && maxMatch.length > maxMatchCnt){
                            // check for match class name
                            if (settings.matches[i].hasOwnProperty('warningClass')) {
                                matchClass = settings.matches[i].warningClass;
                            }
                            // update replaced text
                            notOverMaxText = _this.getWrapedText( notOverMaxText, matchTextList, matchText, matchClass );
                        }
                        else {
                            // check if word exists in input text
                            if( notOverMaxText.indexOf( matchText ) !== -1 ){
                                // check for match class name
                                if (settings.matches[i].hasOwnProperty('matchClass')) {
                                    matchClass = settings.matches[i].matchClass;
                                }
                                // update replaced text
                                notOverMaxText = _this.getWrapedText( notOverMaxText, matchTextList, matchText, matchClass );
                            }
                        }
                    }
                }

                // update background div content
                _this.$backgroundDiv.html( notOverMaxText + overMaxText );
                // trigger update event
                _this.$element.trigger('textarea.highlighter.update', {'textList': matchTextList});

                // if not initialize execution the trigger an initialization complete event
                if (!_this.isInited) {
                    _this.isInited = true;
                    _this.$element.trigger('textarea.highlighter.init.complete');
                }
            }, settings.typingDelay);
            // set setTimeout id
            _this.$element.data('highlighterTimerId', changeId);
        },
        getWrapedText: function( text, textList, matchedText, matchClass ){
            textList.push( matchedText );
            return text.replace( new RegExp( _escapeRegExp( matchedText ), 'g'), ''+ matchedText +'' );
        },
        destroy: function(){
            $.data( this.element, "plugin_" + pluginName, false );
            this.$backgroundDiv.remove();
            this.$element
                .off('scroll.textarea.highlighter')
                .off('input.textarea.highlighter keyup.textarea.highlighter')
                .off('textarea.highlighter.destroy')
                .off('textarea.highlighter.update')
                .off('textarea.highlighter.change')
                .css({
                    'color'     : '',
                    'position'  : '',
                    'background': ''
                })
                .unwrap();
        },
        debugModeOn: function(){
            this.settings.debug = true;
            this.$backgroundDiv.css({ 'color': '#f00' });
            this.$element.css({ 'color': 'rgba(0,0,0,0.5)' });
        },
        debugModeOff: function(){
            this.settings.debug = false;
            this.$backgroundDiv.css({ 'color': 'transparent' });
            this.$element.css({ 'color': 'inherit' });
        }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[ pluginName ] = function ( options ) {
        return this.each(function(i) {
            if ( ! $.data( this, "plugin_" + pluginName ) ) {
                $.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
            }
        });
    };

    /**
     *
     * HELPER FUNCTIONS
     *
     */
    var _escapeRegExp = function(str){
        return str.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
    };
    // get curretn bworser type
    var browser = (function(){
        var userAgent = navigator.userAgent,
            msie    = /(msie|trident)/i.test( userAgent ),
            chrome  = /chrome/i.test( userAgent ),
            firefox = /firefox/i.test( userAgent ),
            safari  = /safari/i.test( userAgent ) && !chrome,
            iphone  = /iphone/i.test( userAgent );

        if( msie ){ return { msie: true }; }
        if( chrome ){ return { chrome: true }; }
        if( firefox ){ return { firefox: true }; }
        if( iphone ){ return { iphone: true }; }
        if( safari ){ return { safari: true }; }

        return {
            msie   : false,
            chrome : false,
            firefox: false,
            safari : false,
            iphone : false
        };
    }());

})( jQuery, window, document );<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { browserHistory } from 'react-router'
import classNames from 'classnames'
import './bulma.css'

import People from './people'
import Buildings from './buildings'
import Shelters from './shelters'

const TABS = [
  {
    label: 'Personas',
    slug: '/personas'
  },
  {
    label: 'Edificios',
    slug: '/edificios'
  },
  {
    label: 'Albergues',
    slug: '/albergues'
  }
]

class App extends Component {
  constructor (props) {
    super(props)
    let path = props.location.pathname
    let test = TABS.filter((tab) => { if (path.includes(tab.slug)) return tab })
    this.data = {
      currentTab: (typeof test[0] !== 'undefined') ? test[0].label : TABS[0].label
    }
    this.state = Object.assign({}, this.data)
  }

  // Set current tab to tab
  setTab (tab) {
    this.setState({'currentTab': TABS[tab].label})
    browserHistory.push(`${TABS[tab].slug}`)
  }

  renderTabs () {
    let renderTabs = TABS.map((tab, index) => {
      return (

          {tab.label}

      )
    })
    return (

          {renderTabs}

    )
  }

  renderContent () {
    let content = null

    switch (this.state.currentTab) {
      case TABS[0].label:
        content = (<People {...this.props} />)
        break
      case TABS[1].label:
        content = (<Buildings {...this.props} />)
        break
      case TABS[2].label:
        content = (<Shelters{...this.props} />)
        break
    }

    return content
  }

  // Render menu
  renderMenu () {
    return (

              Ayuda para sismos, inundaciones y demás en México

              Sismo del 19 de septiembre de 2017

    )
  }

  render () {
    return (

        {this.renderMenu()}

Encontrar gente sismo

          {this.renderTabs()}
          {this.renderContent()}

    )
  }
}

export default App
<commit_msg>Footer<commit_after>import React, { Component } from 'react'
import { browserHistory } from 'react-router'
import classNames from 'classnames'
import './bulma.css'

import People from './people'
import Buildings from './buildings'
import Shelters from './shelters'

const TABS = [
  {
    label: 'Personas',
    slug: '/personas'
  },
  {
    label: 'Edificios',
    slug: '/edificios'
  },
  {
    label: 'Albergues',
    slug: '/albergues'
  }
]

class App extends Component {
  constructor (props) {
    super(props)
    let path = props.location.pathname
    let test = TABS.filter((tab) => { if (path.includes(tab.slug)) return tab })
    this.data = {
      currentTab: (typeof test[0] !== 'undefined') ? test[0].label : TABS[0].label
    }
    this.state = Object.assign({}, this.data)
  }

  // Set current tab to tab
  setTab (tab) {
    this.setState({'currentTab': TABS[tab].label})
    browserHistory.push(`${TABS[tab].slug}`)
  }

  renderTabs () {
    let renderTabs = TABS.map((tab, index) => {
      return (

          {tab.label}

      )
    })
    return (

          {renderTabs}

    )
  }

  renderContent () {
    let content = null

    switch (this.state.currentTab) {
      case TABS[0].label:
        content = (<People {...this.props} />)
        break
      case TABS[1].label:
        content = (<Buildings {...this.props} />)
        break
      case TABS[2].label:
        content = (<Shelters{...this.props} />)
        break
    }

    return content
  }

  // Render menu
  renderMenu () {
    return (

              Ayuda para sismos, inundaciones y demás en México

              Sismo del 19 de septiembre de 2017

    )
  }

  // Render footer
  renderFooter () {
    return (

                  Hackeado por Julio, Diego, César, Angel y Luis .

    )
  }

  render () {
    return (

        {this.renderMenu()}

Encontrar gente sismo

          {this.renderTabs()}
          {this.renderContent()}

        {this.renderFooter()}

    )
  }
}

export default App
<|endoftext|>


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

/**
 * A static object used to send aria-live updates to a screen reader. These are alerts that are independent of user
 * focus. This will simply reference 'aria-live' elements in the HTML document and update their content. ARIA
 * attributes specify the behavior of timing for the alerts. The following HTML elements must be in the document
 *
 *

 *

 *

 *

 *
 * It was discovered that cycling through these alerts prevented a VoiceOver bug where alerts would interrupt each
 * other. Starting from the first element, content is set on each element in order and cycles through.
 *
 * It is a commonly known (but not specified) limitation that aria-live elements must exist in the document before
 * the page has finished loading  to work with screen readers. Screen readers do not add observers to aria-live
 * elements that are added to the document after page load. So these elements must exist in the document before the
 * `onload` event triggers.
 *
 * Many aria-live and related attributes were tested, but none were well supported or particularly useful for PhET sims,
 * see https://github.com/phetsims/chipper/issues/472.
 *
 * NOTE: ariaHerald needs to be initialized before use as a singleton.
 * As of this writing (Nov 2017) this initialization occurs in Sim.js. Therefore if something uses ariaHerald
 * before Sim.js has initialized this file, the result will be a silent no-op.
 *
 * @author Jesse Greenberg
 * @author John Blanco
 */

define( require => {
  'use strict';

  // modules
  const Emitter = require( 'AXON/Emitter' );
  const sceneryPhet = require( 'SCENERY_PHET/sceneryPhet' );
  const timer = require( 'PHET_CORE/timer' );

  // by default, clear old text so sequential updates with identical text are announced, see updateLiveElement()
  const DEFAULT_WITH_CLEAR = true;

  // DOM elements which will receive the updated content. By having four elements and cycling through each one, we
  // can get around a VoiceOver bug where a new alert would interrupt the previous alert if it wasn't finished
  // speaking, see https://github.com/phetsims/scenery-phet/issues/362
  const politeElement1 = document.getElementById( 'polite-1' );
  const politeElement2 = document.getElementById( 'polite-2' );
  const politeElement3 = document.getElementById( 'polite-3' );
  const politeElement4 = document.getElementById( 'polite-4' );
  const ariaLiveElements = [ politeElement1, politeElement2, politeElement3, politeElement4 ];

  class AriaHerald {

    constructor() {
      // {boolean} - whether or not this instance has been initialized or not
      this.initialized = false;

      // index of current aria-live element to use, updated every time an event triggers
      this.elementIndex = 0;

      // @public {null|Emitter} - set in initialize method. Emit whenever we announce.
      this.announcingEmitter = null;
    }

    /**
     * Initialize AriaHerald to allow usage of its features. If not initialized, then it will no-op. This allows
     * AriaHerald to be disabled completely if a11y is not enabled.
     */
    initialize() {

      // verify that all DOM elements with aria-live are in the document
      assert && assert( document.getElementById( 'aria-live-elements' ), 'No alert container element found in document' );
      assert && assert( politeElement1, 'aria-live element 1 missing from document, all are required' );
      assert && assert( politeElement2, 'aria-live element 2 missing from document, all are required' );
      assert && assert( politeElement3, 'aria-live element 3 missing from document, all are required' );
      assert && assert( politeElement4, 'aria-live element 4 missing from document, all are required' );

      this.initialized = true;

      this.announcingEmitter = new Emitter( {
        valueTypes: [ 'string', 'boolean' ]
      } );

      // no need to be removed, exists for the lifetime of the simulation.
      this.announcingEmitter.addListener( ( textContent, withClear ) => {
        const element = ariaLiveElements[ this.elementIndex ];
        this.updateLiveElement( element, textContent, withClear );

        // update index for next time
        this.elementIndex = ( this.elementIndex + 1 ) % ariaLiveElements.length;
      } );
    }

    /**
     * Announce a polite alert.  This alert should be announced when the user has finished their current interaction or
     * after other utterances in the screen reader's queue are finished.
     * @public
     *
     * @param {string} textContent - the polite content to announce
     * @param {boolean} [withClear] - optional, whether or not to remove the old content from the alert before updating
     */
    announcePolite( textContent, withClear ) {

      // or the default to support propper emitter typing
      this.announcingEmitter.emit( textContent, withClear || DEFAULT_WITH_CLEAR );
    }

    /**
     * Update an element with the 'aria-live' attribute by setting its text content.
     * If using withClear, old element text content will be explicitly removed before new text content is set.  This will
     * allow sequential alerts with identical text content to be announced multiple times in a row, which some screen
     * readers might have prevented.
     *
     * @param {HTMLElement} liveElement - the HTML element that will send the alert to the assistive technology
     * @param {string} textContent - the content to be announced
     * @param {boolean} [withClear] - optional, whether or not to remove the old text content before updating the element
     * @private
     */
    updateLiveElement( liveElement, textContent, withClear ) {

      // no-op if not initialized
      if ( !this.initialized ) {
        return;
      }

      withClear = ( withClear === undefined ) ? DEFAULT_WITH_CLEAR : withClear;
      assert && assert( typeof withClear === 'boolean', 'withClear must be of type boolean' );

      // clearing the old content allows repeated alerts
      if ( withClear ) { liveElement.textContent = ''; }

      liveElement.textContent = textContent;

      // after a small delay, remove this alert content from the DOM so that it cannot be found again - must occur
      // after a delay for screen reader to register the change in text content
      timer.setTimeout( () => { liveElement.textContent = ''; }, 200 );
    }
  }

  return sceneryPhet.register( 'ariaHerald', new AriaHerald() );
} );<commit_msg>added TypeDef, Emitter to validate on TypeDef, always using EmitterIO, https://github.com/phetsims/axon/issues/189<commit_after>// Copyright 2017-2018, University of Colorado Boulder

/**
 * A static object used to send aria-live updates to a screen reader. These are alerts that are independent of user
 * focus. This will simply reference 'aria-live' elements in the HTML document and update their content. ARIA
 * attributes specify the behavior of timing for the alerts. The following HTML elements must be in the document
 *
 *

 *

 *

 *

 *
 * It was discovered that cycling through these alerts prevented a VoiceOver bug where alerts would interrupt each
 * other. Starting from the first element, content is set on each element in order and cycles through.
 *
 * It is a commonly known (but not specified) limitation that aria-live elements must exist in the document before
 * the page has finished loading  to work with screen readers. Screen readers do not add observers to aria-live
 * elements that are added to the document after page load. So these elements must exist in the document before the
 * `onload` event triggers.
 *
 * Many aria-live and related attributes were tested, but none were well supported or particularly useful for PhET sims,
 * see https://github.com/phetsims/chipper/issues/472.
 *
 * NOTE: ariaHerald needs to be initialized before use as a singleton.
 * As of this writing (Nov 2017) this initialization occurs in Sim.js. Therefore if something uses ariaHerald
 * before Sim.js has initialized this file, the result will be a silent no-op.
 *
 * @author Jesse Greenberg
 * @author John Blanco
 */

define( require => {
  'use strict';

  // modules
  const Emitter = require( 'AXON/Emitter' );
  const EmitterIO = require( 'AXON/EmitterIO' );
  const sceneryPhet = require( 'SCENERY_PHET/sceneryPhet' );
  const timer = require( 'PHET_CORE/timer' );

  // by default, clear old text so sequential updates with identical text are announced, see updateLiveElement()
  const DEFAULT_WITH_CLEAR = true;

  // DOM elements which will receive the updated content. By having four elements and cycling through each one, we
  // can get around a VoiceOver bug where a new alert would interrupt the previous alert if it wasn't finished
  // speaking, see https://github.com/phetsims/scenery-phet/issues/362
  const politeElement1 = document.getElementById( 'polite-1' );
  const politeElement2 = document.getElementById( 'polite-2' );
  const politeElement3 = document.getElementById( 'polite-3' );
  const politeElement4 = document.getElementById( 'polite-4' );
  const ariaLiveElements = [ politeElement1, politeElement2, politeElement3, politeElement4 ];

  class AriaHerald {

    constructor() {
      // {boolean} - whether or not this instance has been initialized or not
      this.initialized = false;

      // index of current aria-live element to use, updated every time an event triggers
      this.elementIndex = 0;

      // @public {null|Emitter} - set in initialize method. Emit whenever we announce.
      this.announcingEmitter = null;
    }

    /**
     * Initialize AriaHerald to allow usage of its features. If not initialized, then it will no-op. This allows
     * AriaHerald to be disabled completely if a11y is not enabled.
     */
    initialize() {

      // verify that all DOM elements with aria-live are in the document
      assert && assert( document.getElementById( 'aria-live-elements' ), 'No alert container element found in document' );
      assert && assert( politeElement1, 'aria-live element 1 missing from document, all are required' );
      assert && assert( politeElement2, 'aria-live element 2 missing from document, all are required' );
      assert && assert( politeElement3, 'aria-live element 3 missing from document, all are required' );
      assert && assert( politeElement4, 'aria-live element 4 missing from document, all are required' );

      this.initialized = true;

      this.announcingEmitter = new Emitter( {
        phetioType: EmitterIO( [ { type: 'string' }, { type: 'boolean' } ] )
      } );

      // no need to be removed, exists for the lifetime of the simulation.
      this.announcingEmitter.addListener( ( textContent, withClear ) => {
        const element = ariaLiveElements[ this.elementIndex ];
        this.updateLiveElement( element, textContent, withClear );

        // update index for next time
        this.elementIndex = ( this.elementIndex + 1 ) % ariaLiveElements.length;
      } );
    }

    /**
     * Announce a polite alert.  This alert should be announced when the user has finished their current interaction or
     * after other utterances in the screen reader's queue are finished.
     * @public
     *
     * @param {string} textContent - the polite content to announce
     * @param {boolean} [withClear] - optional, whether or not to remove the old content from the alert before updating
     */
    announcePolite( textContent, withClear ) {

      // or the default to support propper emitter typing
      this.announcingEmitter.emit( textContent, withClear || DEFAULT_WITH_CLEAR );
    }

    /**
     * Update an element with the 'aria-live' attribute by setting its text content.
     * If using withClear, old element text content will be explicitly removed before new text content is set.  This will
     * allow sequential alerts with identical text content to be announced multiple times in a row, which some screen
     * readers might have prevented.
     *
     * @param {HTMLElement} liveElement - the HTML element that will send the alert to the assistive technology
     * @param {string} textContent - the content to be announced
     * @param {boolean} [withClear] - optional, whether or not to remove the old text content before updating the element
     * @private
     */
    updateLiveElement( liveElement, textContent, withClear ) {

      // no-op if not initialized
      if ( !this.initialized ) {
        return;
      }

      withClear = ( withClear === undefined ) ? DEFAULT_WITH_CLEAR : withClear;
      assert && assert( typeof withClear === 'boolean', 'withClear must be of type boolean' );

      // clearing the old content allows repeated alerts
      if ( withClear ) { liveElement.textContent = ''; }

      liveElement.textContent = textContent;

      // after a small delay, remove this alert content from the DOM so that it cannot be found again - must occur
      // after a delay for screen reader to register the change in text content
      timer.setTimeout( () => { liveElement.textContent = ''; }, 200 );
    }
  }

  return sceneryPhet.register( 'ariaHerald', new AriaHerald() );
} );<|endoftext|>


<commit_before>var RomoSelectedOptionsList = function(focusElem) {
  this.elem      = undefined;
  this.focusElem = focusElem; // picker/select dropdown elem

  this.items = [];

  this.doInit();
  this._bindElem();
}

RomoSelectedOptionsList.prototype.doInit = function() {
  // override as needed
}

/*
Options are specified as a list of items.  Each 'option' item object
has display text and a value. They are compatible with the option list
dropdown option items.

Example:
[ { 'type': 'option', 'value': 'a', 'displayText': 'A' },
  { 'type': 'option', 'value': 'b', 'displayText': 'B' },
  { 'type': 'option', 'value': 'c', 'displayText': 'C' }
]
*/

RomoSelectedOptionsList.prototype.doSetItems = function(itemsList) {
  this.items = itemsList;
}

RomoSelectedOptionsList.prototype.doClearItems = function() {
  this.items = [];
}

RomoSelectedOptionsList.prototype.doAddItem = function(item) {
  if (!this._getItemValues().includes(item.value)) {
    this.items.push(item);
  }
}

RomoSelectedOptionsList.prototype.doRemoveItem = function(itemValue) {
  var index = this._getItemValues().indexOf(itemValue);
  if (index > -1) {
    this.items.splice(index, 1);
  }
}

RomoSelectedOptionsList.prototype.doRefreshUI = function() {
  var itemValues  = this._getItemValues();
  var uiListElem  = this.elem.find('.romo-selected-options-list-items');
  var uiItemElems = uiListElem.find('.romo-selected-options-list-item');
  var uiValues    = uiItemElems.get().map(function(uiItemNode) {
    return $(uiItemNode).data('romo-selected-options-list-value');
  });
  var rmNodes = uiItemElems.get().filter(function(uiItemNode) {
     return itemValues.indexOf($(uiItemNode).data('romo-selected-options-list-value')) === -1;
   });
  var addItems = this.items.filter(function(item) {
    return uiValues.indexOf(item.value) === -1;
  });
  rmNodes.forEach($.proxy(function(rmNode) {
    $(rmNode).remove();
  }, this));
  addItems.forEach($.proxy(function(addItem) {
    var addElem = this._buildItemElem(addItem);
    uiListElem.append(addElem);

    var listWidth       = parseInt(Romo.getComputedStyle(uiListElem[0], "width"), 10);
    var listLeftPad     = parseInt(Romo.getComputedStyle(uiListElem[0], "padding-left"), 10);
    var listRightPad    = parseInt(Romo.getComputedStyle(uiListElem[0], "padding-right"), 10);
    var itemBorderWidth = 1;
    var itemLeftPad     = parseInt(Romo.getComputedStyle(addElem[0], "padding-left"), 10);
    var itemRightPad    = parseInt(Romo.getComputedStyle(addElem[0], "padding-right"), 10);
    addElem.find('DIV').css('max-width', String(listWidth-listLeftPad-listRightPad-(2*itemBorderWidth)-itemLeftPad-itemRightPad)+'px');
  }, this));

  var focusElemWidth = parseInt(Romo.getComputedStyle(this.focusElem[0], "width"), 10);
  this.elem.css('width', String(focusElemWidth)+'px');

  var maxRows          = undefined;
  var uiListElemHeight = parseInt(Romo.getComputedStyle(uiListElem[0], "height"), 10);
  var firstItemNode    = uiListElem.find('.romo-selected-options-list-item')[0];
  if (firstItemNode !== undefined) {
    var itemHeight       = parseInt(Romo.getComputedStyle(firstItemNode, "height"), 10);
    var itemMarginBottom = parseInt(Romo.getComputedStyle(firstItemNode, "margin-bottom"), 10);
    var itemBorderWidth  = 1;
    var listTopPad       = parseInt(Romo.getComputedStyle(uiListElem[0], "padding-top"), 10);
    var listBottomPad    = parseInt(Romo.getComputedStyle(uiListElem[0], "padding-bottom"), 10);

    var maxRows   = this.focusElem.data('romo-selected-options-list-max-rows') || 0;
    var maxHeight = listTopPad+(itemHeight*maxRows)+(itemMarginBottom*(maxRows-1))+(2*itemBorderWidth*maxRows)+listBottomPad+(itemHeight/2);
  }
  if (maxRows !== 0 && (uiListElemHeight > maxHeight)) {
    this.elem.css({
      'height':     String(maxHeight)+'px',
      'overflow-y': 'auto'
    });
    var itemElems    = uiListElem.find('.romo-selected-options-list-item');
    var lastItemNode = itemElems[itemElems.length-1];
    this._scrollListTopToItem($(lastItemNode));
  } else {
    this.elem.css({
      'height':     String(uiListElemHeight)+'px',
      'overflow-y': undefined
    });
  }
}

/* private */

RomoSelectedOptionsList.prototype._bindElem = function() {
  this.elem = $('

');

  this.elem.on('click', $.proxy(function(e) {
    if (e !== undefined) {
      e.stopPropagation();
      e.preventDefault();
    }
    this.elem.trigger('romoSelectedOptionsList:listClick', [this]);
  }, this));

  this.doSetItems([]);
}

RomoSelectedOptionsList.prototype._buildItemElem = function(item) {
  var itemClass = this.focusElem.data('romo-selected-options-list-item-class') || '';
  var itemElem  = $('

');
  itemElem.append($('
'+(item.displayText || '')+'
'));
  itemElem.attr('data-romo-selected-options-list-value', (item.value || ''));
  itemElem.on('click', $.proxy(this._onItemClick, this));

  return itemElem;
}

RomoSelectedOptionsList.prototype._getItemValues = function() {
  return this.items.map(function(item) { return item.value; });
}

RomoSelectedOptionsList.prototype._onItemClick = function(e) {
  var itemElem = $(e.target);
  if (!itemElem.hasClass('romo-selected-options-list-item')) {
    var itemElem = itemElem.closest('.romo-selected-options-list-item');
  }
  if (itemElem[0] !== undefined) {
    var value = itemElem.data('romo-selected-options-list-value');
    this.elem.trigger('romoSelectedOptionsList:itemClick', [value, this]);
  }
}

RomoSelectedOptionsList.prototype._scrollListTopToItem = function(itemElem) {
  if (itemElem[0] !== undefined) {
    var scroll = this.elem;
    scroll.scrollTop(0);

    var scrollOffsetTop = scroll.offset().top;
    var selOffsetTop    = itemElem.offset().top;
    var selOffset       = itemElem.height() / 2;

    scroll.scrollTop(selOffsetTop - scrollOffsetTop - selOffset);
  }
}
<commit_msg>Update `RomoSelectedOptionsList` component to not use jquery<commit_after>var RomoSelectedOptionsList = function(focusElem) {
  this.elem      = undefined;
  this.focusElem = focusElem; // picker/select dropdown elem

  this.items = [];

  this.doInit();
  this._bindElem();
}

RomoSelectedOptionsList.prototype.doInit = function() {
  // override as needed
}

/*
Options are specified as a list of items.  Each 'option' item object
has display text and a value. They are compatible with the option list
dropdown option items.

Example:
[ { 'type': 'option', 'value': 'a', 'displayText': 'A' },
  { 'type': 'option', 'value': 'b', 'displayText': 'B' },
  { 'type': 'option', 'value': 'c', 'displayText': 'C' }
]
*/

RomoSelectedOptionsList.prototype.doSetItems = function(itemsList) {
  this.items = itemsList;
}

RomoSelectedOptionsList.prototype.doClearItems = function() {
  this.items = [];
}

RomoSelectedOptionsList.prototype.doAddItem = function(item) {
  if (!this._getItemValues().includes(item.value)) {
    this.items.push(item);
  }
}

RomoSelectedOptionsList.prototype.doRemoveItem = function(itemValue) {
  var index = this._getItemValues().indexOf(itemValue);
  if (index > -1) {
    this.items.splice(index, 1);
  }
}

RomoSelectedOptionsList.prototype.doRefreshUI = function() {
  var itemValues  = this._getItemValues();
  var uiListElem  = Romo.find(this.elem, '.romo-selected-options-list-items')[0];
  var uiItemElems = Romo.find(uiListElem, '.romo-selected-options-list-item');
  var uiValues    = uiItemElems.map(Romo.proxy(function(uiItemElem) {
    return Romo.data(uiItemElem, 'romo-selected-options-list-value');
  }, this), []);
  var rmElems = uiItemElems.filter(function(uiItemElem) {
     return itemValues.indexOf(Romo.data(uiItemElem, 'romo-selected-options-list-value')) === -1;
   });
  var addItems = this.items.filter(function(item) {
    return uiValues.indexOf(item.value) === -1;
  });
  rmElems.forEach(Romo.proxy(function(rmElem) {
    Romo.remove(rmElem);
  }, this));
  addItems.forEach(Romo.proxy(function(addItem) {
    var addElem = this._buildItemElem(addItem);
    uiListElem.append(addElem);

    var listWidth       = parseInt(Romo.css(uiListElem, "width"), 10);
    var listLeftPad     = parseInt(Romo.css(uiListElem, "padding-left"), 10);
    var listRightPad    = parseInt(Romo.css(uiListElem, "padding-right"), 10);
    var itemBorderWidth = 1;
    var itemLeftPad     = parseInt(Romo.css(addElem, "padding-left"), 10);
    var itemRightPad    = parseInt(Romo.css(addElem, "padding-right"), 10);
    Romo.setStyle(Romo.find(addElem, 'DIV')[0], 'max-width', String(listWidth-listLeftPad-listRightPad-(2*itemBorderWidth)-itemLeftPad-itemRightPad)+'px');
  }, this));

  var focusElemWidth = parseInt(Romo.css(this.focusElem, "width"), 10);
  Romo.setStyle(this.elem, 'width', String(focusElemWidth)+'px');

  var maxRows           = undefined;
  var uiListElemHeight  = parseInt(Romo.css(uiListElem, "height"), 10);
  var firstItemElem = Romo.find(uiListElem, '.romo-selected-options-list-item')[0];
  if (firstItemElem !== undefined) {
    var itemHeight       = parseInt(Romo.css(firstItemElem, "height"), 10);
    var itemMarginBottom = parseInt(Romo.css(firstItemElem, "margin-bottom"), 10);
    var itemBorderWidth  = 1;
    var listTopPad       = parseInt(Romo.css(uiListElem, "padding-top"), 10);
    var listBottomPad    = parseInt(Romo.css(uiListElem, "padding-bottom"), 10);

    var maxRows   = Romo.data(this.focusElem, 'romo-selected-options-list-max-rows') || 0;
    var maxHeight = listTopPad+(itemHeight*maxRows)+(itemMarginBottom*(maxRows-1))+(2*itemBorderWidth*maxRows)+listBottomPad+(itemHeight/2);
  }
  if (maxRows !== 0 && (uiListElemHeight > maxHeight)) {
    Romo.setStyle(this.elem, 'height',     String(maxHeight)+'px');
    Romo.setStyle(this.elem, 'overflow-y', 'auto');

    var itemElems    = Romo.find(uiListElem, '.romo-selected-options-list-item');
    var lastItemElem = itemElems[itemElems.length-1];
    this._scrollListTopToItem(lastItemElem);
  } else {
    Romo.setStyle(this.elem, 'height',     String(uiListElemHeight)+'px');
    Romo.setStyle(this.elem, 'overflow-y', '');
  }
}

/* private */

RomoSelectedOptionsList.prototype._bindElem = function() {
  this.elem = Romo.elems('

')[0];

  Romo.on(this.elem, 'click', Romo.proxy(function(e) {
    if (e !== undefined) {
      e.stopPropagation();
      e.preventDefault();
    }
    Romo.trigger(this.elem, 'romoSelectedOptionsList:listClick', [this]);
  }, this));

  this.doSetItems([]);
}

RomoSelectedOptionsList.prototype._buildItemElem = function(item) {
  var itemClass = Romo.data(this.focusElem, 'romo-selected-options-list-item-class') || '';
  var itemElem  = Romo.elems('

')[0];
  Romo.append(itemElem, Romo.elems('
'+(item.displayText || '')+'
')[0]);
  Romo.setData(itemElem, 'romo-selected-options-list-value', (item.value || ''));
  Romo.on(itemElem, 'click', Romo.proxy(this._onItemClick, this));

  return itemElem;
}

RomoSelectedOptionsList.prototype._getItemValues = function() {
  return this.items.map(function(item) { return item.value; });
}

RomoSelectedOptionsList.prototype._onItemClick = function(e) {
  var itemElem = e.target;
  if (!Romo.hasClass(itemElem, 'romo-selected-options-list-item')) {
    var itemElem = Romo.closest(itemElem, '.romo-selected-options-list-item');
  }
  if (itemElem !== undefined) {
    var value = Romo.data(itemElem, 'romo-selected-options-list-value');
    Romo.trigger(this.elem, 'romoSelectedOptionsList:itemClick', [value, this]);
  }
}

RomoSelectedOptionsList.prototype._scrollListTopToItem = function(itemElem) {
  if (itemElem !== undefined) {
    var scrollElem = this.elem;
    scrollElem.scrollTop = 0;

    var scrollOffsetTop = Romo.offset(scrollElem).top;
    var selOffsetTop    = Romo.offset(itemElem).top;
    var selOffset       = parseInt(Romo.css(itemElem, 'height'), 10) / 2;

    scrollElem.scrollTop = selOffsetTop - scrollOffsetTop - selOffset;
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import jQuery from 'jquery';
import AddTaskForm from './AddTaskForm';

class App extends React.Component{

  onAddTask(task_value, date_value){
    console.log("I need to get " + task_value " on " + date_value );
  }

    render(){
        return (

Check ☑

          <AddTaskForm onHandleData={this.onAddTask.bind(this)} />

        );
    }
}

export default App;
<commit_msg>edited the texting<commit_after>import React from 'react';
//import jQuery from 'jquery';
import AddTaskForm from './AddTaskForm';

class App extends React.Component{

  onAddTask(task_value, date_value){
    console.log(task_value + date_value );
  }

    render(){
        return (

Check ☑

          <AddTaskForm onHandleData={this.onAddTask.bind(this)} />

        );
    }
}

export default App;
<|endoftext|>