<commit_before>/* Copyright (C) 2012  Lincoln de Sousa <lincoln@comum.org>
 *
 *   Author: Lincoln de Sousa <lincoln@gg.rs.gov.br>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

function showAggregated(parentId) {
    $('#aggregated-' + parentId).slideToggle();
}

function vote(qid) {
    $.get(url_for('govresponde.vote.<qid>', { qid: qid }), function (data) {
        $('#question-' + qid + ' button').replaceWith(
            $('<div>')
                .addClass('success')
                .addClass('msg')
                .show()
                .html('Obrigado por votar. Seu voto foi contabilizado'));
        $('#question-' + qid + ' .score')
            .fadeOut(function () {
                $(this)
                    .html(data)
                    .fadeIn();
            });
    });
}
<commit_msg>(govr) Arrumando a funcionalidade votar<commit_after>/* Copyright (C) 2012  Lincoln de Sousa <lincoln@comum.org>
 *
 *   Author: Lincoln de Sousa <lincoln@gg.rs.gov.br>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

function showAggregated(parentId) {
    $('#aggregated-' + parentId).slideToggle();
}

function vote(qid) {
    if (!auth.isAuthenticated()) {
        return auth.showLoginForm({
            success: function () {
                vote(qid);
            }
        });
    }

    $.get(url_for('govresponde.vote.<qid>', { qid: qid }), function (data) {
        $('#question-' + qid + ' button').replaceWith(
            $('<div>')
                .addClass('success')
                .addClass('msg')
                .show()
                .html('Obrigado por votar. Seu voto foi contabilizado'));
        $('#question-' + qid + ' .score')
            .fadeOut(function () {
                $(this)
                    .html(data)
                    .fadeIn();
            });
    });
}
<|endoftext|>


<commit_before>import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { Provider } from 'react-redux';
import { match, Router, browserHistory } from 'react-router/es6';
import { syncHistoryWithStore } from 'react-router-redux';
import { fromJS } from 'immutable';
import configureStore from './configureStore';

const initialState = fromJS(window.__INITIAL_STATE__);  // redux-immutable only allow immutable obj
const store = configureStore(initialState);
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState: state => state.get('routing').toJS(),
});
const mountNode = document.getElementById('react-view');

const renderApp = () => {
  // eslint-disable-next-line import/newline-after-import
  const createRoutes = require('./routes').default;
  const routes = createRoutes(store);

  // Sync routes both on client and server
  match({ routes, history: browserHistory }, (error, redirectLocation, renderProps) => {
    // Using the enhanced history (react-redux-router) instead of the 'browserHistory'
    const props = Object.assign({}, renderProps, { history });

    render(
      <Provider store={store}>
        <Router {...props} />
      </Provider>,
      mountNode
    );
  });
};

// Enable hot reload by react-hot-loader
if (module.hot) {
  const reRenderApp = () => {
    try {
      renderApp();
    } catch (error) {
      const RedBox = require('redbox-react').default;

      render(<RedBox error={error} />, mountNode);
    }
  };

  module.hot.accept('./routes', () => {
    // Prevent the hot reloading error from react-router
    unmountComponentAtNode(mountNode);
    reRenderApp();
  });
}

renderApp();
<commit_msg>Update<commit_after>import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { Provider } from 'react-redux';
import { match, Router, browserHistory } from 'react-router/es6';
import { syncHistoryWithStore } from 'react-router-redux';
import { fromJS } from 'immutable';
import configureStore from './configureStore';

const initialState = fromJS(window.__INITIAL_STATE__);  // redux-immutable only allow immutable obj
const store = configureStore(initialState);
const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState: state => state.get('routing').toJS(),
});
const mountNode = document.getElementById('react-view');

const renderApp = () => {
  // eslint-disable-next-line import/newline-after-import
  const createRoutes = require('./routes').default;
  const routes = createRoutes(store);

  // Sync routes both on client and server
  match({ routes, history: browserHistory }, (error, redirectLocation, renderProps) => {
    // Using the enhanced history (react-redux-router) instead of the 'browserHistory'
    const props = Object.assign({}, renderProps, { history });

    render(
      <Provider store={store}>
        <Router {...props} />
      </Provider>,
      mountNode
    );
  });
};

// Enable hot reload by react-hot-loader
if (module.hot) {
  const reRenderApp = () => {
    try {
      renderApp();
    } catch (error) {
      const RedBox = require('redbox-react').default;

      render(<RedBox error={error} />, mountNode);
    }
  };

  module.hot.accept('./routes', () => {
    // Prevent the hot reloading error from react-router
    setImmediate(() => {
      unmountComponentAtNode(mountNode);
      reRenderApp();
    });
  });
}

renderApp();
<|endoftext|>


<commit_before>/**
 * THIS IS THE ENTRY POINT FOR THE CLIENT, JUST LIKE server.js IS THE ENTRY POINT FOR THE SERVER.
 */
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import ga from 'react-ga';
import createStore from './redux/create';
import ApiClient from './helpers/ApiClient';
import io from 'socket.io-client';
import {Provider} from 'react-redux';
import { Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import { ReduxAsyncConnect } from 'redux-connect';
import useScroll from 'scroll-behavior/lib/useStandardScroll';
import getRoutes from './routes';

const client = new ApiClient();
const _browserHistory = useScroll(() => browserHistory)();
const dest = document.getElementById('content');
const store = createStore(_browserHistory, client, window.__data);
const history = syncHistoryWithStore(_browserHistory, store);

require('../static/fonts/lato/scss/lato.scss');

if (process.env.NODE_ENV === 'production') {
  ga.initialize('UA-78109937-1');
}

function logPageView() {
  if (process.env.NODE_ENV === 'production') {
    ga.pageview(window.location.pathname);
  }
}

function initSocket() {
  const socket = io('', {path: '/ws'});
  return socket;
}

//global.socket = initSocket();

const component = (
  <Router render={(props) =>
        <ReduxAsyncConnect {...props} helpers={{client}} filter={item => !item.deferred} />
      } history={history} onUpdate={logPageView}>
    {getRoutes(store)}
  </Router>
);

ReactDOM.render(
  <Provider store={store} key="provider">
    {component}
  </Provider>,
  dest
);

if (process.env.NODE_ENV !== 'production') {
  window.React = React; // enable debugger

  if (!dest || !dest.firstChild || !dest.firstChild.attributes || !dest.firstChild.attributes['data-react-checksum']) {
    console.error('Server-side React render was discarded. Make sure that your initial render does not contain any client-side code.');
  }
}

if (__DEVTOOLS__ && !window.devToolsExtension) {
  const DevTools = require('./containers/DevTools/DevTools');
  ReactDOM.render(
    <Provider store={store} key="provider">

        {component}
        <DevTools />

    </Provider>,
    dest
  );
}
<commit_msg>asci art and console easter egg<commit_after>/**
 * THIS IS THE ENTRY POINT FOR THE CLIENT, JUST LIKE server.js IS THE ENTRY POINT FOR THE SERVER.
 */
import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import ga from 'react-ga';
import createStore from './redux/create';
import ApiClient from './helpers/ApiClient';
import io from 'socket.io-client';
import {Provider} from 'react-redux';
import { Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import { ReduxAsyncConnect } from 'redux-connect';
import useScroll from 'scroll-behavior/lib/useStandardScroll';
import getRoutes from './routes';

const client = new ApiClient();
const _browserHistory = useScroll(() => browserHistory)();
const dest = document.getElementById('content');
const store = createStore(_browserHistory, client, window.__data);
const history = syncHistoryWithStore(_browserHistory, store);

require('../static/fonts/lato/scss/lato.scss');

const asci = `
______ ____________________________ _____________   ________
___  //_/__    |__  __/__    |__  //_/__    |__  | / /__    |
__  ,<  __  /| |_  /  __  /| |_  ,<  __  /| |_   |/ /__  /| |
_  /| | _  ___ |  /   _  ___ |  /| | _  ___ |  /|  / _  ___ |
/_/ |_| /_/  |_/_/    /_/  |_/_/ |_| /_/  |_/_/ |_/  /_/  |_|
`;
console.log(asci);
console.log("Если вы хотите вступить в группу разработчиков KATAKANA, обращайтесь по адрессу mail@katakana.xyz");
console.log("Если вам интересна не только сгенерированная верстка, приглашаю вас посетить репозиторий на github: http://github.com/codejunkienick/katakana");

if (process.env.NODE_ENV === 'production') {
  ga.initialize('UA-78109937-1');
}

function logPageView() {
  if (process.env.NODE_ENV === 'production') {
    ga.pageview(window.location.pathname);
  }
}

function initSocket() {
  const socket = io('', {path: '/ws'});
  return socket;
}

//global.socket = initSocket();

const component = (
  <Router render={(props) =>
        <ReduxAsyncConnect {...props} helpers={{client}} filter={item => !item.deferred} />
      } history={history} onUpdate={logPageView}>
    {getRoutes(store)}
  </Router>
);

ReactDOM.render(
  <Provider store={store} key="provider">
    {component}
  </Provider>,
  dest
);

if (process.env.NODE_ENV !== 'production') {
  window.React = React; // enable debugger

  if (!dest || !dest.firstChild || !dest.firstChild.attributes || !dest.firstChild.attributes['data-react-checksum']) {
    console.error('Server-side React render was discarded. Make sure that your initial render does not contain any client-side code.');
  }
}

if (__DEVTOOLS__ && !window.devToolsExtension) {
  const DevTools = require('./containers/DevTools/DevTools');
  ReactDOM.render(
    <Provider store={store} key="provider">

        {component}
        <DevTools />

    </Provider>,
    dest
  );
}
<|endoftext|>


<commit_before>go.app = function() {
    var vumigo = require('vumigo_v02');
    var App = vumigo.App;
    var Choice = vumigo.states.Choice;
    var ChoiceState = vumigo.states.ChoiceState;
    var EndState = vumigo.states.EndState;
    var FreeText = vumigo.states.FreeText;

    var GoNDOH = App.extend(function(self) {
        App.call(self, 'states:start');
        var $ = self.$;

        self.init = function() {

            self.im.on('session:close', function(e) {
                if (!self.should_send_dialback(e)) { return; }
                return self.send_dialback();
            });

            return self.im.contacts
                .for_user()
                .then(function(user_contact) {
                    if ((user_contact.extra.working_on !== undefined) && (user_contact.extra.working_on !== "")){
                        self.user = user_contact;
                        return self.im.contacts.get(user_contact.extra.working_on, {create: true})
                            .then(function(working_on){
                                self.contact = working_on;
                            });
                    } else {
                        self.contact = user_contact;
                    }
                });
        };

        self.should_send_dialback = function(e) {
            return e.user_terminated
                && !go.utils.is_true(self.contact.extra.redial_sms_sent);
        };

        self.send_dialback = function() {
            return self.im.outbound
                .send_to_user({
                    endpoint: 'sms',
                    content: self.get_finish_reg_sms()
                })
                .then(function() {
                    self.contact.extra.redial_sms_sent = 'true';
                    return self.im.contacts.save(self.contact);
                });
        };

        self.get_finish_reg_sms = function() {
            return $("Please dial back in to {{ USSD_number }} to complete the pregnancy registration.")
                .context({
                    USSD_number: self.im.config.channel
                });
        };

        self.states.add('states:start', function(name) {
            var normalised_no = go.utils.normalise_sa_msisdn(self.im.user.addr);

            return new ChoiceState(name, {
                question: $('Welcome to The Department of Health\'s ' +
                            'MomConnect. Tell us if this is the no. that ' +
                            'the mother would like to get SMSs on: {{ num }}')
                    .context({ num: normalised_no }),

                choices: [
                    new Choice('yes', $('Yes')),
                    new Choice('no', $('No')),
                ],

                next: function(choice) {
                    return {
                        yes: 'states:clinic_code',
                        no: 'states:mobile_no'
                    } [choice.value];
                }
            });
        });

        self.states.add('states:clinic_code', function(name) {
            return new FreeText(name, {
                question: $('Please enter the clinic code for the facility ' +
                            'where this pregnancy is being registered:'),

                next: function(content) {
                    self.contact.extra.clinic_code = content;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:due_date_month'
                            };
                        });
                }

            });
        });

        self.states.add('states:mobile_no', function(name, opts) {
            var error = $('Sorry, the mobile number did not validate. ' +
                          'Please reenter the mobile number:');

            var question;
            if (!opts.retry) {
                question = $('Please input the mobile number of the ' +
                            'pregnant woman to be registered:');
            } else {
                question = error;
            }

            return new FreeText(name, {
                question: question,

                check: function(content) {
                    if (!go.utils.check_valid_number(content)) {
                        return error;
                    }
                },

                next: function(content) {
                    msisdn = go.utils.denormalise_sa_msisdn(content);
                    self.contact.extra.working_on = msisdn;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:clinic_code',
                            };
                        });
                }
            });
        });

        self.states.add('states:due_date_month', function(name) {

            var today = go.utils.get_today(self.im.config.testing_today);
            var month = today.getMonth();   // 0-bound

            return new ChoiceState(name, {

                question: $('Please select the month when the baby is due:'),

                choices: go.utils.make_month_choices($, month, 9),

                next: function(choice) {
                    self.contact.extra.due_date_month = choice.value;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:id_type',
                            };
                        });
                }
            });
        });

        self.states.add('states:id_type', function(name) {
            return new ChoiceState(name, {
                question: $('What kind of identification does the pregnant ' +
                            'mother have?'),

                choices: [
                    new Choice('sa_id', $('SA ID')),
                    new Choice('passport', $('Passport')),
                    new Choice('none', $('None')),
                ],

                next: function(choice) {
                    self.contact.extra.id_type = choice.value;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                sa_id: 'states:sa_id',
                                passport: 'states:passport_origin',
                                none: 'states:birth_year'
                            } [choice.value];
                        });
                }
            });
        });

        self.states.add('states:sa_id', function(name, opts) {
            var error = $('Sorry, the mother\'s ID number did not validate. ' +
                          'Please reenter the SA ID number:');

            var question;
            if (!opts.retry) {
                question = $('Please enter the pregnant mother\'s SA ID ' +
                            'number:');
            } else {
                question = error;
            }

            return new FreeText(name, {
                question: question,

                check: function(content) {
                    if (!go.utils.validate_id_sa(content)) {
                        return error;
                    }
                },

                next: function(content) {
                    self.contact.extra.sa_id = content;

                    var id_date_of_birth = go.utils.extract_id_dob(content);
                    self.contact.extra.birth_year = id_date_of_birth.slice(0,4);
                    self.contact.extra.birth_month = id_date_of_birth.slice(5,7);
                    self.contact.extra.birth_day = id_date_of_birth.slice(8,10);
                    self.contact.extra.dob = id_date_of_birth;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:language',
                            };
                        });
                }
            });
        });

        self.states.add('states:passport_origin', function(name) {
            return new ChoiceState(name, {
                question: $('What is the country of origin of the passport?'),

                choices: [
                    new Choice('zw', $('Zimbabwe')),
                    new Choice('mz', $('Mozambique')),
                    new Choice('mw', $('Malawi')),
                    new Choice('ng', $('Nigeria')),
                    new Choice('cd', $('DRC')),
                    new Choice('so', $('Somalia')),
                    new Choice('other', $('Other')),
                ],

                next: function(choice) {
                    self.contact.extra.passport_origin = choice.value;

                    return self.im.contacts.save(self.contact)
                    .then(function() {
                        return {
                            name: 'states:passport_no'
                        };
                    });
                }
            });
        });

        self.states.add('states:passport_no', function(name) {
            return new FreeText(name, {
                question: $('Please enter your Passport number:'),

                next: function(content) {
                    self.contact.extra.passport_no = content;

                    return self.im.contacts.save(self.contact)
                    .then(function() {
                        return {
                            name: 'states:language'
                        };
                    });
                }
            });
        });

        self.states.add('states:birth_year', function(name, opts) {
            var error = $('There was an error in your entry. Please ' +
                        'carefully enter the mother\'s year of birth again (eg ' +
                        '2001)');

            var question;
            if (!opts.retry) {
                question = $('Please enter the year that the pregnant mother was born (eg ' +
                    '1981)');
            } else {
                question = error;
            }

            return new FreeText(name, {
                question: question,

                check: function(content) {
                    if (!go.utils.check_number_in_range(content, 1900, go.utils.get_today(self.im.config.testing_today).getFullYear())) {
                        return error;
                    }
                },

                next: function(content) {
                    self.contact.extra.birth_year = content;

                    return self.im.contacts.save(self.contact)
                    .then(function() {
                        return {
                            name: 'states:birth_month'
                        };
                    });
                }
            });
        });

        self.states.add('states:birth_month', function(name) {
            return new ChoiceState(name, {
                question: $('Please enter the month that you were born.'),

                choices: go.utils.make_month_choices($, 0, 12),

                next: function(choice) {
                    self.contact.extra.birth_month = choice.value;

                    return self.im.contacts.save(self.contact)
                    .then(function() {
                        return {
                            name: 'states:birth_day'
                        };
                    });
                }
            });
        });

        self.states.add('states:birth_day', function(name, opts) {
            var error = $('There was an error in your entry. Please ' +
                        'carefully enter the mother\'s day of birth again (eg ' +
                        '8)');

            var question;
            if (!opts.retry) {
                question = $('Please enter the day that the mother was born ' +
                    '(eg 14).');
            } else {
                question = error;
            }

            return new FreeText(name, {
                question: question,

                check: function(content) {
                    if (!go.utils.check_number_in_range(content, 1, 31)) {
                        return error;
                    }
                },

                next: function(content) {
                    if (content.length === 1) {
                        content = '0' + content;
                    }
                    self.contact.extra.birth_day = content;
                    self.contact.extra.dob = (self.im.user.answers['states:birth_year'] +
                        '-' + self.im.user.answers['states:birth_month'] +
                        '-' + content);

                    return self.im.contacts.save(self.contact)
                    .then(function() {
                        return {
                            name: 'states:language'
                        };
                    });
                }
            });
        });

        self.states.add('states:language', function(name) {
            return new ChoiceState(name, {
                question: $('Please select the language that the ' +
                            'pregnant mother would like to get messages in:'),

                choices: [
                    new Choice('en', $('English')),
                    new Choice('af', $('Afrikaans')),
                    new Choice('zu', $('Zulu')),
                    new Choice('xh', $('Xhosa')),
                    new Choice('so', $('Sotho')),
                ],

                next: function(choice) {
                    self.contact.extra.language_choice = choice.value;

                    return self.im.user.set_lang(choice.value)
                    // we may not have to run this for this flow
                    .then(function() {
                        return self.im.contacts.save(self.contact);
                    })
                    .then(function() {
                        if (self.user !== undefined && self.user.extra.working_on !== undefined) {
                            self.user.extra.working_on = "";
                            return self.im.contacts.save(self.user);
                        }
                    })
                    .then(function() {
                        return 'states:end_success';
                    });
                }
            });
        });

        self.states.add('states:end_success', function(name) {
            return new EndState(name, {
                text: $('Thank you. The pregnant woman will now ' +
                        'receive weekly messages about her pregnancy ' +
                        'from the Department of Health.'),

                next: 'states:start'
            });
        });

    });

    return {
        GoNDOH: GoNDOH
    };
}();
<commit_msg>improve indenting for clinic<commit_after>go.app = function() {
    var vumigo = require('vumigo_v02');
    var App = vumigo.App;
    var Choice = vumigo.states.Choice;
    var ChoiceState = vumigo.states.ChoiceState;
    var EndState = vumigo.states.EndState;
    var FreeText = vumigo.states.FreeText;

    var GoNDOH = App.extend(function(self) {
        App.call(self, 'states:start');
        var $ = self.$;

        self.init = function() {

            self.im.on('session:close', function(e) {
                if (!self.should_send_dialback(e)) { return; }
                return self.send_dialback();
            });

            return self.im.contacts
                .for_user()
                .then(function(user_contact) {
                    if ((user_contact.extra.working_on !== undefined) && (user_contact.extra.working_on !== "")){
                        self.user = user_contact;
                        return self.im.contacts.get(user_contact.extra.working_on, {create: true})
                            .then(function(working_on){
                                self.contact = working_on;
                            });
                    } else {
                        self.contact = user_contact;
                    }
                });
        };

        self.should_send_dialback = function(e) {
            return e.user_terminated
                && !go.utils.is_true(self.contact.extra.redial_sms_sent);
        };

        self.send_dialback = function() {
            return self.im.outbound
                .send_to_user({
                    endpoint: 'sms',
                    content: self.get_finish_reg_sms()
                })
                .then(function() {
                    self.contact.extra.redial_sms_sent = 'true';
                    return self.im.contacts.save(self.contact);
                });
        };

        self.get_finish_reg_sms = function() {
            return $("Please dial back in to {{ USSD_number }} to complete the pregnancy registration.")
                .context({
                    USSD_number: self.im.config.channel
                });
        };

        self.states.add('states:start', function(name) {
            var normalised_no = go.utils.normalise_sa_msisdn(self.im.user.addr);

            return new ChoiceState(name, {
                question: $('Welcome to The Department of Health\'s ' +
                            'MomConnect. Tell us if this is the no. that ' +
                            'the mother would like to get SMSs on: {{ num }}')
                    .context({ num: normalised_no }),

                choices: [
                    new Choice('yes', $('Yes')),
                    new Choice('no', $('No')),
                ],

                next: function(choice) {
                    return {
                        yes: 'states:clinic_code',
                        no: 'states:mobile_no'
                    } [choice.value];
                }
            });
        });

        self.states.add('states:clinic_code', function(name) {
            return new FreeText(name, {
                question: $('Please enter the clinic code for the facility ' +
                            'where this pregnancy is being registered:'),

                next: function(content) {
                    self.contact.extra.clinic_code = content;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:due_date_month'
                            };
                        });
                }

            });
        });

        self.states.add('states:mobile_no', function(name, opts) {
            var error = $('Sorry, the mobile number did not validate. ' +
                          'Please reenter the mobile number:');

            var question;
            if (!opts.retry) {
                question = $('Please input the mobile number of the ' +
                            'pregnant woman to be registered:');
            } else {
                question = error;
            }

            return new FreeText(name, {
                question: question,

                check: function(content) {
                    if (!go.utils.check_valid_number(content)) {
                        return error;
                    }
                },

                next: function(content) {
                    msisdn = go.utils.denormalise_sa_msisdn(content);
                    self.contact.extra.working_on = msisdn;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:clinic_code',
                            };
                        });
                }
            });
        });

        self.states.add('states:due_date_month', function(name) {

            var today = go.utils.get_today(self.im.config.testing_today);
            var month = today.getMonth();   // 0-bound

            return new ChoiceState(name, {

                question: $('Please select the month when the baby is due:'),

                choices: go.utils.make_month_choices($, month, 9),

                next: function(choice) {
                    self.contact.extra.due_date_month = choice.value;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:id_type',
                            };
                        });
                }
            });
        });

        self.states.add('states:id_type', function(name) {
            return new ChoiceState(name, {
                question: $('What kind of identification does the pregnant ' +
                            'mother have?'),

                choices: [
                    new Choice('sa_id', $('SA ID')),
                    new Choice('passport', $('Passport')),
                    new Choice('none', $('None')),
                ],

                next: function(choice) {
                    self.contact.extra.id_type = choice.value;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                sa_id: 'states:sa_id',
                                passport: 'states:passport_origin',
                                none: 'states:birth_year'
                            } [choice.value];
                        });
                }
            });
        });

        self.states.add('states:sa_id', function(name, opts) {
            var error = $('Sorry, the mother\'s ID number did not validate. ' +
                          'Please reenter the SA ID number:');

            var question;
            if (!opts.retry) {
                question = $('Please enter the pregnant mother\'s SA ID ' +
                            'number:');
            } else {
                question = error;
            }

            return new FreeText(name, {
                question: question,

                check: function(content) {
                    if (!go.utils.validate_id_sa(content)) {
                        return error;
                    }
                },

                next: function(content) {
                    self.contact.extra.sa_id = content;

                    var id_date_of_birth = go.utils.extract_id_dob(content);
                    self.contact.extra.birth_year = id_date_of_birth.slice(0,4);
                    self.contact.extra.birth_month = id_date_of_birth.slice(5,7);
                    self.contact.extra.birth_day = id_date_of_birth.slice(8,10);
                    self.contact.extra.dob = id_date_of_birth;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:language',
                            };
                        });
                }
            });
        });

        self.states.add('states:passport_origin', function(name) {
            return new ChoiceState(name, {
                question: $('What is the country of origin of the passport?'),

                choices: [
                    new Choice('zw', $('Zimbabwe')),
                    new Choice('mz', $('Mozambique')),
                    new Choice('mw', $('Malawi')),
                    new Choice('ng', $('Nigeria')),
                    new Choice('cd', $('DRC')),
                    new Choice('so', $('Somalia')),
                    new Choice('other', $('Other')),
                ],

                next: function(choice) {
                    self.contact.extra.passport_origin = choice.value;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:passport_no'
                            };
                        });
                }
            });
        });

        self.states.add('states:passport_no', function(name) {
            return new FreeText(name, {
                question: $('Please enter your Passport number:'),

                next: function(content) {
                    self.contact.extra.passport_no = content;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:language'
                            };
                        });
                }
            });
        });

        self.states.add('states:birth_year', function(name, opts) {
            var error = $('There was an error in your entry. Please ' +
                        'carefully enter the mother\'s year of birth again (eg ' +
                        '2001)');

            var question;
            if (!opts.retry) {
                question = $('Please enter the year that the pregnant mother was born (eg ' +
                    '1981)');
            } else {
                question = error;
            }

            return new FreeText(name, {
                question: question,

                check: function(content) {
                    if (!go.utils.check_number_in_range(content, 1900, go.utils.get_today(self.im.config.testing_today).getFullYear())) {
                        return error;
                    }
                },

                next: function(content) {
                    self.contact.extra.birth_year = content;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:birth_month'
                            };
                        });
                }
            });
        });

        self.states.add('states:birth_month', function(name) {
            return new ChoiceState(name, {
                question: $('Please enter the month that you were born.'),

                choices: go.utils.make_month_choices($, 0, 12),

                next: function(choice) {
                    self.contact.extra.birth_month = choice.value;

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:birth_day'
                            };
                        });
                }
            });
        });

        self.states.add('states:birth_day', function(name, opts) {
            var error = $('There was an error in your entry. Please ' +
                        'carefully enter the mother\'s day of birth again (eg ' +
                        '8)');

            var question;
            if (!opts.retry) {
                question = $('Please enter the day that the mother was born ' +
                    '(eg 14).');
            } else {
                question = error;
            }

            return new FreeText(name, {
                question: question,

                check: function(content) {
                    if (!go.utils.check_number_in_range(content, 1, 31)) {
                        return error;
                    }
                },

                next: function(content) {
                    if (content.length === 1) {
                        content = '0' + content;
                    }
                    self.contact.extra.birth_day = content;
                    self.contact.extra.dob = (self.im.user.answers['states:birth_year'] +
                        '-' + self.im.user.answers['states:birth_month'] +
                        '-' + content);

                    return self.im.contacts.save(self.contact)
                        .then(function() {
                            return {
                                name: 'states:language'
                            };
                        });
                }
            });
        });

        self.states.add('states:language', function(name) {
            return new ChoiceState(name, {
                question: $('Please select the language that the ' +
                            'pregnant mother would like to get messages in:'),

                choices: [
                    new Choice('en', $('English')),
                    new Choice('af', $('Afrikaans')),
                    new Choice('zu', $('Zulu')),
                    new Choice('xh', $('Xhosa')),
                    new Choice('so', $('Sotho')),
                ],

                next: function(choice) {
                    self.contact.extra.language_choice = choice.value;

                    return self.im.user.set_lang(choice.value)
                    // we may not have to run this for this flow
                        .then(function() {
                            return self.im.contacts.save(self.contact);
                        })
                        .then(function() {
                            if (self.user !== undefined && self.user.extra.working_on !== undefined) {
                                self.user.extra.working_on = "";
                                return self.im.contacts.save(self.user);
                            }
                        })
                        .then(function() {
                            return 'states:end_success';
                        });
                }
            });
        });

        self.states.add('states:end_success', function(name) {
            return new EndState(name, {
                text: $('Thank you. The pregnant woman will now ' +
                        'receive weekly messages about her pregnancy ' +
                        'from the Department of Health.'),

                next: 'states:start'
            });
        });

    });

    return {
        GoNDOH: GoNDOH
    };
}();
<|endoftext|>


<commit_before>/*
    ***** BEGIN LICENSE BLOCK *****

    Copyright © 2009 Center for History and New Media
                     George Mason University, Fairfax, Virginia, USA
                     http://zotero.org

    This file is part of Zotero.

    Zotero is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Zotero is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Zotero.  If not, see <http://www.gnu.org/licenses/>.

    ***** END LICENSE BLOCK *****
*/

Zotero.MIME = new function(){
	this.isTextType = isTextType;
	this.isExternalTextExtension = isExternalTextExtension;
	this.getPrimaryExtension = getPrimaryExtension;
	this.sniffForMIMEType = sniffForMIMEType;
	this.sniffForBinary = sniffForBinary;
	this.getMIMETypeFromData = getMIMETypeFromData;
	this.getMIMETypeFromFile = getMIMETypeFromFile;
	this.hasNativeHandler = hasNativeHandler;
	this.hasInternalHandler = hasInternalHandler;
	this.fileHasInternalHandler = fileHasInternalHandler;

	// Magic numbers
	var _snifferEntries = [
		["%PDF-", "application/pdf"],
		["%!PS-Adobe-", 'application/postscript', 0],
		["%! PS-Adobe-", 'application/postscript', 0],
		["\uFFFD\uFFFD\x11\u0871\x1A\uFFFD\x00\x00", "application/msword", 0],
		["From", 'text/plain', 0],
		[">From", 'text/plain', 0],
		["#!", 'text/plain', 0],
		["<?xml", 'text/xml', 0],
		["<!DOCTYPE html", 'text/html', 0],
		["<html", 'text/html', 0],
		["\uFFFD\uFFFD\uFFFD\uFFFD", 'image/jpeg', 0],
		["GIF8", 'image/gif', 0],
		["\uFFFDPNG", 'image/png', 0],
		["PK\x03\x04", "application/vnd.oasis.opendocument.text", 0],
		["JFIF", 'image/jpeg'],
		["FLV", "video/x-flv", 0]

	];

	var _textTypes = {
		'application/xhtml+xml': true,
		'application/xml': true,
		'application/x-javascript': true
	};

	// MIME types handled natively by Gecko
	// DEBUG: There's definitely a better way of getting these
	var _nativeMIMETypes = {
		'text/html': true,
		'text/css': true,
		'image/jpeg': true,
		'image/gif': true,
		'image/png': true,
		'image/svg+xml': true,
		'text/xml': true,
		'application/xhtml+xml': true,
		'application/xml': true,
		'text/plain': true,
		'application/x-javascript': true
	};

	// Extensions of text files (generally XML) to force to be external
	var _externalTextExtensions = {
		graffle: true,
		mm: true,
		opml: true,
		bib: true
	};

	function isTextType(mimeType) {
		return mimeType.substr(0, 5) == 'text/' || _textTypes[mimeType];
	}

	/*
	 * Check if file extension should be forced to open externally
	 */
	function isExternalTextExtension(ext){
		return typeof _externalTextExtensions[ext] != 'undefined';
	}

	/*
	 * Our own wrapper around the MIME service's getPrimaryExtension() that
	 * works a little better
	 */
	function getPrimaryExtension(mimeType, ext) {
		// Enforce some extensions
		switch (mimeType) {
			case 'text/html':
			case 'application/xhtml+xml':
				return 'html';

			case 'application/pdf':
			case 'application/x-pdf':
			case 'application/acrobat':
			case 'applications/vnd.pdf':
			case 'text/pdf':
			case 'text/x-pdf':
				return 'pdf';

			case 'image/jpg':
			case 'image/jpeg':
				return 'jpg';

			case 'image/gif':
				return 'gif';

			case 'application/msword':
			case 'application/doc':
			case 'application/vnd.msword':
			case 'application/vnd.ms-word':
			case 'application/winword':
			case 'application/word':
			case 'application/x-msw6':
			case 'application/x-msword':
				return 'doc';

			case 'application/vnd.oasis.opendocument.text':
			case 'application/x-vnd.oasis.opendocument.text':
				return 'odt';

			case 'video/flv':
			case 'video/x-flv':
				return 'flv';

			case 'image/tif':
			case 'image/tiff':
			case 'image/tif':
			case 'image/x-tif':
			case 'image/tiff':
			case 'image/x-tiff':
			case 'application/tif':
			case 'application/x-tif':
			case 'application/tiff':
			case 'application/x-tiff':
				return 'tiff';

			case 'application/zip':
			case 'application/x-zip':
			case 'application/x-zip-compressed':
			case 'application/x-compress':
			case 'application/x-compressed':
			case 'multipart/x-zip':
				return 'zip';

			case 'video/quicktime':
			case 'video/x-quicktime':
				return 'mov';

			case 'video/avi':
			case 'video/msvideo':
			case 'video/x-msvideo':
				return 'avi';

			case 'audio/wav':
			case 'audio/x-wav':
			case 'audio/wave':
				return 'wav';

			case 'audio/aiff':
			case 'audio/x-aiff':
			case 'sound/aiff':
				return 'aiff';
		}

		try {
			ext = Components.classes["@mozilla.org/mime;1"]
				.getService(Components.interfaces.nsIMIMEService)
				.getPrimaryExtension(mimeType, ext);
		}
		// nsIMIMEService.getPrimaryExtension() doesn't work on Linux and
		// throws an error if it can't find an extension
		catch (e) {}

		return ext ? ext : '';
	}

	/*
	 * Searches string for magic numbers
	 */
	function sniffForMIMEType(str){
		for (var i in _snifferEntries){
			var match = false;
			// If an offset is defined, match only from there
			if (typeof _snifferEntries[i][2] != 'undefined') {
				if (str.substr(i[2]).indexOf(_snifferEntries[i][0]) == 0) {
					match = true;
				}
			}
			// Otherwise allow match anywhere in sample
			// (128 bytes from getSample() by default)
			else if (str.indexOf(_snifferEntries[i][0]) != -1) {
				match = true;
			}

			if (match) {
				return _snifferEntries[i][1];
			}
		}

		return false;
	}

	/*
	 * Searches string for embedded nulls
	 *
	 * Returns 'application/octet-stream' or 'text/plain'
	 */
	function sniffForBinary(str){
		for (var i=0; i<str.length; i++){
			if (!_isTextCharacter(str.charAt(i))){
				return 'application/octet-stream';
			}
		}
		return 'text/plain';
	}

	/*
	 * Try to determine the MIME type of a string, using a few different
	 * techniques
	 *
	 * ext is an optional file extension hint if data sniffing is unsuccessful
	 */
	function getMIMETypeFromData(str, ext){
		var mimeType = sniffForMIMEType(str);
		if (mimeType){
			Zotero.debug('Detected MIME type ' + mimeType);
			return mimeType;
		}

		try {
			if (ext) {
				var mimeType = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
					.getService(Components.interfaces.nsIMIMEService).getTypeFromExtension(ext);
				Zotero.debug('Got MIME type ' + mimeType + ' from extension');
				return mimeType;
			}
		}
		catch (e) {}

		var mimeType = sniffForBinary(str);
		Zotero.debug('Cannot determine MIME type from magic number or extension -- settling for ' + mimeType);
		return mimeType;
	}

	/*
	 * Try to determine the MIME type of the file, using a few different
	 * techniques
	 */
	function getMIMETypeFromFile(file){
		var str = Zotero.File.getSample(file);
		var ext = Zotero.File.getExtension(file);

		return getMIMETypeFromData(str, ext);
	}

	this.getMIMETypeFromURL = function (url, callback) {
		Zotero.HTTP.doHead(url, function(xmlhttp) {
			if (xmlhttp.status != 200 && xmlhttp.status != 204) {
				Zotero.debug("Attachment HEAD request returned with status code "
					+ xmlhttp.status + " in Zotero.MIME.getMIMETypeFromURL()", 2);
				var mimeType = '';
			}
			else {
				var mimeType = xmlhttp.channel.contentType;
			}

			var nsIURL = Components.classes["@mozilla.org/network/standard-url;1"]
						.createInstance(Components.interfaces.nsIURL);
			nsIURL.spec = url;

			// Override MIME type to application/pdf if extension is .pdf --
			// workaround for sites that respond to the HEAD request with an
			// invalid MIME type (https://www.zotero.org/trac/ticket/460)
			//
			// Downloaded file is inspected in attachment code and deleted if actually HTML
			if (nsIURL.fileName.match(/pdf$/) || url.match(/pdf$/)) {
				mimeType = 'application/pdf';
			}

			var ext = nsIURL.fileExtension;
			var hasNativeHandler = Zotero.MIME.hasNativeHandler(mimeType, ext)

			callback(mimeType, hasNativeHandler);
		});
	}

	/*
	 * Determine if a MIME type can be handled natively
	 * or if it needs to be passed off to a plugin or external helper app
	 *
	 * ext is an optional extension hint (only needed for text files
	 * that should be forced to open externally)
	 *
	 * Note: it certainly seems there should be a more native way of doing this
	 * without replicating all the Mozilla functionality
	 *
	 * Note: nsIMIMEInfo provides a hasDefaultHandler() method, but it doesn't
	 * do what we need
	 */
	function hasNativeHandler(mimeType, ext) {
		if (mimeType.match(/^text\//)) {
			if (isExternalTextExtension(ext)){
				Zotero.debug(mimeType + " file has extension '" + ext + "' that should be handled externally");
				return false;
			}
			return true;
		}

		if (_nativeMIMETypes[mimeType]){
			Zotero.debug('MIME type ' + mimeType + ' can be handled natively');
			return true;
		}

		return null;
	}

	/*
	 * Determine if a MIME type can be handled internally
	 * or if it needs to be passed off to an external helper app
	 *
	 * Similar to hasNativeHandler() but also includes plugins
	 */
	function hasInternalHandler(mimeType, ext) {
		var isNative = hasNativeHandler(mimeType, ext);
		if (isNative !== null) {
			return isNative;
		}

		// Is there a better way to get to navigator?
		var types = Components.classes["@mozilla.org/appshell/appShellService;1"]
				.getService(Components.interfaces.nsIAppShellService)
				.hiddenDOMWindow.navigator.mimeTypes;

		for (var i in types){
			if (types[i].type && types[i].type == mimeType){
				Zotero.debug('MIME type ' + mimeType + ' can be handled by plugins');
				return true;
			}
		}

		Zotero.debug('MIME type ' + mimeType + ' cannot be handled internally');
		return false;
	}

	function fileHasInternalHandler(file){
		var mimeType = getMIMETypeFromFile(file);
		var ext = Zotero.File.getExtension(file);
		return hasInternalHandler(mimeType, ext);
	}

	/*
	 * Detect whether a character is text
	 *
	 * Based on RFC 2046 Section 4.1.2. Treat any char 0-31
	 * except the 9-13 range (\t, \n, \v, \f, \r) and char 27 (used by
     * encodings like Shift_JIS) as non-text
	 *
	 * This is the logic used by the Mozilla sniffer.
	 */
	function _isTextCharacter(chr){
		var chr = chr.charCodeAt(0);
		return chr > 31 || (9 <= chr && chr <=13 ) || chr == 27;
	}
}
<commit_msg>Don't use "application/vnd.oasis.opendocument.text" for all ZIP files<commit_after>/*
    ***** BEGIN LICENSE BLOCK *****

    Copyright © 2009 Center for History and New Media
                     George Mason University, Fairfax, Virginia, USA
                     http://zotero.org

    This file is part of Zotero.

    Zotero is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Zotero is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Zotero.  If not, see <http://www.gnu.org/licenses/>.

    ***** END LICENSE BLOCK *****
*/

Zotero.MIME = new function(){
	this.isTextType = isTextType;
	this.isExternalTextExtension = isExternalTextExtension;
	this.getPrimaryExtension = getPrimaryExtension;
	this.sniffForMIMEType = sniffForMIMEType;
	this.sniffForBinary = sniffForBinary;
	this.getMIMETypeFromData = getMIMETypeFromData;
	this.getMIMETypeFromFile = getMIMETypeFromFile;
	this.hasNativeHandler = hasNativeHandler;
	this.hasInternalHandler = hasInternalHandler;
	this.fileHasInternalHandler = fileHasInternalHandler;

	// Magic numbers
	var _snifferEntries = [
		["%PDF-", "application/pdf"],
		["%!PS-Adobe-", 'application/postscript', 0],
		["%! PS-Adobe-", 'application/postscript', 0],
		["\uFFFD\uFFFD\x11\u0871\x1A\uFFFD\x00\x00", "application/msword", 0],
		["From", 'text/plain', 0],
		[">From", 'text/plain', 0],
		["#!", 'text/plain', 0],
		["<?xml", 'text/xml', 0],
		["<!DOCTYPE html", 'text/html', 0],
		["<html", 'text/html', 0],
		["\uFFFD\uFFFD\uFFFD\uFFFD", 'image/jpeg', 0],
		["GIF8", 'image/gif', 0],
		["\uFFFDPNG", 'image/png', 0],
		["JFIF", 'image/jpeg'],
		["FLV", "video/x-flv", 0]

	];

	var _textTypes = {
		'application/xhtml+xml': true,
		'application/xml': true,
		'application/x-javascript': true
	};

	// MIME types handled natively by Gecko
	// DEBUG: There's definitely a better way of getting these
	var _nativeMIMETypes = {
		'text/html': true,
		'text/css': true,
		'image/jpeg': true,
		'image/gif': true,
		'image/png': true,
		'image/svg+xml': true,
		'text/xml': true,
		'application/xhtml+xml': true,
		'application/xml': true,
		'text/plain': true,
		'application/x-javascript': true
	};

	// Extensions of text files (generally XML) to force to be external
	var _externalTextExtensions = {
		graffle: true,
		mm: true,
		opml: true,
		bib: true
	};

	function isTextType(mimeType) {
		return mimeType.substr(0, 5) == 'text/' || _textTypes[mimeType];
	}

	/*
	 * Check if file extension should be forced to open externally
	 */
	function isExternalTextExtension(ext){
		return typeof _externalTextExtensions[ext] != 'undefined';
	}

	/*
	 * Our own wrapper around the MIME service's getPrimaryExtension() that
	 * works a little better
	 */
	function getPrimaryExtension(mimeType, ext) {
		// Enforce some extensions
		switch (mimeType) {
			case 'text/html':
			case 'application/xhtml+xml':
				return 'html';

			case 'application/pdf':
			case 'application/x-pdf':
			case 'application/acrobat':
			case 'applications/vnd.pdf':
			case 'text/pdf':
			case 'text/x-pdf':
				return 'pdf';

			case 'image/jpg':
			case 'image/jpeg':
				return 'jpg';

			case 'image/gif':
				return 'gif';

			case 'application/msword':
			case 'application/doc':
			case 'application/vnd.msword':
			case 'application/vnd.ms-word':
			case 'application/winword':
			case 'application/word':
			case 'application/x-msw6':
			case 'application/x-msword':
				return 'doc';

			case 'application/vnd.oasis.opendocument.text':
			case 'application/x-vnd.oasis.opendocument.text':
				return 'odt';

			case 'video/flv':
			case 'video/x-flv':
				return 'flv';

			case 'image/tif':
			case 'image/tiff':
			case 'image/tif':
			case 'image/x-tif':
			case 'image/tiff':
			case 'image/x-tiff':
			case 'application/tif':
			case 'application/x-tif':
			case 'application/tiff':
			case 'application/x-tiff':
				return 'tiff';

			case 'application/zip':
			case 'application/x-zip':
			case 'application/x-zip-compressed':
			case 'application/x-compress':
			case 'application/x-compressed':
			case 'multipart/x-zip':
				return 'zip';

			case 'video/quicktime':
			case 'video/x-quicktime':
				return 'mov';

			case 'video/avi':
			case 'video/msvideo':
			case 'video/x-msvideo':
				return 'avi';

			case 'audio/wav':
			case 'audio/x-wav':
			case 'audio/wave':
				return 'wav';

			case 'audio/aiff':
			case 'audio/x-aiff':
			case 'sound/aiff':
				return 'aiff';
		}

		try {
			ext = Components.classes["@mozilla.org/mime;1"]
				.getService(Components.interfaces.nsIMIMEService)
				.getPrimaryExtension(mimeType, ext);
		}
		// nsIMIMEService.getPrimaryExtension() doesn't work on Linux and
		// throws an error if it can't find an extension
		catch (e) {}

		return ext ? ext : '';
	}

	/*
	 * Searches string for magic numbers
	 */
	function sniffForMIMEType(str){
		for (var i in _snifferEntries){
			var match = false;
			// If an offset is defined, match only from there
			if (typeof _snifferEntries[i][2] != 'undefined') {
				if (str.substr(i[2]).indexOf(_snifferEntries[i][0]) == 0) {
					match = true;
				}
			}
			// Otherwise allow match anywhere in sample
			// (128 bytes from getSample() by default)
			else if (str.indexOf(_snifferEntries[i][0]) != -1) {
				match = true;
			}

			if (match) {
				return _snifferEntries[i][1];
			}
		}

		return false;
	}

	/*
	 * Searches string for embedded nulls
	 *
	 * Returns 'application/octet-stream' or 'text/plain'
	 */
	function sniffForBinary(str){
		for (var i=0; i<str.length; i++){
			if (!_isTextCharacter(str.charAt(i))){
				return 'application/octet-stream';
			}
		}
		return 'text/plain';
	}

	/*
	 * Try to determine the MIME type of a string, using a few different
	 * techniques
	 *
	 * ext is an optional file extension hint if data sniffing is unsuccessful
	 */
	function getMIMETypeFromData(str, ext){
		var mimeType = sniffForMIMEType(str);
		if (mimeType){
			Zotero.debug('Detected MIME type ' + mimeType);
			return mimeType;
		}

		try {
			if (ext) {
				var mimeType = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
					.getService(Components.interfaces.nsIMIMEService).getTypeFromExtension(ext);
				Zotero.debug('Got MIME type ' + mimeType + ' from extension');
				return mimeType;
			}
		}
		catch (e) {}

		var mimeType = sniffForBinary(str);
		Zotero.debug('Cannot determine MIME type from magic number or extension -- settling for ' + mimeType);
		return mimeType;
	}

	/*
	 * Try to determine the MIME type of the file, using a few different
	 * techniques
	 */
	function getMIMETypeFromFile(file){
		var str = Zotero.File.getSample(file);
		var ext = Zotero.File.getExtension(file);

		return getMIMETypeFromData(str, ext);
	}

	this.getMIMETypeFromURL = function (url, callback) {
		Zotero.HTTP.doHead(url, function(xmlhttp) {
			if (xmlhttp.status != 200 && xmlhttp.status != 204) {
				Zotero.debug("Attachment HEAD request returned with status code "
					+ xmlhttp.status + " in Zotero.MIME.getMIMETypeFromURL()", 2);
				var mimeType = '';
			}
			else {
				var mimeType = xmlhttp.channel.contentType;
			}

			var nsIURL = Components.classes["@mozilla.org/network/standard-url;1"]
						.createInstance(Components.interfaces.nsIURL);
			nsIURL.spec = url;

			// Override MIME type to application/pdf if extension is .pdf --
			// workaround for sites that respond to the HEAD request with an
			// invalid MIME type (https://www.zotero.org/trac/ticket/460)
			//
			// Downloaded file is inspected in attachment code and deleted if actually HTML
			if (nsIURL.fileName.match(/pdf$/) || url.match(/pdf$/)) {
				mimeType = 'application/pdf';
			}

			var ext = nsIURL.fileExtension;
			var hasNativeHandler = Zotero.MIME.hasNativeHandler(mimeType, ext)

			callback(mimeType, hasNativeHandler);
		});
	}

	/*
	 * Determine if a MIME type can be handled natively
	 * or if it needs to be passed off to a plugin or external helper app
	 *
	 * ext is an optional extension hint (only needed for text files
	 * that should be forced to open externally)
	 *
	 * Note: it certainly seems there should be a more native way of doing this
	 * without replicating all the Mozilla functionality
	 *
	 * Note: nsIMIMEInfo provides a hasDefaultHandler() method, but it doesn't
	 * do what we need
	 */
	function hasNativeHandler(mimeType, ext) {
		if (mimeType.match(/^text\//)) {
			if (isExternalTextExtension(ext)){
				Zotero.debug(mimeType + " file has extension '" + ext + "' that should be handled externally");
				return false;
			}
			return true;
		}

		if (_nativeMIMETypes[mimeType]){
			Zotero.debug('MIME type ' + mimeType + ' can be handled natively');
			return true;
		}

		return null;
	}

	/*
	 * Determine if a MIME type can be handled internally
	 * or if it needs to be passed off to an external helper app
	 *
	 * Similar to hasNativeHandler() but also includes plugins
	 */
	function hasInternalHandler(mimeType, ext) {
		var isNative = hasNativeHandler(mimeType, ext);
		if (isNative !== null) {
			return isNative;
		}

		// Is there a better way to get to navigator?
		var types = Components.classes["@mozilla.org/appshell/appShellService;1"]
				.getService(Components.interfaces.nsIAppShellService)
				.hiddenDOMWindow.navigator.mimeTypes;

		for (var i in types){
			if (types[i].type && types[i].type == mimeType){
				Zotero.debug('MIME type ' + mimeType + ' can be handled by plugins');
				return true;
			}
		}

		Zotero.debug('MIME type ' + mimeType + ' cannot be handled internally');
		return false;
	}

	function fileHasInternalHandler(file){
		var mimeType = getMIMETypeFromFile(file);
		var ext = Zotero.File.getExtension(file);
		return hasInternalHandler(mimeType, ext);
	}

	/*
	 * Detect whether a character is text
	 *
	 * Based on RFC 2046 Section 4.1.2. Treat any char 0-31
	 * except the 9-13 range (\t, \n, \v, \f, \r) and char 27 (used by
     * encodings like Shift_JIS) as non-text
	 *
	 * This is the logic used by the Mozilla sniffer.
	 */
	function _isTextCharacter(chr){
		var chr = chr.charCodeAt(0);
		return chr > 31 || (9 <= chr && chr <=13 ) || chr == 27;
	}
}
<|endoftext|>


<commit_before>/*jshint globalstrict:true*/
'use strict';

var isDefined = angular.isDefined,
  isUndefined = angular.isUndefined,
  isFunction = angular.isFunction,
  isString = angular.isString,
  isNumber = angular.isNumber,
  isObject = angular.isObject,
  isArray = angular.isArray,
  forEach = angular.forEach,
  extend = angular.extend,
  copy = angular.copy,
  equals = angular.equals;<commit_msg>feat(common): strings helpers<commit_after>/*jshint globalstrict:true*/
'use strict';

var isDefined = angular.isDefined,
  isUndefined = angular.isUndefined,
  isFunction = angular.isFunction,
  isString = angular.isString,
  isNumber = angular.isNumber,
  isObject = angular.isObject,
  isArray = angular.isArray,
  forEach = angular.forEach,
  extend = angular.extend,
  copy = angular.copy,
  equals = angular.equals;

/**
 * @description
 * returns if a string ends with a particular suffix
 * @param str
 * @param suffix
 * @returns {boolean}
 */
function endsWith(str, suffix) {
  return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

/**
 * @description
 * returns if a string starts with a particular prefix
 * @param str
 * @param prefix
 * @returns {boolean}
 */
function startWith(str, prefix) {
  return !str.indexOf(prefix);
}<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 artjomb
 */
(function(C){
    // put on ext property in CryptoJS
    var ext;
    if (!C.hasOwnProperty("ext")) {
        ext = C.ext = {};
    } else {
        ext = C.ext;
    }

    // Shortcuts
    var Base = C.lib.Base;
    var WordArray = C.lib.WordArray;
    var AES = C.algo.AES;

    // Constants
    ext.const_Zero = WordArray.create([0x00000000, 0x00000000, 0x00000000, 0x00000000]);
    ext.const_One = WordArray.create([0x00000000, 0x00000000, 0x00000000, 0x00000001]);
    ext.const_Rb = WordArray.create([0x00000000, 0x00000000, 0x00000000, 0x00000087]); // 00..0010000111
    ext.const_Rb_Shifted = WordArray.create([0x80000000, 0x00000000, 0x00000000, 0x00000043]); // 100..001000011
    ext.const_nonMSB = WordArray.create([0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF]); // 1^64 || 0^1 || 1^31 || 0^1 || 1^31

    /**
     * Looks into the object to see if it is a WordArray.
     *
     * @param obj Some object
     *
     * @returns {boolean}

     */
    ext.isWordArray = function(obj) {
        return obj && typeof obj.clamp === "function" && typeof obj.concat === "function" && typeof obj.words === "array";
    }

    /**
     * This padding is a 1 bit followed by as many 0 bits as needed to fill
     * up the block. This implementation doesn't work on bits directly,
     * but on bytes. Therefore the granularity is much bigger.
     */
    C.pad.OneZeroPadding = {
        pad: function (data, blocksize) {
            // Shortcut
            var blockSizeBytes = blocksize * 4;

            // Count padding bytes
            var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;

            // Create padding
            var paddingWords = [];
            for (var i = 0; i < nPaddingBytes; i += 4) {
                var paddingWord = 0x00000000;
                if (i === 0) {
                    paddingWord = 0x80000000;
                }
                paddingWords.push(paddingWord);
            }
            var padding = WordArray.create(paddingWords, nPaddingBytes);

            // Add padding
            data.concat(padding);
        },
        unpad: function () {
            // TODO: implement
        }
    };

    /**
     * No padding is applied. This is necessary for streaming cipher modes
     * like CTR.
     */
    C.pad.NoPadding = {
        pad: function () {},
        unpad: function () {}
    };

    /**
     * Returns the n leftmost bytes of the WordArray.
     *
     * @param {WordArray} wordArray WordArray to work on
     * @param {int} n Bytes to retrieve
     *
     * @returns new WordArray
     */
    ext.leftmostBytes = function(wordArray, n){
        var lmArray = wordArray.clone();
        lmArray.sigBytes = n;
        lmArray.clamp();
        return lmArray;
    };

    /**
     * Returns the n rightmost bytes of the WordArray.
     *
     * @param {WordArray} wordArray WordArray to work on
     * @param {int} n Bytes to retrieve (must be positive)
     *
     * @returns new WordArray
     */
    ext.rightmostBytes = function(wordArray, n){
        wordArray.clamp();
        var wordSize = 32;
        var rmArray = wordArray.clone();
        var bitsToShift = (rmArray.sigBytes - n) * 8;
        if (bitsToShift >= wordSize) {
            var popCount = Math.floor(bitsToShift/wordSize);
            bitsToShift -= popCount * wordSize;
            rmArray.words.splice(0, popCount);
            rmArray.sigBytes -= popCount * wordSize / 8;
        }
        if (bitsToShift > 0) {
            ext.bitshift(rmArray, bitsToShift);
            rmArray.sigBytes -= bitsToShift / 8;
        }
        return rmArray;
    };

    /**
     * Returns the n rightmost words of the WordArray. It assumes
     * that the current WordArray has at least n words.
     *
     * @param {WordArray} wordArray WordArray to work on
     * @param {int} n Words to retrieve (must be positive)
     *
     * @returns popped words as new WordArray
     */
    ext.popWords = function(wordArray, n){
        var left = ext.leftmostBytes(wordArray, n * 4);
        wordArray.words = wordArray.words.slice(n);
        wordArray.sigBytes -= n * 4;
        return left;
    };

    /**
     * Shifts the array to the left and returns the shifted dropped elements
     * as WordArray. The initial WordArray must contain at least n bytes and
     * they have to be significant.
     *
     * @param {WordArray} wordArray WordArray to work on (is modified)
     * @param {int} n Bytes to shift (must be positive, default 16)
     *
     * @returns new WordArray
     */
    ext.shiftBytes = function(wordArray, n){
        n = n || 16;
        var r = n % 4;
        n -= r;

        var shiftedArray = WordArray.create();
        for(var i = 0; i < n; i += 4) {
            shiftedArray.words.push(wordArray.words.shift());
            wordArray.sigBytes -= 4;
            shiftedArray.sigBytes += 4;
        }
        if (r > 0) {
            shiftedArray.words.push(wordArray.words[0]);
            shiftedArray.sigBytes += r;

            ext.bitshift(wordArray, r * 8);
            wordArray.sigBytes -= r;
        }
        return shiftedArray;
    };

    /**
     * XORs arr2 to the end of arr1 array. This doesn't modify the current
     * array aside from clamping.
     *
     * @param {WordArray} arr1 Bigger array
     * @param {WordArray} arr2 Smaller array to be XORed to the end
     *
     * @returns new WordArray
     */
    ext.xorendBytes = function(arr1, arr2){
        // TODO: more efficient
        return ext.leftmostBytes(arr1, arr1.sigBytes-arr2.sigBytes)
                .concat(ext.xor(ext.rightmostBytes(arr1, arr2.sigBytes), arr2));
    };

    /**
     * Doubling operation on a 128-bit value. This operation modifies the
     * passed array.
     *
     * @param {WordArray} wordArray WordArray to work on
     *
     * @returns passed WordArray
     */
    ext.dbl = function(wordArray){
        var carry = ext.msb(wordArray);
        ext.bitshift(wordArray, 1);
        if (carry === 1) {
            ext.xor(wordArray, ext.const_Rb);
        }
        return wordArray;
    };

    /**
     * Inverse operation on a 128-bit value. This operation modifies the
     * passed array.
     *
     * @param {WordArray} wordArray WordArray to work on
     *
     * @returns passed WordArray
     */
    ext.inv = function(wordArray){
        var carry = wordArray.words[4] & 1;
        ext.bitshift(wordArray, -1);
        if (carry === 1) {
            ext.xor(wordArray, ext.const_Rb_Shifted);
        }
        return wordArray;
    };

    /**
     * Check whether the word arrays are equal.
     *
     * @param {WordArray} arr1 Array 1
     * @param {WordArray} arr2 Array 2
     *
     * @returns boolean
     */
    ext.equals = function(arr1, arr2){
        if (!arr2 || !arr2.words || arr1.sigBytes !== arr2.sigBytes) {
            return false;
        }
        arr1.clamp();
        arr2.clamp();
        for(var i = 0; i < arr1.words.length; i++) {
            if (arr1.words[i] !== arr2.words[i]) {
                return false;
            }
        }
        return true;
    };

    /**
     * Retrieves the most significant bit of the WordArray as an Integer.
     *
     * @param {WordArray} arr
     *
     * @returns Integer
     */
    ext.msb = function(arr) {
        return arr.words[0] >>> 31;
    }
})(CryptoJS);<commit_msg>added some constant time fixes<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 artjomb
 */
(function(C){
    // put on ext property in CryptoJS
    var ext;
    if (!C.hasOwnProperty("ext")) {
        ext = C.ext = {};
    } else {
        ext = C.ext;
    }

    // Shortcuts
    var Base = C.lib.Base;
    var WordArray = C.lib.WordArray;
    var AES = C.algo.AES;

    // Constants
    ext.const_Zero = WordArray.create([0x00000000, 0x00000000, 0x00000000, 0x00000000]);
    ext.const_One = WordArray.create([0x00000000, 0x00000000, 0x00000000, 0x00000001]);
    ext.const_Rb = WordArray.create([0x00000000, 0x00000000, 0x00000000, 0x00000087]); // 00..0010000111
    ext.const_Rb_Shifted = WordArray.create([0x80000000, 0x00000000, 0x00000000, 0x00000043]); // 100..001000011
    ext.const_nonMSB = WordArray.create([0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF]); // 1^64 || 0^1 || 1^31 || 0^1 || 1^31

    /**
     * Looks into the object to see if it is a WordArray.
     *
     * @param obj Some object
     *
     * @returns {boolean}

     */
    ext.isWordArray = function(obj) {
        return obj && typeof obj.clamp === "function" && typeof obj.concat === "function" && typeof obj.words === "array";
    }

    /**
     * This padding is a 1 bit followed by as many 0 bits as needed to fill
     * up the block. This implementation doesn't work on bits directly,
     * but on bytes. Therefore the granularity is much bigger.
     */
    C.pad.OneZeroPadding = {
        pad: function (data, blocksize) {
            // Shortcut
            var blockSizeBytes = blocksize * 4;

            // Count padding bytes
            var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;

            // Create padding
            var paddingWords = [];
            for (var i = 0; i < nPaddingBytes; i += 4) {
                var paddingWord = 0x00000000;
                if (i === 0) {
                    paddingWord = 0x80000000;
                }
                paddingWords.push(paddingWord);
            }
            var padding = WordArray.create(paddingWords, nPaddingBytes);

            // Add padding
            data.concat(padding);
        },
        unpad: function () {
            // TODO: implement
        }
    };

    /**
     * No padding is applied. This is necessary for streaming cipher modes
     * like CTR.
     */
    C.pad.NoPadding = {
        pad: function () {},
        unpad: function () {}
    };

    /**
     * Returns the n leftmost bytes of the WordArray.
     *
     * @param {WordArray} wordArray WordArray to work on
     * @param {int} n Bytes to retrieve
     *
     * @returns new WordArray
     */
    ext.leftmostBytes = function(wordArray, n){
        var lmArray = wordArray.clone();
        lmArray.sigBytes = n;
        lmArray.clamp();
        return lmArray;
    };

    /**
     * Returns the n rightmost bytes of the WordArray.
     *
     * @param {WordArray} wordArray WordArray to work on
     * @param {int} n Bytes to retrieve (must be positive)
     *
     * @returns new WordArray
     */
    ext.rightmostBytes = function(wordArray, n){
        wordArray.clamp();
        var wordSize = 32;
        var rmArray = wordArray.clone();
        var bitsToShift = (rmArray.sigBytes - n) * 8;
        if (bitsToShift >= wordSize) {
            var popCount = Math.floor(bitsToShift/wordSize);
            bitsToShift -= popCount * wordSize;
            rmArray.words.splice(0, popCount);
            rmArray.sigBytes -= popCount * wordSize / 8;
        }
        if (bitsToShift > 0) {
            ext.bitshift(rmArray, bitsToShift);
            rmArray.sigBytes -= bitsToShift / 8;
        }
        return rmArray;
    };

    /**
     * Returns the n rightmost words of the WordArray. It assumes
     * that the current WordArray has at least n words.
     *
     * @param {WordArray} wordArray WordArray to work on
     * @param {int} n Words to retrieve (must be positive)
     *
     * @returns popped words as new WordArray
     */
    ext.popWords = function(wordArray, n){
        var left = ext.leftmostBytes(wordArray, n * 4);
        wordArray.words = wordArray.words.slice(n);
        wordArray.sigBytes -= n * 4;
        return left;
    };

    /**
     * Shifts the array to the left and returns the shifted dropped elements
     * as WordArray. The initial WordArray must contain at least n bytes and
     * they have to be significant.
     *
     * @param {WordArray} wordArray WordArray to work on (is modified)
     * @param {int} n Bytes to shift (must be positive, default 16)
     *
     * @returns new WordArray
     */
    ext.shiftBytes = function(wordArray, n){
        n = n || 16;
        var r = n % 4;
        n -= r;

        var shiftedArray = WordArray.create();
        for(var i = 0; i < n; i += 4) {
            shiftedArray.words.push(wordArray.words.shift());
            wordArray.sigBytes -= 4;
            shiftedArray.sigBytes += 4;
        }
        if (r > 0) {
            shiftedArray.words.push(wordArray.words[0]);
            shiftedArray.sigBytes += r;

            ext.bitshift(wordArray, r * 8);
            wordArray.sigBytes -= r;
        }
        return shiftedArray;
    };

    /**
     * XORs arr2 to the end of arr1 array. This doesn't modify the current
     * array aside from clamping.
     *
     * @param {WordArray} arr1 Bigger array
     * @param {WordArray} arr2 Smaller array to be XORed to the end
     *
     * @returns new WordArray
     */
    ext.xorendBytes = function(arr1, arr2){
        // TODO: more efficient
        return ext.leftmostBytes(arr1, arr1.sigBytes-arr2.sigBytes)
                .concat(ext.xor(ext.rightmostBytes(arr1, arr2.sigBytes), arr2));
    };

    /**
     * Doubling operation on a 128-bit value. This operation modifies the
     * passed array.
     *
     * @param {WordArray} wordArray WordArray to work on
     *
     * @returns passed WordArray
     */
    ext.dbl = function(wordArray){
        var carry = ext.msb(wordArray);
        ext.bitshift(wordArray, 1);
        ext.xor(wordArray, carry === 1 ? ext.const_Rb : ext.const_Zero);
        return wordArray;
    };

    /**
     * Inverse operation on a 128-bit value. This operation modifies the
     * passed array.
     *
     * @param {WordArray} wordArray WordArray to work on
     *
     * @returns passed WordArray
     */
    ext.inv = function(wordArray){
        var carry = wordArray.words[4] & 1;
        ext.bitshift(wordArray, -1);
        ext.xor(wordArray, carry === 1 ? ext.const_Rb_Shifted : ext.const_Zero);
        return wordArray;
    };

    /**
     * Check whether the word arrays are equal.
     *
     * @param {WordArray} arr1 Array 1
     * @param {WordArray} arr2 Array 2
     *
     * @returns boolean
     */
    ext.equals = function(arr1, arr2){
        if (!arr2 || !arr2.words || arr1.sigBytes !== arr2.sigBytes) {
            return false;
        }
        arr1.clamp();
        arr2.clamp();
        var equal = 0;
        for(var i = 0; i < arr1.words.length; i++) {
            equal |= arr1.words[i] ^ arr2.words[i];
        }
        return equal === 0;
    };

    /**
     * Retrieves the most significant bit of the WordArray as an Integer.
     *
     * @param {WordArray} arr
     *
     * @returns Integer
     */
    ext.msb = function(arr) {
        return arr.words[0] >>> 31;
    }
})(CryptoJS);<|endoftext|>


<commit_before>
export default {
  domain: 'http://v3.wufazhuce.com:8000',
  musicDomain: 'http://xiamirun.avosapps.com/run?song=http://www.xiami.com/song/',
  apiPath: '/api',
  imgUrl: 'http://image.wufazhuce.com/',
  apiVersion: 'v4.2.1',
  dev: true,
  baseId: 4060,
  baseTime: 1494255991848
};
<commit_msg>bump api version<commit_after>
export default {
  domain: 'http://v3.wufazhuce.com:8000',
  musicDomain: 'http://xiamirun.avosapps.com/run?song=http://www.xiami.com/song/',
  apiPath: '/api',
  imgUrl: 'http://image.wufazhuce.com/',
  apiVersion: 'v4.2.2',
  dev: true,
  baseId: 4060,
  baseTime: 1494255991848
};
<|endoftext|>


<commit_before>const readPkgUp = require('read-pkg-up')
const pkg = readPkgUp.sync().pkg
const program = require('commander')
const { info, error } = require('prettycli')
const debug = require('./debug')

/* Config from package.json */
const packageJSONconfig = pkg.bundlesize

/* Config from CLI */

program
  .option('-f, --files [files]', 'files to test against (dist/*.js)')
  .option('-s, --max-size [maxSize]', 'maximum size threshold (3Kb)')
  .option('--debug', 'run in debug mode')
  .parse(process.argv)

let cliConfig

if (program.files && program.maxSize) {
  cliConfig = [
    {
      path: program.files,
      maxSize: program.maxSize
    }
  ]
}

/* Send to readme if no configuration is provided */

if (!packageJSONconfig && !cliConfig) {
  error(
    `Config not found.

    You can read about the configuration options here:
    https://github.com/siddharthkp/bundlesize#configuration
  `,
    { silent: true }
  )
}

const config = cliConfig || packageJSONconfig

debug('cli config', cliConfig)
debug('package json config', packageJSONconfig)
debug('selected config', config)

module.exports = config
<commit_msg>only files is compulsory field<commit_after>const readPkgUp = require('read-pkg-up')
const pkg = readPkgUp.sync().pkg
const program = require('commander')
const { info, error } = require('prettycli')
const debug = require('./debug')

/* Config from package.json */
const packageJSONconfig = pkg.bundlesize

/* Config from CLI */

program
  .option('-f, --files [files]', 'files to test against (dist/*.js)')
  .option('-s, --max-size [maxSize]', 'maximum size threshold (3Kb)')
  .option('--debug', 'run in debug mode')
  .parse(process.argv)

let cliConfig

if (program.files) {
  cliConfig = [
    {
      path: program.files,
      maxSize: program.maxSize
    }
  ]
}

/* Send to readme if no configuration is provided */

if (!packageJSONconfig && !cliConfig) {
  error(
    `Config not found.

    You can read about the configuration options here:
    https://github.com/siddharthkp/bundlesize#configuration
  `,
    { silent: true }
  )
}

const config = cliConfig || packageJSONconfig

debug('cli config', cliConfig)
debug('package json config', packageJSONconfig)
debug('selected config', config)

module.exports = config
<|endoftext|>


<commit_before>//http://www.w3schools.com/js/js_cookies.asp
var Cookie = {

  prefix() {
    return  '__' + pixelFuncName + '_';
  },

  set(name, value, minutes, path = "/") {
    var expires = "";
    if (isset(minutes)) {
      var date = new Date();
      date.setTime(date.getTime()+(minutes*60*1000));
      expires = "; expires="+date.toGMTString();
    }
    document.cookie = this.prefix() + name + "=" + value + expires + "; path=" + path;
  },

  get(name) {
    var name = this.prefix() + name + "=";
    var ca = document.cookie.split(';');
    for (var i=0; i<ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1);
        if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
    }
    return;
  },

  delete(name) {
    this.set(name,"",-100);
  },

  exists(name) {
    return isset(this.get(name));
  },

  // set a cookie that expires in 10 minutes to throttle analytics requests from that page
  // throttle(name){
  //   this.set(name, 1, 10, window.location.pathname);
  // },

  setUtms() {
    var utmArray = ['utm_source','utm_medium','utm_term','utm_content','utm_campaign'];
    var exists = false;
    for (var i = 0, l = utmArray.length; i < l; i++) {
      if (isset(Url.getParameterByName(utmArray[i]))) {
        exists = true;
        break;
      }
    }
    if (exists) {
      var val, save = {};
      for (var i = 0, l = utmArray.length; i < l; i++) {
        val = Url.getParameterByName(utmArray[i]);
        if (isset(val)) {
          save[utmArray[i]] = val;
        }
      }
      this.set('utm', JSON.stringify(save));
    }
  },

  getUtm(name) {
    if (this.exists('utm')) {
      var utms = JSON.parse(this.get('utm'));
      return name in utms ? utms[name] : "";
    }
  }
}
<commit_msg>Update cookie.js (#62)<commit_after>//http://www.w3schools.com/js/js_cookies.asp
var Cookie = {

  prefix() {
    return  '__' + pixelFuncName + '_';
  },

  set(name, value, minutes, path = "/") {
    var expires = "";
    if (isset(minutes)) {
      var date = new Date();
      date.setTime(date.getTime()+(minutes*60*1000));
      expires = "; expires="+date.toGMTString();
    }
    document.cookie = this.prefix() + name + "=" + value + expires + "; path=" + path +"; SameSite=Lax";
  },

  get(name) {
    var name = this.prefix() + name + "=";
    var ca = document.cookie.split(';');
    for (var i=0; i<ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1);
        if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
    }
    return;
  },

  delete(name) {
    this.set(name,"",-100);
  },

  exists(name) {
    return isset(this.get(name));
  },

  // set a cookie that expires in 10 minutes to throttle analytics requests from that page
  // throttle(name){
  //   this.set(name, 1, 10, window.location.pathname);
  // },

  setUtms() {
    var utmArray = ['utm_source','utm_medium','utm_term','utm_content','utm_campaign'];
    var exists = false;
    for (var i = 0, l = utmArray.length; i < l; i++) {
      if (isset(Url.getParameterByName(utmArray[i]))) {
        exists = true;
        break;
      }
    }
    if (exists) {
      var val, save = {};
      for (var i = 0, l = utmArray.length; i < l; i++) {
        val = Url.getParameterByName(utmArray[i]);
        if (isset(val)) {
          save[utmArray[i]] = val;
        }
      }
      this.set('utm', JSON.stringify(save));
    }
  },

  getUtm(name) {
    if (this.exists('utm')) {
      var utms = JSON.parse(this.get('utm'));
      return name in utms ? utms[name] : "";
    }
  }
}
<|endoftext|>


<commit_before>const cookie = exports;
import * as utils from 'utils';

const queue = [];

function fireSyncs() {
  queue.forEach(obj => {
    utils.logMessage(`Invoking cookie sync for bidder: ${obj.bidder}`);
    if(obj.type === 'iframe') {
      utils.insertCookieSyncIframe(obj.url);
    } else {
      utils.insertPixel(obj.url);
    }
  });
}

/**
 * Add this bidder to the queue for sync
 * @param  {String} bidder bidder code
 * @param  {String} url    optional URL for invoking cookie sync if provided.
 */
cookie.queueSync = function ({bidder, url, type}) {
  queue.push({bidder, url, type});
};

/**
 * Fire cookie sync URLs previously queued
 * @param  {number} timeout time in ms to delay in sending
 */
cookie.syncCookies = function(timeout) {
  if(timeout) {
    setTimeout(fireSyncs, timeout);
  }
  else {
    fireSyncs();
  }
};

cookie.persist = function(url, msgHtml) {
  if(!utils.isSafariBrowser()){
    return;
  }
  linkOverride(url);
  displayFooter(msgHtml);
};

function linkOverride(url) {
   for (var i = 0; i < document.links.length; i++){
     var link = document.links[i];
     link.href = url + encodeURIComponent(link.href);
   }
 }

function displayFooter(msgHtml) {
  // https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#Example_3_Do_something_only_once
  if (document.cookie.replace(/(?:(?:^|.*;\s*)pbsCookiePersistFooter\s*\=\s*([^;]*).*$)|^.*$/, '$1') !== 'true') {
    document.body.appendChild(createFooter(msgHtml));
    document.cookie = 'pbsCookiePersistFooter=true; expires=Fri, 31 Dec 9999 23:59:59 GMT';
  }
}

function createFooter(msgHtml) {
  var footer = document.createElement('div');
  footer.style.background = '#ccc';
  footer.style.color = '#333';
  footer.style.boxShadow = '0 -1px 2px rgba(0, 0, 0, 0.2)';
  footer.style.fontFamily = 'sans-serif';
  footer.style.fontWeight = '300';
  footer.style.position = 'fixed';
  footer.style.bottom = '0px';
  footer.style.width = '100%';
  footer.style.padding = '1em';
  footer.style.zindex = '1000';
  footer.innerHTML = msgHtml;
  return footer;
}
<commit_msg>Improve footer styling (#1171)<commit_after>const cookie = exports;
import * as utils from 'utils';

const queue = [];

function fireSyncs() {
  queue.forEach(obj => {
    utils.logMessage(`Invoking cookie sync for bidder: ${obj.bidder}`);
    if(obj.type === 'iframe') {
      utils.insertCookieSyncIframe(obj.url);
    } else {
      utils.insertPixel(obj.url);
    }
  });
}

/**
 * Add this bidder to the queue for sync
 * @param  {String} bidder bidder code
 * @param  {String} url    optional URL for invoking cookie sync if provided.
 */
cookie.queueSync = function ({bidder, url, type}) {
  queue.push({bidder, url, type});
};

/**
 * Fire cookie sync URLs previously queued
 * @param  {number} timeout time in ms to delay in sending
 */
cookie.syncCookies = function(timeout) {
  if(timeout) {
    setTimeout(fireSyncs, timeout);
  }
  else {
    fireSyncs();
  }
};

cookie.persist = function(url, msgHtml) {
  if(!utils.isSafariBrowser()){
    return;
  }
  linkOverride(url);
  displayFooter(msgHtml);
};

function linkOverride(url) {
   for (var i = 0; i < document.links.length; i++){
     var link = document.links[i];
     link.href = url + encodeURIComponent(link.href);
   }
 }

function displayFooter(msgHtml) {
  // https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#Example_3_Do_something_only_once
  if (document.cookie.replace(/(?:(?:^|.*;\s*)pbsCookiePersistFooter\s*\=\s*([^;]*).*$)|^.*$/, '$1') !== 'true') {
    document.body.appendChild(createFooter(msgHtml));
    document.cookie = 'pbsCookiePersistFooter=true; expires=Fri, 31 Dec 9999 23:59:59 GMT';
  }
}

function createFooter(msgHtml) {
  const footer = document.createElement('div');
  footer.style.background = '#D3D3D3';
  footer.style.color = '#555';
  footer.style.boxShadow = '0 -1px 2px rgba(0, 0, 0, 0.2)';

  footer.style.fontFamily = 'sans-serif';
  footer.style.lineHeight = '1.5';

  footer.style.position = 'fixed';
  footer.style.bottom = '0';
  footer.style.left = '0';
  footer.style.right = '0';
  footer.style.width = '100%';

  footer.style.padding = '1em 0';
  footer.style.zindex = '1000';

  const footerText = document.createElement('p');
  footerText.style.margin = '0 2em';
  footerText.innerHTML = msgHtml;
  footer.appendChild(footerText);

  return footer;
}
<|endoftext|>


<commit_before>/*
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

var CordovaCliCreate = function () {

};

/**
 * provides logic for exposing cordova-lib create functionality to the command line
 * the create argument is implied from the call to this function, all other cl arguments should be passed in unmodified
 *
 * @args  -
 * @undashed
 */
CordovaCliCreate.prototype.run = function (args, undashed) {
    var cfg = {},
        customWww;

    // parseConfig will determine if there's a valid config JSON string
    cfg = parseConfig(undashed[4]);

    // customWww
    this.customWww = function (args) {

    }

    // create(dir, id, name, cfg)
    cordova.raw.create( undashed[1]  // dir to create the project in
                      , undashed[2]  // App id
                      , undashed[3]  // App name
                      , cfg
    ).done();
};

/**
 * parseConfig
 * generic parser, if it's valid json, returns the resulting object
 * if anything resolving to false is passed in, return an empty object
 * invalid json results in an error message and process exit with status code 2.
 *
 * jsondata - a json data string
 *
 */
CordovaCliCreate.prototype.parseConfig = function (jsondata) {
    if (!jsondata) return {};

    try {
        cfg = JSON.parse(jsondata);
    } catch (e) {
        console.error('Error while parsing json data\nError: '+ e +'\nData:' + jsondata);
        process.exit(2);
    }
};

CordovaCliCreate.prototype.customWww = function (args) {
    // handle custom www
    if (customWww = args['copy-from'] || args['link-to']) {

        if (customWww.indexOf(':') != -1) {
            throw new CordovaError(
            'Only local paths for custom www assets are supported.'
            );

        }

        if ( customWww.substr(0,1) === '~' ) {  // resolve tilde in a naive way.
            customWww = path.join(process.env.HOME,  customWww.substr(1));
        }

        customWww = path.resolve(customWww);
        var wwwCfg = { uri: customWww };
        if (args['link-to']) {
            wwwCfg.link = true;
        }

        cfg.lib = cfg.lib || {};
        cfg.lib.www = wwwCfg;
    }
};

module.exports = new CordovaCliCreate();
<commit_msg>CB-7950 CLI make CordovaCliCreate.prototype.run vaguely correct<commit_after>/*
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

var CordovaCliCreate = function () {

};

/**
 * provides logic for exposing cordova-lib create functionality to the command line
 * the create argument is implied from the call to this function, all other cl arguments should be passed in unmodified
 *
 * @args  -
 * @undashed
 */
CordovaCliCreate.prototype.run = function (args, undashed) {
    var cfg = {},
        customWww;

    // parseConfig will determine if there's a valid config JSON string
    cfg = this.parseConfig(undashed[4]);

    // create(dir, id, name, cfg)
    cordova.raw.create( undashed[1]  // dir to create the project in
                      , undashed[2]  // App id
                      , undashed[3]  // App name
                      , cfg
    ).done();
};

/**
 * parseConfig
 * generic parser, if it's valid json, returns the resulting object
 * if anything resolving to false is passed in, return an empty object
 * invalid json results in an error message and process exit with status code 2.
 *
 * jsondata - a json data string
 *
 */
CordovaCliCreate.prototype.parseConfig = function (jsondata) {
    if (!jsondata) return {};

    try {
        cfg = JSON.parse(jsondata);
    } catch (e) {
        console.error('Error while parsing json data\nError: '+ e +'\nData:' + jsondata);
        process.exit(2);
    }
};

CordovaCliCreate.prototype.customWww = function (args) {
    // handle custom www
    if (customWww = args['copy-from'] || args['link-to']) {

        if (customWww.indexOf(':') != -1) {
            throw new CordovaError(
            'Only local paths for custom www assets are supported.'
            );

        }

        if ( customWww.substr(0,1) === '~' ) {  // resolve tilde in a naive way.
            customWww = path.join(process.env.HOME,  customWww.substr(1));
        }

        customWww = path.resolve(customWww);
        var wwwCfg = { uri: customWww };
        if (args['link-to']) {
            wwwCfg.link = true;
        }

        cfg.lib = cfg.lib || {};
        cfg.lib.www = wwwCfg;
    }
};

module.exports = new CordovaCliCreate();
<|endoftext|>


<commit_before>'use strict';
class RowFormFileFieldController extends RowFormFieldController {
    getViewClass() {
        return RowFormFileFieldView;
    }
    onFileChange = async e => {
        // console.log('RowFormFileFieldController.onFileChange', e.target.files[0]);
        const dataUrl = await Helper.readFileAsDataURL(e.target.files[0]);
        // console.log('dataUrl:', dataUrl);
        this.onChange(dataUrl);
    }
}
<commit_msg>FileField change event with file<commit_after>'use strict';
class RowFormFileFieldController extends RowFormFieldController {
    getViewClass() {
        return RowFormFileFieldView;
    }
    onFileChange = async e => {
        // console.log('RowFormFileFieldController.onFileChange', e.target.files[0]);
        const file = e.target.files[0];
        const value = await Helper.readFileAsDataURL(file);
        // console.log('value:', value);
        this.emit('change', {file, value});
        this.onChange(value);
    }
}
<|endoftext|>