<commit_before>module.exports = `

Physical

        bp (°C)

                    Low
                    High
                    P (torr)
                    DOI

                        <input type='number' max=100000 data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='number' data-field='pressure'>

                        <input type='text' size=20 data-field='doi'>

        mp (°C)

                    Low
                    High
                    DOI

                        <input type='number' max=100000 data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='text' size=20 data-field='doi'>

        density

                    Low
                    High
                    Temp (°C)
                    DOI

                        <input type='number' max=100000 data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='number' data-field='temperature'>

                        <input type='text' size=20 data-field='doi'>

        nd

                    Low
                    High
                    Temp (°C)
                    DOI

                        <input type='number' max=100000 data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='number' data-field='temperature'>

                        <input type='text' size=20 data-field='doi'>

`;
<commit_msg>Add alpha and Rf<commit_after>// you may use the following page to test:
// http://www.cheminfo.org/?viewURL=https%3A%2F%2Fcouch.cheminfo.org%2Fcheminfo-public%2Fb9728349aa850f575f594496a2a38233%2Fview.json&loadversion=true&fillsearch=Twig+dynamic+form+experiments

module.exports = `

Physical

        bp (°C)

                    Low
                    High
                    P (torr)
                    DOI

                        <input type='number' max=100000 data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='number' data-field='pressure'>

                        <input type='text' size=20 data-field='doi'>

        mp (°C)

                    Low
                    High
                    DOI

                        <input type='number' max=100000 data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='text' size=20 data-field='doi'>

        density

                    Low
                    High
                    Temp (°C)
                    DOI

                        <input type='number' max=100000 data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='number' data-field='temperature'>

                        <input type='text' size=20 data-field='doi'>

        nd

                    Low
                    High
                    Temp (°C)
                    DOI

                        <input type='number' max=100000 data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='number' data-field='temperature'>

                        <input type='text' size=20 data-field='doi'>

        [α]

                    Low
                    High
                    Temp (°C)
                    𝝺 (nm)
                    [] (g/mL)
                    Solvent
                    DOI

                        <input type='number' data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='number' data-field='temperature'>

                        <input type='number' data-field='wavelength'>

                        <input type='number' data-field='concentration'>

                        <input type='text' size=10 data-field='solvent'>

                        <input type='text' size=20 data-field='doi'>

        Rf

                    Solvent
                    Plate
                    Low
                    High

                                Name
                                Parts

                                    <select data-field='name'>
                                        <option value=""></option>
                                        <option value="MeOH">MeOH</option>
                                        <option value="EtOH">EtOH</option>
                                        <option value="propanol">propanol</option>
                                        <option value="CH2Cl2">CH2Cl2</option>
                                        <option value="hexanes">hexanes</option>
                                        <option value="hexane">hexane</option>
                                        <option value="pentane">pentane</option>
                                        <option value="cyclohexane">cyclohexane</option>
                                        <option value="AcOEt">AcOEt</option>
                                    </select>

                                    <input type='number' data-field='part'>

                        <select data-field='name'>
                            <option value=""></option>
                            <option value="alumina">alumina</option>
                            <option value="silica">silica</option>
                        </select>

                        <input type='number' data-field='low'>

                        <input type='number' data-field='high'>

                        <input type='text' size=20 data-field='doi'>

`;
<|endoftext|>


<commit_before>// ***********************************************//
//                 models and stores
// ***********************************************//
import observe from '../mixins/observe';

require('akvo-flow/core-common');
require('akvo-flow/models/store_def-common');

FLOW.BaseModel = DS.Model.extend(observe({
  isSaving: 'anySaving',
  isDirty: 'anySaving',
}), {
  keyId: DS.attr('number'),
  savingStatus: null,

  // this method calls the checkSaving method on the savingMessageControl, which
  // checks if there are any records inflight. If yes, it sets a boolean,
  // so a saving message can be displayed. savingStatus is used to capture the
  // moment that nothing is being saved anymore, but in the previous event it was
  // so we can turn off the saving message.
  anySaving() {
    if (this.get('isSaving') || this.get('isDirty') || this.get('savingStatus')) {
      FLOW.savingMessageControl.checkSaving();
    }
    this.set('savingStatus', (this.get('isSaving') || this.get('isDirty')));
  },
});

FLOW.CaddisflyTestDefinition = Ember.Object.extend({
  name: null,
  multiParameter: null,
  sample: null,
  device: null,
  brand: null,
  model: null,
  uuid: null,
  results: [],
  reagents: [],
});

FLOW.CascadeResource = FLOW.BaseModel.extend({
  name: DS.attr('string', {
    defaultValue: '',
  }),
  version: DS.attr('number', {
    defaultValue: 1,
  }),
  numLevels: DS.attr('number', {
    defaultValue: 1,
  }),
  status: DS.attr('string', {
    defaultValue: 'NOT_PUBLISHED',
  }),
  levelNames: DS.attr('array', { defaultValue: [] }),
});

FLOW.CascadeNode = FLOW.BaseModel.extend({
  name: DS.attr('string', {
    defaultValue: '',
  }),
  code: DS.attr('string', {
    defaultValue: '',
  }),
  parentNodeId: DS.attr('number', {
    defaultValue: '',
  }),
  cascadeResourceId: DS.attr('number', {
    defaultValue: '',
  }),
});

FLOW.SurveyGroup = FLOW.BaseModel.extend({
  description: DS.attr('string', {
    defaultValue: '',
  }),
  name: DS.attr('string', {
    defaultValue: '',
  }),
  path: DS.attr('string', {
    defaultValue: null,
  }),
  ancestorIds: DS.attr('array', {
    defaultValue: [],
  }),
  createdDateTime: DS.attr('string', {
    defaultValue: '',
  }),
  monitoringGroup: DS.attr('boolean', {
    defaultValue: false,
  }),
  newLocaleSurveyId: DS.attr('number'),
  lastUpdateDateTime: DS.attr('string', {
    defaultValue: '',
  }),
  // the code field is used as name
  code: DS.attr('string', {
    defaultValue: '',
  }),

  parentId: DS.attr('number', {
    defaultValue: null,
  }),

  projectType: DS.attr('string', {
    defaultValue: 'PROJECT',
  }),

  privacyLevel: DS.attr('string', {
    defaultValue: 'PRIVATE',
  }),

  defaultLanguageCode: DS.attr('string', {
    defaultValue: 'en',
  }),

  published: DS.attr('boolean', {
    defaultValue: false,
  }),

  requireDataApproval: DS.attr('boolean', {
    defaultValue: false,
  }),

  dataApprovalGroupId: DS.attr('number', {
    defaultValue: null,
  }),

  surveyList: DS.attr('array', {
    defaultValue: null,
  }),

});

FLOW.Survey = FLOW.BaseModel.extend({

  defaultLanguageCode: DS.attr('string'),
  status: DS.attr('string'),
  sector: DS.attr('string'),
  code: DS.attr('string'),
  requireApproval: DS.attr('string'),
  version: DS.attr('string'),
  description: DS.attr('string'),
  name: DS.attr('string'),
  path: DS.attr('string'),
  ancestorIds: DS.attr('array'),
  pointType: DS.attr('string'),
  surveyGroupId: DS.attr('number'),
  createdDateTime: DS.attr('number'),
  lastUpdateDateTime: DS.attr('number'),

  // This attribute is used for the 'Copy Survey' functionality
  // Most of the times is `null`
  sourceId: DS.attr('number', {
    defaultValue: null,
  }),

  /* computed property that is used in the assignment edit page but never saved to backend.
  it should ideally appear as a view property. to be refactored */
  surveyGroupName: Ember.computed(function () {
    const surveyId = this.get('surveyGroupId');
    const survey = surveyId && FLOW.store.find(FLOW.SurveyGroup, surveyId);
    if (!Ember.empty(survey)) return survey.get('name');
    return '';
  }).property(''),

  allowEdit: Ember.computed(function () {
    return !this.get('isNew') && this.get('status') !== 'COPYING';
  }).property('status', 'isNew'),

});

FLOW.QuestionGroup = FLOW.BaseModel.extend({
  order: DS.attr('number'),
  name: DS.attr('string'),
  path: DS.attr('string'),
  code: DS.attr('string'),
  surveyId: DS.attr('number'),
  status: DS.attr('string'),
  sourceId: DS.attr('number', {
    defaultValue: null,
  }),
  repeatable: DS.attr('boolean', {
    defaultValue: false,
  }),
});

FLOW.Question = FLOW.BaseModel.extend({
  questionOptions: DS.hasMany('FLOW.QuestionOption'),

  allowDecimal: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowMultipleFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowOtherFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  localeNameFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  localeLocationFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowSign: DS.attr('boolean', {
    defaultValue: false,
  }),
  geoLocked: DS.attr('boolean', {
    defaultValue: false,
  }),
  requireDoubleEntry: DS.attr('boolean', {
    defaultValue: false,
  }),
  collapseable: DS.attr('boolean', {
    defaultValue: false,
  }),
  immutable: DS.attr('boolean', {
    defaultValue: false,
  }),
  mandatoryFlag: DS.attr('boolean', {
    defaultValue: true,
  }),
  dependentFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  dependentQuestionAnswer: DS.attr('string'),
  dependentQuestionId: DS.attr('number'),
  maxVal: DS.attr('number', {
    defaultValue: null,
  }),
  minVal: DS.attr('number', {
    defaultValue: null,
  }),
  order: DS.attr('number'),
  cascadeResourceId: DS.attr('number'),
  caddisflyResourceUuid: DS.attr('string'),
  path: DS.attr('string'),
  questionGroupId: DS.attr('number'),
  surveyId: DS.attr('number'),
  variableName: DS.attr('string'),
  metricId: DS.attr('number'),
  text: DS.attr('string'),
  tip: DS.attr('string'),
  type: DS.attr('string', {
    defaultValue: 'FREE_TEXT',
  }),
  // This attribute is used for the 'Copy Survey' functionality
  // Most of the times is `null`
  sourceId: DS.attr('number', {
    defaultValue: null,
  }),
  allowExternalSources: DS.attr('boolean', {
    defaultValue: false,
  }),
  // Geoshape question type options
  allowPoints: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowLine: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowPolygon: DS.attr('boolean', {
    defaultValue: false,
  }),
});

FLOW.QuestionOption = FLOW.BaseModel.extend({
  question: DS.belongsTo('FLOW.Question'),
  order: DS.attr('number'),
  questionId: DS.attr('number'),
  text: DS.attr('string'),
  code: DS.attr('string'),
});

FLOW.DeviceGroup = FLOW.BaseModel.extend({
  code: DS.attr('string', {
    defaultValue: '',
  }),
});

FLOW.Device = FLOW.BaseModel.extend({
  didLoad() {
    let combinedName;
    if (Ember.empty(this.get('deviceIdentifier'))) {
      combinedName = 'no identifer';
    } else {
      combinedName = this.get('deviceIdentifier');
    }
    this.set('combinedName', `${combinedName} ${this.get('phoneNumber')}`);
  },
  esn: DS.attr('string', {
    defaultValue: '',
  }),
  phoneNumber: DS.attr('string', {
    defaultValue: '',
  }),
  deviceIdentifier: DS.attr('string', {
    defaultValue: '',
  }),
  gallatinSoftwareManifest: DS.attr('string'),
  lastKnownLat: DS.attr('number', {
    defaultValue: 0,
  }),
  lastKnownLon: DS.attr('number', {
    defaultValue: 0,
  }),
  lastKnownAccuracy: DS.attr('number', {
    defaultValue: 0,
  }),
  lastPositionDate: DS.attr('number', {
    defaultValue: '',
  }),
  deviceGroup: DS.attr('string', {
    defaultValue: '',
  }),
  deviceGroupName: DS.attr('string', {
    defaultValue: '',
  }),
  isSelected: false,
  combinedName: null,
});

FLOW.SurveyAssignment = FLOW.BaseModel.extend({
  name: DS.attr('string'),
  startDate: DS.attr('number'),
  endDate: DS.attr('number'),
  devices: DS.attr('array'),
  surveys: DS.attr('array'),
  language: DS.attr('string'),
});

FLOW.SurveyedLocale = DS.Model.extend({
  description: DS.attr('string', {
    defaultValue: '',
  }),
  keyId: DS.attr('number'),
  latitude: DS.attr('number'),
  longitude: DS.attr('number'),
  displayName: DS.attr('string'),
  lastUpdateDateTime: DS.attr('number'),
  surveyGroupId: DS.attr('number'),
  identifier: DS.attr('string'),
  primaryKey: 'keyId',
});

FLOW.Placemark = FLOW.BaseModel.extend({
  latitude: DS.attr('number'),
  longitude: DS.attr('number'),
  count: DS.attr('number'),
  level: DS.attr('number'),
  surveyId: DS.attr('number'),
  collectionDate: DS.attr('number'),
});

FLOW.SurveyInstance = FLOW.BaseModel.extend({
  approvedFlag: DS.attr('string'),
  approximateLocationFlag: DS.attr('string'),
  surveyInstanceId: DS.attr('number'),
  surveyId: DS.attr('number'),
  surveyedLocaleId: DS.attr('number'),
  collectionDate: DS.attr('number'),
  surveyCode: DS.attr('string'),
  submitterName: DS.attr('string'),
  deviceIdentifier: DS.attr('string'),
  surveyedLocaleIdentifier: DS.attr('string'),
  surveyedLocaleDisplayName: DS.attr('string'),
});

FLOW.QuestionAnswer = FLOW.BaseModel.extend({
  value: DS.attr('string'),
  type: DS.attr('string'),
  oldValue: DS.attr('string'),
  surveyId: DS.attr('number'),
  collectionDate: DS.attr('number'),
  surveyInstanceId: DS.attr('number'),
  iteration: DS.attr('number'),
  questionID: DS.attr('string'), // TODO should be number?
  questionText: DS.attr('string'),
});

FLOW.ApprovalGroup = FLOW.BaseModel.extend({
  name: DS.attr('string'),
  ordered: DS.attr('boolean'),
});

FLOW.ApprovalStep = FLOW.BaseModel.extend({
  approvalGroupId: DS.attr('number'),
  order: DS.attr('number'),
  title: DS.attr('string'),
  approverUserList: DS.attr('array', {
    defaultValue: null,
  }),
});

FLOW.DataPointApproval = FLOW.BaseModel.extend({
  surveyedLocaleId: DS.attr('number'),

  approvalStepId: DS.attr('number'),

  approverUserName: DS.attr('string'),

  approvalDate: DS.attr('number'),

  status: DS.attr('string'),

  comment: DS.attr('string'),
});

FLOW.SurveyQuestionSummary = FLOW.BaseModel.extend({
  response: DS.attr('string'),
  count: DS.attr('number'),
  percentage: null,
  questionId: DS.attr('string'),
});

FLOW.User = FLOW.BaseModel.extend({
  userName: DS.attr('string'),
  emailAddress: DS.attr('string'),
  admin: DS.attr('boolean', {
    defaultValue: 0,
  }),
  superAdmin: DS.attr('boolean', {
    defaultValue: 0,
  }),
  permissionList: DS.attr('string')
});

FLOW.UserConfig = FLOW.BaseModel.extend({
  group: DS.attr('string'),
  name: DS.attr('string'),
  value: DS.attr('string'),
  userId: DS.attr('number'),
});

FLOW.Message = FLOW.BaseModel.extend({
  objectId: DS.attr('number'),
  lastUpdateDateTime: DS.attr('number'),
  userName: DS.attr('string'),
  objectTitle: DS.attr('string'),
  actionAbout: DS.attr('string'),
  shortMessage: DS.attr('string'),
});

FLOW.Action = FLOW.BaseModel.extend({});

FLOW.Translation = FLOW.BaseModel.extend(observe({
  'this.keyId': 'didCreateId',
}), {
  didUpdate() {
    FLOW.translationControl.putSingleTranslationInList(this.get('parentType'), this.get('parentId'), this.get('text'), this.get('keyId'), false);
  },

  // can't use this at the moment, as the didCreate is fired before the id is back from the
  // ajax call
  // didCreate: function(){
  //   console.log('didCreate',this.get('keyId'));
  // FLOW.translationControl.putSingleTranslationInList(
  //   this.get('parentType'),
  //   this.get('parentId'),
  //   this.get('text'),
  //   this.get('keyId'),
  //   false
  // );
  // },

  // temporary hack to fire the didCreate event after the keyId is known
  didCreateId() {
    if (!Ember.none(this.get('keyId')) && this.get('keyId') > 0) {
      FLOW.translationControl.putSingleTranslationInList(this.get('parentType'), this.get('parentId'), this.get('text'), this.get('keyId'), false);
    }
  },

  didDelete() {
    FLOW.translationControl.putSingleTranslationInList(this.get('parentType'), this.get('parentId'), null, null, true);
  },

  parentType: DS.attr('string'),
  parentId: DS.attr('string'),
  surveyId: DS.attr('string'),
  questionGroupId: DS.attr('string'),
  text: DS.attr('string'),
  langCode: DS.attr('string'),
});

FLOW.NotificationSubscription = FLOW.BaseModel.extend({
  notificationDestination: DS.attr('string'),
  notificationOption: DS.attr('string'),
  notificationMethod: DS.attr('string'),
  notificationType: DS.attr('string'),
  expiryDate: DS.attr('number'),
  entityId: DS.attr('number'),
});

FLOW.SubCountry = FLOW.BaseModel.extend({
  countryCode: DS.attr('string'),
  level: DS.attr('number'),
  name: DS.attr('string'),
  parentKey: DS.attr('number'),
  parentName: DS.attr('string'),
});

FLOW.Report = FLOW.BaseModel.extend({
  reportType: DS.attr('string'), // DATA_CLEANING/COMPREHENSIVE/...
  formId: DS.attr('number'),
  state: DS.attr('string'), // QUEUED/IN_PROGRESS/FINISHED_SUCCESS/FINISHED_ERROR
  startDate: DS.attr('string'),
  endDate: DS.attr('string'),
  message: DS.attr('string'),
  filename: DS.attr('string'),
  questionId: DS.attr('number'),
  createdDateTime: DS.attr('number'),
  lastUpdateDateTime: DS.attr('number'),
  lastCollectionOnly: DS.attr('boolean', {
    defaultValue: false,
  }),
});
<commit_msg>[#3203] Fix eslint issue<commit_after>// ***********************************************//
//                 models and stores
// ***********************************************//
import observe from '../mixins/observe';

require('akvo-flow/core-common');
require('akvo-flow/models/store_def-common');

FLOW.BaseModel = DS.Model.extend(observe({
  isSaving: 'anySaving',
  isDirty: 'anySaving',
}), {
  keyId: DS.attr('number'),
  savingStatus: null,

  // this method calls the checkSaving method on the savingMessageControl, which
  // checks if there are any records inflight. If yes, it sets a boolean,
  // so a saving message can be displayed. savingStatus is used to capture the
  // moment that nothing is being saved anymore, but in the previous event it was
  // so we can turn off the saving message.
  anySaving() {
    if (this.get('isSaving') || this.get('isDirty') || this.get('savingStatus')) {
      FLOW.savingMessageControl.checkSaving();
    }
    this.set('savingStatus', (this.get('isSaving') || this.get('isDirty')));
  },
});

FLOW.CaddisflyTestDefinition = Ember.Object.extend({
  name: null,
  multiParameter: null,
  sample: null,
  device: null,
  brand: null,
  model: null,
  uuid: null,
  results: [],
  reagents: [],
});

FLOW.CascadeResource = FLOW.BaseModel.extend({
  name: DS.attr('string', {
    defaultValue: '',
  }),
  version: DS.attr('number', {
    defaultValue: 1,
  }),
  numLevels: DS.attr('number', {
    defaultValue: 1,
  }),
  status: DS.attr('string', {
    defaultValue: 'NOT_PUBLISHED',
  }),
  levelNames: DS.attr('array', { defaultValue: [] }),
});

FLOW.CascadeNode = FLOW.BaseModel.extend({
  name: DS.attr('string', {
    defaultValue: '',
  }),
  code: DS.attr('string', {
    defaultValue: '',
  }),
  parentNodeId: DS.attr('number', {
    defaultValue: '',
  }),
  cascadeResourceId: DS.attr('number', {
    defaultValue: '',
  }),
});

FLOW.SurveyGroup = FLOW.BaseModel.extend({
  description: DS.attr('string', {
    defaultValue: '',
  }),
  name: DS.attr('string', {
    defaultValue: '',
  }),
  path: DS.attr('string', {
    defaultValue: null,
  }),
  ancestorIds: DS.attr('array', {
    defaultValue: [],
  }),
  createdDateTime: DS.attr('string', {
    defaultValue: '',
  }),
  monitoringGroup: DS.attr('boolean', {
    defaultValue: false,
  }),
  newLocaleSurveyId: DS.attr('number'),
  lastUpdateDateTime: DS.attr('string', {
    defaultValue: '',
  }),
  // the code field is used as name
  code: DS.attr('string', {
    defaultValue: '',
  }),

  parentId: DS.attr('number', {
    defaultValue: null,
  }),

  projectType: DS.attr('string', {
    defaultValue: 'PROJECT',
  }),

  privacyLevel: DS.attr('string', {
    defaultValue: 'PRIVATE',
  }),

  defaultLanguageCode: DS.attr('string', {
    defaultValue: 'en',
  }),

  published: DS.attr('boolean', {
    defaultValue: false,
  }),

  requireDataApproval: DS.attr('boolean', {
    defaultValue: false,
  }),

  dataApprovalGroupId: DS.attr('number', {
    defaultValue: null,
  }),

  surveyList: DS.attr('array', {
    defaultValue: null,
  }),

});

FLOW.Survey = FLOW.BaseModel.extend({

  defaultLanguageCode: DS.attr('string'),
  status: DS.attr('string'),
  sector: DS.attr('string'),
  code: DS.attr('string'),
  requireApproval: DS.attr('string'),
  version: DS.attr('string'),
  description: DS.attr('string'),
  name: DS.attr('string'),
  path: DS.attr('string'),
  ancestorIds: DS.attr('array'),
  pointType: DS.attr('string'),
  surveyGroupId: DS.attr('number'),
  createdDateTime: DS.attr('number'),
  lastUpdateDateTime: DS.attr('number'),

  // This attribute is used for the 'Copy Survey' functionality
  // Most of the times is `null`
  sourceId: DS.attr('number', {
    defaultValue: null,
  }),

  /* computed property that is used in the assignment edit page but never saved to backend.
  it should ideally appear as a view property. to be refactored */
  surveyGroupName: Ember.computed(function () {
    const surveyId = this.get('surveyGroupId');
    const survey = surveyId && FLOW.store.find(FLOW.SurveyGroup, surveyId);
    if (!Ember.empty(survey)) return survey.get('name');
    return '';
  }).property(''),

  allowEdit: Ember.computed(function () {
    return !this.get('isNew') && this.get('status') !== 'COPYING';
  }).property('status', 'isNew'),

});

FLOW.QuestionGroup = FLOW.BaseModel.extend({
  order: DS.attr('number'),
  name: DS.attr('string'),
  path: DS.attr('string'),
  code: DS.attr('string'),
  surveyId: DS.attr('number'),
  status: DS.attr('string'),
  sourceId: DS.attr('number', {
    defaultValue: null,
  }),
  repeatable: DS.attr('boolean', {
    defaultValue: false,
  }),
});

FLOW.Question = FLOW.BaseModel.extend({
  questionOptions: DS.hasMany('FLOW.QuestionOption'),

  allowDecimal: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowMultipleFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowOtherFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  localeNameFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  localeLocationFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowSign: DS.attr('boolean', {
    defaultValue: false,
  }),
  geoLocked: DS.attr('boolean', {
    defaultValue: false,
  }),
  requireDoubleEntry: DS.attr('boolean', {
    defaultValue: false,
  }),
  collapseable: DS.attr('boolean', {
    defaultValue: false,
  }),
  immutable: DS.attr('boolean', {
    defaultValue: false,
  }),
  mandatoryFlag: DS.attr('boolean', {
    defaultValue: true,
  }),
  dependentFlag: DS.attr('boolean', {
    defaultValue: false,
  }),
  dependentQuestionAnswer: DS.attr('string'),
  dependentQuestionId: DS.attr('number'),
  maxVal: DS.attr('number', {
    defaultValue: null,
  }),
  minVal: DS.attr('number', {
    defaultValue: null,
  }),
  order: DS.attr('number'),
  cascadeResourceId: DS.attr('number'),
  caddisflyResourceUuid: DS.attr('string'),
  path: DS.attr('string'),
  questionGroupId: DS.attr('number'),
  surveyId: DS.attr('number'),
  variableName: DS.attr('string'),
  metricId: DS.attr('number'),
  text: DS.attr('string'),
  tip: DS.attr('string'),
  type: DS.attr('string', {
    defaultValue: 'FREE_TEXT',
  }),
  // This attribute is used for the 'Copy Survey' functionality
  // Most of the times is `null`
  sourceId: DS.attr('number', {
    defaultValue: null,
  }),
  allowExternalSources: DS.attr('boolean', {
    defaultValue: false,
  }),
  // Geoshape question type options
  allowPoints: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowLine: DS.attr('boolean', {
    defaultValue: false,
  }),
  allowPolygon: DS.attr('boolean', {
    defaultValue: false,
  }),
});

FLOW.QuestionOption = FLOW.BaseModel.extend({
  question: DS.belongsTo('FLOW.Question'),
  order: DS.attr('number'),
  questionId: DS.attr('number'),
  text: DS.attr('string'),
  code: DS.attr('string'),
});

FLOW.DeviceGroup = FLOW.BaseModel.extend({
  code: DS.attr('string', {
    defaultValue: '',
  }),
});

FLOW.Device = FLOW.BaseModel.extend({
  didLoad() {
    let combinedName;
    if (Ember.empty(this.get('deviceIdentifier'))) {
      combinedName = 'no identifer';
    } else {
      combinedName = this.get('deviceIdentifier');
    }
    this.set('combinedName', `${combinedName} ${this.get('phoneNumber')}`);
  },
  esn: DS.attr('string', {
    defaultValue: '',
  }),
  phoneNumber: DS.attr('string', {
    defaultValue: '',
  }),
  deviceIdentifier: DS.attr('string', {
    defaultValue: '',
  }),
  gallatinSoftwareManifest: DS.attr('string'),
  lastKnownLat: DS.attr('number', {
    defaultValue: 0,
  }),
  lastKnownLon: DS.attr('number', {
    defaultValue: 0,
  }),
  lastKnownAccuracy: DS.attr('number', {
    defaultValue: 0,
  }),
  lastPositionDate: DS.attr('number', {
    defaultValue: '',
  }),
  deviceGroup: DS.attr('string', {
    defaultValue: '',
  }),
  deviceGroupName: DS.attr('string', {
    defaultValue: '',
  }),
  isSelected: false,
  combinedName: null,
});

FLOW.SurveyAssignment = FLOW.BaseModel.extend({
  name: DS.attr('string'),
  startDate: DS.attr('number'),
  endDate: DS.attr('number'),
  devices: DS.attr('array'),
  surveys: DS.attr('array'),
  language: DS.attr('string'),
});

FLOW.SurveyedLocale = DS.Model.extend({
  description: DS.attr('string', {
    defaultValue: '',
  }),
  keyId: DS.attr('number'),
  latitude: DS.attr('number'),
  longitude: DS.attr('number'),
  displayName: DS.attr('string'),
  lastUpdateDateTime: DS.attr('number'),
  surveyGroupId: DS.attr('number'),
  identifier: DS.attr('string'),
  primaryKey: 'keyId',
});

FLOW.Placemark = FLOW.BaseModel.extend({
  latitude: DS.attr('number'),
  longitude: DS.attr('number'),
  count: DS.attr('number'),
  level: DS.attr('number'),
  surveyId: DS.attr('number'),
  collectionDate: DS.attr('number'),
});

FLOW.SurveyInstance = FLOW.BaseModel.extend({
  approvedFlag: DS.attr('string'),
  approximateLocationFlag: DS.attr('string'),
  surveyInstanceId: DS.attr('number'),
  surveyId: DS.attr('number'),
  surveyedLocaleId: DS.attr('number'),
  collectionDate: DS.attr('number'),
  surveyCode: DS.attr('string'),
  submitterName: DS.attr('string'),
  deviceIdentifier: DS.attr('string'),
  surveyedLocaleIdentifier: DS.attr('string'),
  surveyedLocaleDisplayName: DS.attr('string'),
});

FLOW.QuestionAnswer = FLOW.BaseModel.extend({
  value: DS.attr('string'),
  type: DS.attr('string'),
  oldValue: DS.attr('string'),
  surveyId: DS.attr('number'),
  collectionDate: DS.attr('number'),
  surveyInstanceId: DS.attr('number'),
  iteration: DS.attr('number'),
  questionID: DS.attr('string'), // TODO should be number?
  questionText: DS.attr('string'),
});

FLOW.ApprovalGroup = FLOW.BaseModel.extend({
  name: DS.attr('string'),
  ordered: DS.attr('boolean'),
});

FLOW.ApprovalStep = FLOW.BaseModel.extend({
  approvalGroupId: DS.attr('number'),
  order: DS.attr('number'),
  title: DS.attr('string'),
  approverUserList: DS.attr('array', {
    defaultValue: null,
  }),
});

FLOW.DataPointApproval = FLOW.BaseModel.extend({
  surveyedLocaleId: DS.attr('number'),

  approvalStepId: DS.attr('number'),

  approverUserName: DS.attr('string'),

  approvalDate: DS.attr('number'),

  status: DS.attr('string'),

  comment: DS.attr('string'),
});

FLOW.SurveyQuestionSummary = FLOW.BaseModel.extend({
  response: DS.attr('string'),
  count: DS.attr('number'),
  percentage: null,
  questionId: DS.attr('string'),
});

FLOW.User = FLOW.BaseModel.extend({
  userName: DS.attr('string'),
  emailAddress: DS.attr('string'),
  admin: DS.attr('boolean', {
    defaultValue: 0,
  }),
  superAdmin: DS.attr('boolean', {
    defaultValue: 0,
  }),
  permissionList: DS.attr('string'),
});

FLOW.UserConfig = FLOW.BaseModel.extend({
  group: DS.attr('string'),
  name: DS.attr('string'),
  value: DS.attr('string'),
  userId: DS.attr('number'),
});

FLOW.Message = FLOW.BaseModel.extend({
  objectId: DS.attr('number'),
  lastUpdateDateTime: DS.attr('number'),
  userName: DS.attr('string'),
  objectTitle: DS.attr('string'),
  actionAbout: DS.attr('string'),
  shortMessage: DS.attr('string'),
});

FLOW.Action = FLOW.BaseModel.extend({});

FLOW.Translation = FLOW.BaseModel.extend(observe({
  'this.keyId': 'didCreateId',
}), {
  didUpdate() {
    FLOW.translationControl.putSingleTranslationInList(this.get('parentType'), this.get('parentId'), this.get('text'), this.get('keyId'), false);
  },

  // can't use this at the moment, as the didCreate is fired before the id is back from the
  // ajax call
  // didCreate: function(){
  //   console.log('didCreate',this.get('keyId'));
  // FLOW.translationControl.putSingleTranslationInList(
  //   this.get('parentType'),
  //   this.get('parentId'),
  //   this.get('text'),
  //   this.get('keyId'),
  //   false
  // );
  // },

  // temporary hack to fire the didCreate event after the keyId is known
  didCreateId() {
    if (!Ember.none(this.get('keyId')) && this.get('keyId') > 0) {
      FLOW.translationControl.putSingleTranslationInList(this.get('parentType'), this.get('parentId'), this.get('text'), this.get('keyId'), false);
    }
  },

  didDelete() {
    FLOW.translationControl.putSingleTranslationInList(this.get('parentType'), this.get('parentId'), null, null, true);
  },

  parentType: DS.attr('string'),
  parentId: DS.attr('string'),
  surveyId: DS.attr('string'),
  questionGroupId: DS.attr('string'),
  text: DS.attr('string'),
  langCode: DS.attr('string'),
});

FLOW.NotificationSubscription = FLOW.BaseModel.extend({
  notificationDestination: DS.attr('string'),
  notificationOption: DS.attr('string'),
  notificationMethod: DS.attr('string'),
  notificationType: DS.attr('string'),
  expiryDate: DS.attr('number'),
  entityId: DS.attr('number'),
});

FLOW.SubCountry = FLOW.BaseModel.extend({
  countryCode: DS.attr('string'),
  level: DS.attr('number'),
  name: DS.attr('string'),
  parentKey: DS.attr('number'),
  parentName: DS.attr('string'),
});

FLOW.Report = FLOW.BaseModel.extend({
  reportType: DS.attr('string'), // DATA_CLEANING/COMPREHENSIVE/...
  formId: DS.attr('number'),
  state: DS.attr('string'), // QUEUED/IN_PROGRESS/FINISHED_SUCCESS/FINISHED_ERROR
  startDate: DS.attr('string'),
  endDate: DS.attr('string'),
  message: DS.attr('string'),
  filename: DS.attr('string'),
  questionId: DS.attr('number'),
  createdDateTime: DS.attr('number'),
  lastUpdateDateTime: DS.attr('number'),
  lastCollectionOnly: DS.attr('boolean', {
    defaultValue: false,
  }),
});
<|endoftext|>


<commit_before>/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

// This is mock data used while the front-end is not communicating with the macros
// The data structure is not definitive, and may change to match the final specs

define({

  query: {
    properties: ["doc_title", "age", "job", "other"],

    source: {
      id: "...",
      url: "...",
    },

    hiddenFilters: {},

    filters: {},

    sort: [ {properties: "age", descending: true} ],

    offset: 0,
    limit: 10,

  },

  meta: {

    layouts: ["tableLayout"],
    defaultLayout: "tableLayout",

    propertyDescriptors: [
      {
        id: "doc_title",
        name: "Name",
        type: "Text",
      },
      {
        id: "age",
        name: "Age",
        type: "Number",
      },
      {
        id: "job",
        name: "Job",
        type: "Text",
      },
      {
        id: "country",
        name: "Country",
        type: "List",
      },
      {
        id: "other",
        name: "Autre truc",
        type: "Text",
      },
    ],

  },

  data: {

    count: 5,

    entries: [
      {
        doc_url: "#link1",
        doc_name: "Name1",
        doc_date: "2020/03/27 13:23",
        doc_title: "Title 1",
        doc_author: "Author 1",
        doc_creationDate: "2020/03/27 13:21",
        doc_creator: "Creator 1",
        age: 48,
        job: "Job 1",
        country: "France",
        other: "lorem ipsum",
      },
      {
        doc_url: "#link2",
        doc_name: "Name2",
        doc_date: "2020/04/22 14:07",
        doc_title: "Title 2",
        doc_author: "Author 2",
        doc_creationDate: "2020/04/22 14:06",
        doc_creator: "Creator 2",
        age: 24,
        job: "Job 2",
        country: "France",
        other: "dorol sit amet",
      },
      {
        doc_url: "#link3",
        doc_name: "Name3",
        doc_date: "2020/03/27 14:34",
        doc_title: "Title 3",
        doc_author: "Author 3",
        doc_creationDate: "2020/03/27 14:34",
        doc_creator: "Creator 3",
        age: 12,
        job: "Job 3",
        country: "Romania",
        other: "consequtir",
      },
      {
        doc_url: "#link4",
        doc_name: "Name4",
        doc_date: "2020/03/27 14:34",
        doc_title: "Title 4",
        doc_author: "Author 4",
        doc_creationDate: "2020/03/27 14:34",
        doc_creator: "Creator 4",
        age: 52,
        country: "Romania",
      },
    ],

  },

});<commit_msg>XWIKI-17387 Wrap mockData properties with quotes to please yuicompresssor linter<commit_after>/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

// This is mock data used while the front-end is not communicating with the macros
// The data structure is not definitive, and may change to match the final specs

define({

  query: {
    properties: ["doc_title", "age", "job", "other"],

    source: {
      id: "...",
      url: "...",
    },

    hiddenFilters: {},

    filters: {},

    sort: [ {properties: "age", descending: true} ],

    offset: 0,
    limit: 10,

  },

  meta: {

    layouts: ["tableLayout"],
    defaultLayout: "tableLayout",

    propertyDescriptors: [
      {
        id: "doc_title",
        name: "Name",
        type: "Text",
      },
      {
        id: "age",
        name: "Age",
        type: "Number",
      },
      {
        id: "job",
        name: "Job",
        type: "Text",
      },
      {
        id: "country",
        name: "Country",
        type: "List",
      },
      {
        id: "other",
        name: "Autre truc",
        type: "Text",
      },
    ],

  },

  data: {

    count: 5,

    entries: [
      {
        "doc_url": "#link1",
        "doc_name": "Name1",
        "doc_date": "2020/03/27 13:23",
        "doc_title": "Title 1",
        "doc_author": "Author 1",
        "doc_creationDate": "2020/03/27 13:21",
        "doc_creator": "Creator 1",
        "age": 48,
        "job": "Job 1",
        "country": "France",
        "other": "lorem ipsum",
      },
      {
        "doc_url": "#link2",
        "doc_name": "Name2",
        "doc_date": "2020/04/22 14:07",
        "doc_title": "Title 2",
        "doc_author": "Author 2",
        "doc_creationDate": "2020/04/22 14:06",
        "doc_creator": "Creator 2",
        "age": 24,
        "job": "Job 2",
        "country": "France",
        "other": "dorol sit amet",
      },
      {
        "doc_url": "#link3",
        "doc_name": "Name3",
        "doc_date": "2020/03/27 14:34",
        "doc_title": "Title 3",
        "doc_author": "Author 3",
        "doc_creationDate": "2020/03/27 14:34",
        "doc_creator": "Creator 3",
        "age": 12,
        "job": "Job 3",
        "country": "Romania",
        "other": "consequtir",
      },
      {
        "doc_url": "#link4",
        "doc_name": "Name4",
        "doc_date": "2020/03/27 14:34",
        "doc_title": "Title 4",
        "doc_author": "Author 4",
        "doc_creationDate": "2020/03/27 14:34",
        "doc_creator": "Creator 4",
        "age": 52,
        "country": "Romania",
      },
    ],

  },

});<|endoftext|>


<commit_before>import extendTheme from "../../utils/extendTheme";
import mapKeys from "../../utils/mapKeys";
import system from "./system";
import baseTheme from "../../baseTheme";
import mediumDensityTheme from "../../densities/mediumDensity";
import accordion from "./components/accordion";
import avatarBundle from "./components/avatarBundle";
import badge from "./components/badge";
import banner from "./components/banner";
import button from "./components/button";
import checkbox from "./components/checkbox";
import iconButton from "./components/iconButton";
import illustration from "./components/illustration";
import input from "./components/input";
import label from "./components/label";
import progressBar from "./components/progressBar";
import progressRing from "./components/progressRing";
import sideNav from "./components/sideNav";
import skeletonItem from "./components/skeletonItem";
import slider from "./components/slider";
import stepIndicator from "./components/stepIndicator";
import tabs from "./components/tabs";
import tag from "./components/tag";
import textLink from "./components/textLink";
import thumbnail from "./components/thumbnail";
import tile from "./components/tile";
import token from "./components/token";
import tooltip from "./components/tooltip";
import topNav from "./components/topNav";
import treeView from "./components/treeView";
console.log(tile);
const darkBlueThemeConfig = extendTheme(baseTheme.unresolvedRoles, {
  ...mediumDensityTheme.unresolvedRoles,
  ...mapKeys(system.colorScheme, (key) => `colorScheme.${key}`),
  ...accordion,
  ...avatarBundle,
  ...badge,
  ...banner,
  ...button,
  ...checkbox,
  ...iconButton,
  ...illustration,
  ...input,
  ...label,
  ...progressBar,
  ...progressRing,
  ...sideNav,
  ...skeletonItem,
  ...slider,
  ...stepIndicator,
  ...tabs,
  ...tag,
  ...textLink,
  ...thumbnail,
  ...tile,
  ...token,
  ...tooltip,
  ...topNav,
  ...treeView,
});

export default darkBlueThemeConfig;
<commit_msg>refactor: removed console log from dark blue unresolved roles<commit_after>import extendTheme from "../../utils/extendTheme";
import mapKeys from "../../utils/mapKeys";
import system from "./system";
import baseTheme from "../../baseTheme";
import mediumDensityTheme from "../../densities/mediumDensity";
import accordion from "./components/accordion";
import avatarBundle from "./components/avatarBundle";
import badge from "./components/badge";
import banner from "./components/banner";
import button from "./components/button";
import checkbox from "./components/checkbox";
import iconButton from "./components/iconButton";
import illustration from "./components/illustration";
import input from "./components/input";
import label from "./components/label";
import progressBar from "./components/progressBar";
import progressRing from "./components/progressRing";
import sideNav from "./components/sideNav";
import skeletonItem from "./components/skeletonItem";
import slider from "./components/slider";
import stepIndicator from "./components/stepIndicator";
import tabs from "./components/tabs";
import tag from "./components/tag";
import textLink from "./components/textLink";
import thumbnail from "./components/thumbnail";
import tile from "./components/tile";
import token from "./components/token";
import tooltip from "./components/tooltip";
import topNav from "./components/topNav";
import treeView from "./components/treeView";

const darkBlueThemeConfig = extendTheme(baseTheme.unresolvedRoles, {
  ...mediumDensityTheme.unresolvedRoles,
  ...mapKeys(system.colorScheme, (key) => `colorScheme.${key}`),
  ...accordion,
  ...avatarBundle,
  ...badge,
  ...banner,
  ...button,
  ...checkbox,
  ...iconButton,
  ...illustration,
  ...input,
  ...label,
  ...progressBar,
  ...progressRing,
  ...sideNav,
  ...skeletonItem,
  ...slider,
  ...stepIndicator,
  ...tabs,
  ...tag,
  ...textLink,
  ...thumbnail,
  ...tile,
  ...token,
  ...tooltip,
  ...topNav,
  ...treeView,
});

export default darkBlueThemeConfig;
<|endoftext|>


<commit_before>// 声明插件以及配置文件的依赖
var plugins     = require('gulp-load-plugins')({
                    rename: {
                      'gulp-file-include': 'include',
                      'gulp-merge-link': 'merge'
                    }
                  }),
    packageInfo = require('../package.json'),
    lib         = require('./lib.js'),
    config;

// 读取项目配置表
try {
  config = require('../../config.js');
} catch (_event) {
  try {
    config = require('../../config.json');
    var result
  } catch (_event) {
    plugins.util.log(plugins.util.colors.red('QMUI Config: ') + '找不到项目配置表，请按照 http://qmuiteam.com/web/index.html 的说明进行项目配置');

  }
}

// 创建 common 对象
var common = {};

common.plugins = plugins;
common.config = config;
common.packageInfo = packageInfo;
common.lib = lib;

module.exports = common;
<commit_msg>废弃多余的代码<commit_after>// 声明插件以及配置文件的依赖
var plugins     = require('gulp-load-plugins')({
                    rename: {
                      'gulp-file-include': 'include',
                      'gulp-merge-link': 'merge'
                    }
                  }),
    packageInfo = require('../package.json'),
    lib         = require('./lib.js'),
    config;

// 读取项目配置表
try {
  config = require('../../config.js');
} catch (_event) {
  try {
    config = require('../../config.json');
  } catch (_event) {
    plugins.util.log(plugins.util.colors.red('QMUI Config: ') + '找不到项目配置表，请按照 http://qmuiteam.com/web/index.html 的说明进行项目配置');

  }
}

// 创建 common 对象
var common = {};

common.plugins = plugins;
common.config = config;
common.packageInfo = packageInfo;
common.lib = lib;

module.exports = common;
<|endoftext|>


<commit_before>// Tip: If you have access to soundcard settings, adjust input gain so that
// microphone input averages between 50% and 75% metering on soundcard.
// Good rule of thumb for analyser is that -100dB is a very quiet room and 0 is
// a very loud input. Under this setup most inputs should avg between -40 and
// -5 dB, but it all depends on the environment, input gain,
// and analyser.minDecibels.

var helpers = require('./audioHelpers.js');
var makePitchAnalyser = require('./makePitchAnalyser.js');

var h1 = $('h1');
var contextClass = (window.AudioContext ||
  window.webkitAudioContext ||
  window.mozAudioContext ||
  window.oAudioContext ||
  window.msAudioContext);
if (contextClass) {
  var audioContext = new contextClass();
} else {
  h1.text("web audio is not enabled, sorry.");
}

var state = {
  serverReady: false,
  inputEnabled: false,
  emitting: false,
};
var server = io.connect('/audio');
var microphone;
var hiPass = helpers.makeFilter(audioContext,"HIGHPASS",80);
var loPass = helpers.makeFilter(audioContext,"LOWPASS",1200);
var filters = helpers.nodeChain();
filters.add(hiPass,loPass);

server.on("welcome",function(data){
  if (data.audio) {
    state.serverReady = true;
  }
});

server.on("toggleSound",function(data) {
  state.serverReady = data.sound;
  if (!state.emitting && state.inputEnabled && state.serverReady) {
    startEmitting();
  } else if (state.emitting && !state.serverReady) {
    stopEmitting();
  }
});

server.on("reset", function() {
  state.serverReady = false;
  if (state.emitting) {
    stopEmitting();
  }
});

var streamLoaded = function(stream) {
  h1.text("Audio input enabled. Waiting for command from server.");
  state.inputEnabled = true;
  microphone = audioContext.createMediaStreamSource(stream);
  microphone.connect(filters.first);
  if (state.serverReady) { startEmitting(); }
};

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
navigator.getUserMedia( {audio:true}, streamLoaded);

var startEmitting = function() {
  h1.text("Calibrating...");
  pitchAnalyser = makePitchAnalyser(audioContext,filters);
  pitchAnalyser.calibrate(function(){
    h1.text('Emitting audio stream.');
    state.emitting = true;
    pitchAnalyser.start(60,function(data){
      if (data.volume > pitchAnalyser.threshold) {
        server.emit("audio",data);
      }
    });
  });
};

var stopEmitting = function() {
  h1.text("TRANSMISSION ENDED");
  state.emitting = false;
  pitchAnalyser.end();
};
<commit_msg>Bugfix -- navigator.getUserMedia now requires a third argument (a Chrome error is thrown otherwise)<commit_after>// Tip: If you have access to soundcard settings, adjust input gain so that
// microphone input averages between 50% and 75% metering on soundcard.
// Good rule of thumb for analyser is that -100dB is a very quiet room and 0 is
// a very loud input. Under this setup most inputs should avg between -40 and
// -5 dB, but it all depends on the environment, input gain,
// and analyser.minDecibels.

var helpers = require('./audioHelpers.js');
var makePitchAnalyser = require('./makePitchAnalyser.js');

var h1 = $('h1');
var contextClass = (window.AudioContext ||
  window.webkitAudioContext ||
  window.mozAudioContext ||
  window.oAudioContext ||
  window.msAudioContext);
if (contextClass) {
  var audioContext = new contextClass();
} else {
  h1.text("web audio is not enabled, sorry.");
}

var state = {
  serverReady: false,
  inputEnabled: false,
  emitting: false,
};
var server = io.connect('/audio');
var microphone;
var hiPass = helpers.makeFilter(audioContext,"HIGHPASS",80);
var loPass = helpers.makeFilter(audioContext,"LOWPASS",1200);
var filters = helpers.nodeChain();
filters.add(hiPass,loPass);

server.on("welcome",function(data){
  console.log(data);
  if (data.audio) {
    state.serverReady = true;
  }
});

server.on("toggleSound",function(data) {
  state.serverReady = data.sound;
  if (!state.emitting && state.inputEnabled && state.serverReady) {
    startEmitting();
  } else if (state.emitting && !state.serverReady) {
    stopEmitting();
  }
});

server.on("reset", function() {
  state.serverReady = false;
  if (state.emitting) {
    stopEmitting();
  }
});

var streamLoaded = function(stream) {
  h1.text("Audio input enabled. Waiting for command from server.");
  state.inputEnabled = true;
  microphone = audioContext.createMediaStreamSource(stream);
  microphone.connect(filters.first);
  if (state.serverReady) { startEmitting(); }
};

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
navigator.getUserMedia( {audio:true}, streamLoaded, function(data){console.log(data)});

var startEmitting = function() {
  h1.text("Calibrating...");
  pitchAnalyser = makePitchAnalyser(audioContext,filters);
  pitchAnalyser.calibrate(function(){
    h1.text('Emitting audio stream.');
    state.emitting = true;
    pitchAnalyser.start(60,function(data){
      if (data.volume > pitchAnalyser.threshold) {
        server.emit("audio",data);
      }
    });
  });
};

var stopEmitting = function() {
  h1.text("TRANSMISSION ENDED");
  state.emitting = false;
  pitchAnalyser.end();
};
<|endoftext|>


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

  var _ = require('underscore');

  module.exports = {
    getSearchPromptTemplate: function () {
      return `<i>(enter a search term)</i>`;
    },
    // Returns search result template for the track.
    getTrackSearchResultTemplate: function (track) {
      var result = '';

      if (!track || !track.name) {
        return result;
      }

      result += `<div><b>${track.name}</b></div>`;

      if (track.artists && track.artists.length && track.artists[0].name) {
        result += `<div>${track.artists[0].name}</div>`;
      } else {
        result += `<div>(unknown artist)</div>`;
      }

      return result;
    },
    getNoSearchResultsTemplate: function () {
      return `<i>(no results)</i>`;
    },
    // Returns full track link template
    getRobustTrackLinkTemplate: function (track) {
      var result = '',
          image,
          artistName;

      if (!track || !track.id) {
        return result;
      }

      result += `<div style="display:inline-block;padding:15px;font-family:helvetica,sans-serif;border-radius:3px;background-color:#000;">`;
      result += `<a href="https://embed.spotify.com/?uri=spotify:track:${track.id}" ` +
        `target="_blank" style="text-decoration:none;color:#fff;">`;
      result += `<div style="display:flex;align-items:center;">`;

      if (track.album && track.album.images && track.album.images.length) {
        image = _.chain(track.album.images)
          .sortBy('width')
          .first()
          .value();

        if (!!image) {
          result += `<img src="${image.url}" alt="Album cover" ` +
            `height="${image.height}" width="${image.width}" ` +
            `style="margin-right:10px;" />`;
        }
      }

      result += `<div>`;
      result += `<div><b>${track.name || '(unknown song name)'}</b></div>`;

      artistName = track.artists && track.artists.length ?
        track.artists[0].name : '(unknown artist)';
      result += `<div style="font-size:12px;margin-top:10px;">${artistName}</div>`;

      result += `</div></div></a></div>`;
      return result;
    }
  };
}());
<commit_msg>-More style adjustments<commit_after>(function () {
  'use strict';

  var _ = require('underscore');

  module.exports = {
    getSearchPromptTemplate: function () {
      return `<i>(enter a search term)</i>`;
    },
    // Returns search result template for the track.
    getTrackSearchResultTemplate: function (track) {
      var result = '';

      if (!track || !track.name) {
        return result;
      }

      result += `<div><b>${track.name}</b></div>`;

      if (track.artists && track.artists.length && track.artists[0].name) {
        result += `<div>${track.artists[0].name}</div>`;
      } else {
        result += `<div>(unknown artist)</div>`;
      }

      return result;
    },
    getNoSearchResultsTemplate: function () {
      return `<i>(no results)</i>`;
    },
    // Returns full track link template
    getRobustTrackLinkTemplate: function (track) {
      var result = '',
          image,
          artistName;

      if (!track || !track.id) {
        return result;
      }

      result += `<a href="https://embed.spotify.com/?uri=spotify:track:${track.id}" ` +
        `target="_blank" style="text-decoration:none;color:#fff;">`;
      result += `<div style="display:inline-block;padding:15px;` +
        `font-family:helvetica,sans-serif;border-radius:3px;` +
        `background-color:#000;border:1px solid #2ebd59;" ` +
        `onmouseover="this.style.opacity='0.8';" ` +
        `onmouseout="this.style.opacity='1'">`;
      result += `<div style="display:flex;align-items:center;">`;

      if (track.album && track.album.images && track.album.images.length) {
        image = _.chain(track.album.images)
          .sortBy('width')
          .first()
          .value();

        if (!!image) {
          result += `<img src="${image.url}" alt="Album cover" ` +
            `height="${image.height}" width="${image.width}" ` +
            `style="margin-right:15px;" />`;
        }
      }

      result += `<div>`;
      result += `<div><b>${track.name || '(unknown song name)'}</b></div>`;

      artistName = track.artists && track.artists.length ?
        track.artists[0].name : '(unknown artist)';
      result += `<div style="font-size:12px;margin-top:10px;">${artistName}</div>`;

      result += `</div></div></div></a>`;
      return result;
    }
  };
}());
<|endoftext|>


<commit_before>/**
 * @fileoverview Utility functions related to the user agent.
 */

function isMobile() {
  return isIOS() || isAndroid();
}

function isIOS() {
  return /iPhone|iPad|iPod/i.test(navigator.userAgent);
}

function isAndroid() {
  return /Android/i.test(navigator.userAgent);
}

function isChrome() {
  return navigator.userAgent.indexOf('Chrome') != -1;
}

function isSafari() {
  return !isChrome() && navigator.userAgent.indexOf('Safari') != -1;
}

function isFirefox() {
  return navigator.userAgent.indexOf('Firefox') != -1;
}

function isIE() {
  return /MSIE\/\d+/.test(navigator.userAgent);
}

function isIEorEdge() {
  return /Edge\/\d+/.test(navigator.userAgent) ||
      /MSIE\/\d+/.test(navigator.userAgent) ||
      /Trident\/\d+/.test(navigator.userAgent);
}

module.exports = {
  isAndroid: isAndroid,
  isChrome: isChrome,
  isFirefox: isFirefox,
  isIOS: isIOS,
  isIE: isIE,
  isIEorEdge: isIEorEdge,
  isMobile: isMobile,
  isSafari: isSafari
};
<commit_msg>Add Edge useragent detection<commit_after>/**
 * @fileoverview Utility functions related to the user agent.
 */

function isMobile() {
  return isIOS() || isAndroid();
}

function isIOS() {
  return /iPhone|iPad|iPod/i.test(navigator.userAgent);
}

function isAndroid() {
  return /Android/i.test(navigator.userAgent);
}

function isChrome() {
  return navigator.userAgent.indexOf('Chrome') != -1 && !isEdge();
}

function isSafari() {
  return !isChrome() && navigator.userAgent.indexOf('Safari') != -1;
}

function isFirefox() {
  return navigator.userAgent.indexOf('Firefox') != -1;
}

function isIE() {
  return /MSIE\/\d+/.test(navigator.userAgent);
}

function isEdge() {
  return navigator.userAgent.indexOf('Edge') != -1;
}

function isIEorEdge() {
  return /Edge\/\d+/.test(navigator.userAgent) ||
      /MSIE\/\d+/.test(navigator.userAgent) ||
      /Trident\/\d+/.test(navigator.userAgent);
}

module.exports = {
  isAndroid: isAndroid,
  isChrome: isChrome,
  isEdge: isEdge,
  isFirefox: isFirefox,
  isIOS: isIOS,
  isIE: isIE,
  isIEorEdge: isIEorEdge,
  isMobile: isMobile,
  isSafari: isSafari
};
<|endoftext|>


<commit_before>cordova.define("com.citronium.lineaprocdv.LineaProCDV", function(require, exports, module) {var argscheck = require('cordova/argscheck'),
    channel = require('cordova/channel'),
    utils = require('cordova/utils'),
    exec = require('cordova/exec'),
    cordova = require('cordova');

 function LineaProCDV() {
    this.results = [];
    this.connCallback = null;
    this.errorCallback = null;
    this.cancelCallback = null;

}

LineaProCDV.prototype.initDT = function(connectionCallback, cancelCallback, errorCallback) {
    this.results = [];
    this.connCallback = connectionCallback;
    exec(null, errorCallback, "LineaProCDV", "initDT", []);
};

LineaProCDV.prototype.barcodeStart = function() {
    exec(null, null, "LineaProCDV", "barcodeStart", []);
};

LineaProCDV.prototype.barcodeStop = function() {
    exec(null, null, "LineaProCDV", "barcodeStop", []);
};

LineaProCDV.prototype.connectionChanged = function(state) {
    this.connCallback(state);
};

module.exports = new LineaProCDV();
});
<commit_msg>- fixed "cordova.define" from js<commit_after>var argscheck = require('cordova/argscheck'),
    channel = require('cordova/channel'),
    utils = require('cordova/utils'),
    exec = require('cordova/exec'),
    cordova = require('cordova');

 function LineaProCDV() {
    this.results = [];
    this.connCallback = null;
    this.errorCallback = null;
    this.cancelCallback = null;

}

LineaProCDV.prototype.initDT = function(connectionCallback, cancelCallback, errorCallback) {
    this.results = [];
    this.connCallback = connectionCallback;
    exec(null, errorCallback, "LineaProCDV", "initDT", []);
};

LineaProCDV.prototype.barcodeStart = function() {
    exec(null, null, "LineaProCDV", "barcodeStart", []);
};

LineaProCDV.prototype.barcodeStop = function() {
    exec(null, null, "LineaProCDV", "barcodeStop", []);
};

LineaProCDV.prototype.connectionChanged = function(state) {
    this.connCallback(state);
};

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


<commit_before>var app = angular.module('timecrunch', ['ui.router']);

app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('home', {
      url: '/home',
      templateUrl: '/home.html',
      controller: 'DashCtrl'
    })
    .state('food', {
      url: '/food',
      templateUrl: '/food.html',
      controller: 'ListCtrl',
      resolve: {
        foodPromise: ['foods', function(foods) {
            return foods.getFood();
        }]
      }
    })
    .state('recipes', {
      url: '/recipes',
      templateUrl: '/recipes.html',
      controller: 'ListCtrl',
      resolve: {
        recipePromise: ['recipes', function(recipes) {
            return recipes.getAll();
        }]
      }
    })
    .state('recipeform', {
      url: '/recipes/form',
      templateUrl: '/recipeform.html',
      controller: 'ListCtrl'
    })
    .state('recipe', {
      url: '/recipes/{id}',
      templateUrl: '/recipe.html',
      controller: 'RecipesCtrl',
      resolve: {
        recipe: ['$stateParams', 'recipes', function($stateParams, recipes) {
          return recipes.get($stateParams.id);
        }]
      }
    })
    .state('login', {
      url: '/login',
      templateUrl: '/login.html',
      controller: 'AuthCtrl',
      onEnter: ['$state', 'auth', function($state, auth) {
        if(auth.isLoggedIn()) {
          $state.go('home');
        }
      }]
    })
    .state('register', {
      url: '/register',
      templateUrl: '/register.html',
      controller: 'AuthCtrl',
      onEnter: ['$state', 'auth', function($state, auth) {
        if(auth.isLoggedIn()) {
          $state.go('home');
        }
      }]
    });

  $urlRouterProvider.otherwise('home');
}]);

app.factory('auth', ['$http', '$window', function($http, $window) {
  var auth = {};

  // save given token
  auth.saveToken = function(token) {
    $window.localStorage['time-crunch-token'] = token;
  };

  // get token from localStorage
  auth.getToken = function() {
    return $window.localStorage['time-crunch-token'];
  };

  // register user
  auth.register = function(user) {
    return $http.post('/register', user).then(function(data) {
      auth.saveToken(data.data.token);
    });
  };

  // login user save token
  auth.logIn = function(user) {
    return $http.post('/login', user).then(function(data) {
      auth.saveToken(data.data.token);
    });
  };

  // logout a user and delete token
  auth.logOut = function() {
    $window.localStorage.removeItem('time-crunch-token');
  };

  // check if user is logged in
  auth.isLoggedIn = function() {
    var token = auth.getToken();

    if(token) {
      var payload = JSON.parse($window.atob(token.split('.')[1]));

      return payload.exp > Date.now() / 1000;
    } else {
      return false;
    }
  };

  // returns currently logged in username
  auth.currentUser = function() {
    if(auth.isLoggedIn()) {
      var token = auth.getToken();
      var payload = JSON.parse($window.atob(token.split('.')[1]));

      return payload.username;
      }
    };

  return auth;
}]);

app.factory('foods', ['$http', '$state', 'auth', function($http, $state, auth) {
  var o = {
    foods: []
  };

  o.getFood = function() {
    if(auth.isLoggedIn()) {
      return $http.get('/food', {
        headers: {Authorization: 'Bearer ' + auth.getToken()}
      }).then(function(data) {
        angular.copy(data.data, o.foods);
      });
    }
    $state.go('login');
  };

  o.create = function(food) {
    return $http.post('/food', food, {
      headers: {Authorization: 'Bearer ' + auth.getToken()}
    }).then(function(data) {
      o.getFood();
    });
  };

  o.delete = function(food) {
    return $http.delete('/food/' + food._id).then(function(data) {
      o.getFood();
    });
  };

  return o;
}]);

app.factory('recipes', ['$http', 'auth', function($http, auth) {
  var o = {
    recipes: []
  };

  o.getAll = function() {
    return $http.get('/recipes').then(function(data) {
      angular.copy(data.data, o.recipes);
    });
  };

  o.get = function(id) {
    for(i = 0; i < o.recipes.length; ++i) {
      if(o.recipes[i]._id == id) {
        return o.recipes[i];
      }
    }
  };

  o.create = function(recipe) {
    return $http.post('/recipes', recipe, {
      headers: {Authorization: 'Bearer ' + auth.getToken()}
    }).then(function(data) {
      o.getAll();
    });
  };

  o.delete = function(recipe) {
    return $http.delete('/recipes/' + recipe._id).then(function(data) {
      o.getAll();
    });
  };

  return o;
}]);

// Controller for dashboard on home/index
app.controller('DashCtrl', [
  '$scope',
  'foods',
  function($scope, foods){
    $scope.foods = foods.foods;
}]);

// Controller for recipe and food lists
app.controller('ListCtrl', [
  '$scope',
  '$state',
  'auth',
  'foods',
  'recipes',
  function($scope, $state, auth, foods, recipes) {

    $scope.foods = foods.foods;
    $scope.recipes = recipes.recipes;
    $scope.ingredients = [];
    $scope.isLoggedIn = auth.isLoggedIn;

    $scope.categories = [
      "Baking",
      "Dairy",
      "Fruit",
      "Herb/Spice",
      "Meat",
      "Sauce",
      "Vegetable",
      "Other-Ingredient",
      "Other-Food",
      "Other-Produce"
    ];

    $scope.sortBy = "name";
    $scope.filterCat = "";

    $scope.filter = function() {
      return function(item) {
        if($scope.filterCat == "" || !$scope.filterCat
          || $scope.filterCat == item.category) {
          return true;
        }
        return false;
      };
    };

    // Add a new food
    $scope.addFood = function() {
      // Make sure food name is valid
      if(!$scope.name || $scope.name == '') {
        alert("Please fill in the name field");
        return;
      }
      // If sell by was left blank, set it to 2 years from now
      if(!$scope.sellBy) {
        $scope.sellBy = new Date();
        $scope.sellBy.setDate($scope.sellBy.getDate() + 730);
      }
      foods.create({
        name: $scope.name,
        sellBy: $scope.sellBy,
        amount: $scope.amount,
        units: $scope.units,
        category: $scope.category
      });
    };

    // Remove a food
    $scope.removeFood = function(food) {
      foods.delete(food);
    };

    // Add a new recipe
    $scope.addRecipe = function() {
      //Check that the recipe has a name, ingredients, and instructions
      if(!$scope.name || $scope.name == '' || !$scope.ingredients) {
        alert("Please make sure all fields are filled out");
        return;
      }

      if(!$scope.instructions && !$scope.link) {
        alert("Please provide either instructions or a link to the full recipe");
        return;
      }

      recipes.create({
        name: $scope.name,
        ingredients: $scope.ingredients,
        prepTime: $scope.prepTime,
        link: $scope.link,
        instructions: $scope.instructions
      }).then(function success() {
        // Return to the recipe list
        $state.go('recipes');
      }, function failure(error) {
        // Show error message
        $scope.error = error.data;
      });
    };

    // Add an ingredient to a recipe
    $scope.addIngredient = function() {
      // Build the ingredient string
      var ing = $scope.ing_name.concat(" - " + $scope.ing_amount);
      if($scope.ing_unit) {
        ing = ing.concat(" " + $scope.ing_unit);
      }

      // Check if the ingredient is a duplicate
      if($scope.ingredients.indexOf(ing) > -1) {
        alert("Duplicate ingredients! Please change your entry.");
      }
      else {
        ($scope.ingredients).push(ing);
      }
    };

    // Remove an ingredient from a recipe
    $scope.removeIngredient = function(ingredient) {
      if($scope.ingredients.length == 1) {
        $scope.ingredients = [];
      }
      else {
        var i = $scope.ingredients.indexOf(ingredient);
        $scope.ingredients.splice(i, 1);
      }
    };
}]);

// Controller for recipe details page
app.controller('RecipesCtrl', [
  '$scope',
  '$state',
  'recipe',
  'recipes',
  'auth',
  function($scope, $state, recipe, recipes, auth){
    $scope.recipe = recipe;
    $scope.currentUser = auth.currentUser();

    $scope.canEdit = function() {
      return recipe.author == $scope.currentUser;
    }

    $scope.deleteRecipe = function() {
      recipes.delete(recipe);
      $state.go('recipes');
    }

}]);

// Controller for logging in and registering
app.controller('AuthCtrl', [
  '$scope',
  '$state',
  'auth',
  function($scope, $state, auth) {
    $scope.user = {};

    // Registers a new user
    $scope.register = function() {
      auth.register($scope.user).then(function success() {
        // Go to dashboard once logged in
        $state.go('home');
      }, function failure(error) {
        // Show error message
        $scope.error = error.data;
      });
    };

    // Starts a new login session
    $scope.logIn = function() {
      auth.logIn($scope.user).then(function success() {
        // Go to dashboard once logged in
        $state.go('home');
      }, function failure(error) {
        // Show error message
        $scope.error = error.data;
      });
    };
}]);

// Controller for dashboard on home/index
app.controller('NavCtrl', [
  '$scope',
  'auth',
  function($scope, auth){

    $scope.isLoggedIn = auth.isLoggedIn;
    $scope.currentUser = auth.currentUser;
    $scope.logOut = auth.logOut;
}]);<commit_msg>deleteRecipe now checks canEdit<commit_after>var app = angular.module('timecrunch', ['ui.router']);

app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('home', {
      url: '/home',
      templateUrl: '/home.html',
      controller: 'DashCtrl'
    })
    .state('food', {
      url: '/food',
      templateUrl: '/food.html',
      controller: 'ListCtrl',
      resolve: {
        foodPromise: ['foods', function(foods) {
            return foods.getFood();
        }]
      }
    })
    .state('recipes', {
      url: '/recipes',
      templateUrl: '/recipes.html',
      controller: 'ListCtrl',
      resolve: {
        recipePromise: ['recipes', function(recipes) {
            return recipes.getAll();
        }]
      }
    })
    .state('recipeform', {
      url: '/recipes/form',
      templateUrl: '/recipeform.html',
      controller: 'ListCtrl'
    })
    .state('recipe', {
      url: '/recipes/{id}',
      templateUrl: '/recipe.html',
      controller: 'RecipesCtrl',
      resolve: {
        recipe: ['$stateParams', 'recipes', function($stateParams, recipes) {
          return recipes.get($stateParams.id);
        }]
      }
    })
    .state('login', {
      url: '/login',
      templateUrl: '/login.html',
      controller: 'AuthCtrl',
      onEnter: ['$state', 'auth', function($state, auth) {
        if(auth.isLoggedIn()) {
          $state.go('home');
        }
      }]
    })
    .state('register', {
      url: '/register',
      templateUrl: '/register.html',
      controller: 'AuthCtrl',
      onEnter: ['$state', 'auth', function($state, auth) {
        if(auth.isLoggedIn()) {
          $state.go('home');
        }
      }]
    });

  $urlRouterProvider.otherwise('home');
}]);

app.factory('auth', ['$http', '$window', function($http, $window) {
  var auth = {};

  // save given token
  auth.saveToken = function(token) {
    $window.localStorage['time-crunch-token'] = token;
  };

  // get token from localStorage
  auth.getToken = function() {
    return $window.localStorage['time-crunch-token'];
  };

  // register user
  auth.register = function(user) {
    return $http.post('/register', user).then(function(data) {
      auth.saveToken(data.data.token);
    });
  };

  // login user save token
  auth.logIn = function(user) {
    return $http.post('/login', user).then(function(data) {
      auth.saveToken(data.data.token);
    });
  };

  // logout a user and delete token
  auth.logOut = function() {
    $window.localStorage.removeItem('time-crunch-token');
  };

  // check if user is logged in
  auth.isLoggedIn = function() {
    var token = auth.getToken();

    if(token) {
      var payload = JSON.parse($window.atob(token.split('.')[1]));

      return payload.exp > Date.now() / 1000;
    } else {
      return false;
    }
  };

  // returns currently logged in username
  auth.currentUser = function() {
    if(auth.isLoggedIn()) {
      var token = auth.getToken();
      var payload = JSON.parse($window.atob(token.split('.')[1]));

      return payload.username;
      }
    };

  return auth;
}]);

app.factory('foods', ['$http', '$state', 'auth', function($http, $state, auth) {
  var o = {
    foods: []
  };

  o.getFood = function() {
    if(auth.isLoggedIn()) {
      return $http.get('/food', {
        headers: {Authorization: 'Bearer ' + auth.getToken()}
      }).then(function(data) {
        angular.copy(data.data, o.foods);
      });
    }
    $state.go('login');
  };

  o.create = function(food) {
    return $http.post('/food', food, {
      headers: {Authorization: 'Bearer ' + auth.getToken()}
    }).then(function(data) {
      o.getFood();
    });
  };

  o.delete = function(food) {
    return $http.delete('/food/' + food._id).then(function(data) {
      o.getFood();
    });
  };

  return o;
}]);

app.factory('recipes', ['$http', 'auth', function($http, auth) {
  var o = {
    recipes: []
  };

  o.getAll = function() {
    return $http.get('/recipes').then(function(data) {
      angular.copy(data.data, o.recipes);
    });
  };

  o.get = function(id) {
    for(i = 0; i < o.recipes.length; ++i) {
      if(o.recipes[i]._id == id) {
        return o.recipes[i];
      }
    }
  };

  o.create = function(recipe) {
    return $http.post('/recipes', recipe, {
      headers: {Authorization: 'Bearer ' + auth.getToken()}
    }).then(function(data) {
      o.getAll();
    });
  };

  o.delete = function(recipe) {
    return $http.delete('/recipes/' + recipe._id).then(function(data) {
      o.getAll();
    });
  };

  return o;
}]);

// Controller for dashboard on home/index
app.controller('DashCtrl', [
  '$scope',
  'foods',
  function($scope, foods){
    $scope.foods = foods.foods;
}]);

// Controller for recipe and food lists
app.controller('ListCtrl', [
  '$scope',
  '$state',
  'auth',
  'foods',
  'recipes',
  function($scope, $state, auth, foods, recipes) {

    $scope.foods = foods.foods;
    $scope.recipes = recipes.recipes;
    $scope.ingredients = [];
    $scope.isLoggedIn = auth.isLoggedIn;

    $scope.categories = [
      "Baking",
      "Dairy",
      "Fruit",
      "Herb/Spice",
      "Meat",
      "Sauce",
      "Vegetable",
      "Other-Ingredient",
      "Other-Food",
      "Other-Produce"
    ];

    $scope.sortBy = "name";
    $scope.filterCat = "";

    $scope.filter = function() {
      return function(item) {
        if($scope.filterCat == "" || !$scope.filterCat
          || $scope.filterCat == item.category) {
          return true;
        }
        return false;
      };
    };

    // Add a new food
    $scope.addFood = function() {
      // Make sure food name is valid
      if(!$scope.name || $scope.name == '') {
        alert("Please fill in the name field");
        return;
      }
      // If sell by was left blank, set it to 2 years from now
      if(!$scope.sellBy) {
        $scope.sellBy = new Date();
        $scope.sellBy.setDate($scope.sellBy.getDate() + 730);
      }
      foods.create({
        name: $scope.name,
        sellBy: $scope.sellBy,
        amount: $scope.amount,
        units: $scope.units,
        category: $scope.category
      });
    };

    // Remove a food
    $scope.removeFood = function(food) {
      foods.delete(food);
    };

    // Add a new recipe
    $scope.addRecipe = function() {
      //Check that the recipe has a name, ingredients, and instructions
      if(!$scope.name || $scope.name == '' || !$scope.ingredients) {
        alert("Please make sure all fields are filled out");
        return;
      }

      if(!$scope.instructions && !$scope.link) {
        alert("Please provide either instructions or a link to the full recipe");
        return;
      }

      recipes.create({
        name: $scope.name,
        ingredients: $scope.ingredients,
        prepTime: $scope.prepTime,
        link: $scope.link,
        instructions: $scope.instructions
      }).then(function success() {
        // Return to the recipe list
        $state.go('recipes');
      }, function failure(error) {
        // Show error message
        $scope.error = error.data;
      });
    };

    // Add an ingredient to a recipe
    $scope.addIngredient = function() {
      // Build the ingredient string
      var ing = $scope.ing_name.concat(" - " + $scope.ing_amount);
      if($scope.ing_unit) {
        ing = ing.concat(" " + $scope.ing_unit);
      }

      // Check if the ingredient is a duplicate
      if($scope.ingredients.indexOf(ing) > -1) {
        alert("Duplicate ingredients! Please change your entry.");
      }
      else {
        ($scope.ingredients).push(ing);
      }
    };

    // Remove an ingredient from a recipe
    $scope.removeIngredient = function(ingredient) {
      if($scope.ingredients.length == 1) {
        $scope.ingredients = [];
      }
      else {
        var i = $scope.ingredients.indexOf(ingredient);
        $scope.ingredients.splice(i, 1);
      }
    };
}]);

// Controller for recipe details page
app.controller('RecipesCtrl', [
  '$scope',
  '$state',
  'recipe',
  'recipes',
  'auth',
  function($scope, $state, recipe, recipes, auth){
    $scope.recipe = recipe;
    $scope.currentUser = auth.currentUser();

    $scope.canEdit = function() {
      return recipe.author == $scope.currentUser;
    }

    $scope.deleteRecipe = function() {
      if($scope.canEdit()) {
        recipes.delete(recipe);
        $state.go('recipes');
      }
      else {
        alert('You cannot delete this recipe!');
      }
    }

}]);

// Controller for logging in and registering
app.controller('AuthCtrl', [
  '$scope',
  '$state',
  'auth',
  function($scope, $state, auth) {
    $scope.user = {};

    // Registers a new user
    $scope.register = function() {
      auth.register($scope.user).then(function success() {
        // Go to dashboard once logged in
        $state.go('home');
      }, function failure(error) {
        // Show error message
        $scope.error = error.data;
      });
    };

    // Starts a new login session
    $scope.logIn = function() {
      auth.logIn($scope.user).then(function success() {
        // Go to dashboard once logged in
        $state.go('home');
      }, function failure(error) {
        // Show error message
        $scope.error = error.data;
      });
    };
}]);

// Controller for dashboard on home/index
app.controller('NavCtrl', [
  '$scope',
  'auth',
  function($scope, auth){

    $scope.isLoggedIn = auth.isLoggedIn;
    $scope.currentUser = auth.currentUser;
    $scope.logOut = auth.logOut;
}]);<|endoftext|>


<commit_before><commit_msg>sort values<commit_after><|endoftext|>


<commit_before><commit_msg>even faster admin-support redraw<commit_after><|endoftext|>


<commit_before>$(function() {

  var $editor = $('.coach_edit');

  var todo = (function() {

    var $overview = $editor.find('.overview');
    var $el = $overview.find('.todo');
    var $option = $editor.find('select[name=listed] option[value=true]');

    var must = [{
      html: 'Complete your lichess profile',
      check: function() {
        return $el.data('profile');
      }
    }, {
      html: 'Upload a profile picture',
      check: function() {
        return $editor.find('img.picture').length;
      }
    }, {
      html: 'Fill in basic informations',
      check: function() {
        ['profile.headline', 'profile.languages'].forEach(function(name) {
          if (!$editor.find('[name="' + name + '"]').val()) return false;
        });
        return true;
      }
    }, {
      html: 'Fill at least 3 description texts',
      check: function() {
        return $editor.find('.panel.texts textarea').filter(function() {
          return !!$(this).val();
        }).length >= 3;
      }
    }];

    return function() {
      var points = [];
      must.forEach(function(o) {
        if (!o.check()) points.push($('
').html(o.html));
      });
      $el.find('ul').html(points);
      var fail = !!points.length;
      $overview.toggleClass('with_todo', fail);
      if (fail) $option.parent().val('false');
      $option.attr('disabled', fail);
    };
  })();
  todo();

  $editor.find('.tabs > div').click(function() {
    $editor.find('.tabs > div').removeClass('active');
    $(this).addClass('active');
    $editor.find('.panel').removeClass('active');
    $editor.find('.panel.' + $(this).data('tab')).addClass('active');
    $editor.find('div.status').removeClass('saved');
  });
  var submit = $.fp.debounce(function() {
    $editor.find('form.form').ajaxSubmit({
      success: function() {
        $editor.find('div.status').addClass('saved');
      }
    });
  }, 1000);
  $editor.find('input, textarea, select')
    .bind("input paste change keyup", function() {
      $editor.find('div.status').removeClass('saved');
      submit();
    });

  if ($editor.find('.reviews .review').length)
    $editor.find('.tabs div[data-tab=reviews]').click();

  $reviews = $editor.find('.reviews');
  $reviews.find('.actions a').click(function() {
    var $review = $(this).parents('.review');
    $.ajax({
      method: 'post',
      url: $review.data('action') + '?v=' + $(this).data('value'),
      complete: function() {
        todo();
      }
    });
    $review.slideUp(300);
    $editor.find('.tabs div[data-tab=reviews]').attr('data-count', $reviews.find('.review').length - 1);
    return false;
  });

  $editor.find('.analytics .pageview_chart').each(function() {
    var $el = $(this);
    $.getJSON('/monitor/coach/pageview', function(data) {
      lichess.coachPageViewChart(data, $el);
    });
  });

  $('.coach_picture form.upload input[type=file]').change(function() {
    $('.picture_wrap').html(lichess.spinnerHtml);
    $(this).parents('form').submit();
  });
});
<commit_msg>fix coach form validation<commit_after>$(function() {

  var $editor = $('.coach_edit');

  var todo = (function() {

    var $overview = $editor.find('.overview');
    var $el = $overview.find('.todo');
    var $option = $editor.find('select[name=listed] option[value=true]');

    var must = [{
      html: 'Complete your lichess profile',
      check: function() {
        return $el.data('profile');
      }
    }, {
      html: 'Upload a profile picture',
      check: function() {
        return $editor.find('img.picture').length;
      }
    }, {
      html: 'Fill in basic informations',
      check: function() {
        ['profile.headline', 'profile.languages'].forEach(function(name) {
          if (!$editor.find('[name="' + name + '"]').val()) return false;
        });
        return true;
      }
    }, {
      html: 'Fill at least 3 description texts',
      check: function() {
        return $editor.find('.panel.texts textarea').filter(function() {
          return !!$(this).val();
        }).length >= 3;
      }
    }];

    return function() {
      var points = [];
      must.forEach(function(o) {
        if (!o.check()) points.push($('
').html(o.html));
      });
      $el.find('ul').html(points);
      var fail = !!points.length;
      $overview.toggleClass('with_todo', fail);
      if (fail) $option.parent().val('false');
      $option.attr('disabled', fail);
    };
  })();
  todo();

  $editor.find('.tabs > div').click(function() {
    $editor.find('.tabs > div').removeClass('active');
    $(this).addClass('active');
    $editor.find('.panel').removeClass('active');
    $editor.find('.panel.' + $(this).data('tab')).addClass('active');
    $editor.find('div.status').removeClass('saved');
  });
  var submit = $.fp.debounce(function() {
    $editor.find('form.form').ajaxSubmit({
      success: function() {
        $editor.find('div.status').addClass('saved');
        todo();
      }
    });
  }, 1000);
  $editor.find('input, textarea, select')
    .bind("input paste change keyup", function() {
      $editor.find('div.status').removeClass('saved');
      submit();
    });

  if ($editor.find('.reviews .review').length)
    $editor.find('.tabs div[data-tab=reviews]').click();

  $reviews = $editor.find('.reviews');
  $reviews.find('.actions a').click(function() {
    var $review = $(this).parents('.review');
    $.ajax({
      method: 'post',
      url: $review.data('action') + '?v=' + $(this).data('value')
    });
    $review.slideUp(300);
    $editor.find('.tabs div[data-tab=reviews]').attr('data-count', $reviews.find('.review').length - 1);
    return false;
  });

  $editor.find('.analytics .pageview_chart').each(function() {
    var $el = $(this);
    $.getJSON('/monitor/coach/pageview', function(data) {
      lichess.coachPageViewChart(data, $el);
    });
  });

  $('.coach_picture form.upload input[type=file]').change(function() {
    $('.picture_wrap').html(lichess.spinnerHtml);
    $(this).parents('form').submit();
  });
});
<|endoftext|>


<commit_before>var map, directionsDisplay, pos;
var directionsService = new google.maps.DirectionsService();

function initialize() {
  var mapOptions = {
    zoom: 18
  };
  var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

  // Try HTML5 geolocation
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      pos = new google.maps.LatLng(position.coords.latitude,
                                  position.coords.longitude);
      var infowindow = new google.maps.InfoWindow({
        map: map,
        position: pos
      });

      // var marker = new google.maps.Marker({
      //   position: pos,
      //   map: map,
      //   draggable: true,
      //   title: 'Your Position'
      // });

      map.setCenter(pos);

      // google.maps.event.addListener(marker, "dragend", function(event) {
      //   var lat = event.latLng.k;
      //   var lng = event.latLng.B;
      //   updateMap(lat, lng);
      // });
    google.maps.event.addListener(map, 'tilesloaded', function(){
      // Map has loaded
      console.log('Done Loading');
    });
  }, function() {
    handleNoGeolocation(true);
    });
  } else {
    // Browser doesn't support Geolocation
    handleNoGeolocation(false);
  }

  function handleNoGeolocation(errorFlag) {
    if (errorFlag) {
      var content = 'Error: The Geolocation service failed.';
    } else {
      var content = 'Error: Your browser doesn\'t support geolocation.';
    }

    var options = {
      map: map,
      position: new google.maps.LatLng(60, 105),
      content: content
    };

    var infowindow = new google.maps.InfoWindow(options);
    map.setCenter(options.position);
  }

  var rendererOptions = {draggable: true};

  directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
  directionsDisplay.setMap(map);
  directionsDisplay.setPanel(document.getElementById('directions'));
}

function updateMap(latitude, longitude) {
  centerAt = new google.maps.LatLng(latitude, longitude);
  map.setCenter(centerAt);
  addToForm(latitude, longitude);
}

function calcRoute() {
  setTimeout(function() {
    var $end = $('#end').val();
    var parsedEnd = parseCoordinates($end);
    var end = new google.maps.LatLng(parsedEnd[0], parsedEnd[1]);

    var request = {
      origin: pos,
      destination: end,
      travelMode: google.maps.TravelMode.WALKING
    };

    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
      }
    });
  }, 4000);
}

function parseCoordinates(coord) {
  var separateCoord = coord.split(", ");
  separateCoord[0] = separateCoord[0].replace("(", "");
  separateCoord[1] = separateCoord[1].replace(")", "");
  var finalCoord = [parseFloat(separateCoord[0]),
                    parseFloat(separateCoord[1])];
  return finalCoord;
}

google.maps.event.addDomListener(window, 'load', initialize);
google.maps.event.addDomListener(window, 'load', calcRoute);<commit_msg>Remove timeout function<commit_after>var map, directionsDisplay, pos, rendererOptions;
var directionsService = new google.maps.DirectionsService();

function initialize() {
  var mapOptions = {
    zoom: 18
  };
  var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

  // Try HTML5 geolocation
  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      pos = new google.maps.LatLng(position.coords.latitude,
                                  position.coords.longitude);
      var infowindow = new google.maps.InfoWindow({
        map: map,
        position: pos
      });

      map.setCenter(pos);

      google.maps.event.addListener(map, 'tilesloaded', function(){
      // Map has loaded
      console.log('Done Loading');
    });

    rendererOptions = {draggable: true};
    directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
    directionsDisplay.setMap(map);
    directionsDisplay.setPanel(document.getElementById('directions'));
    calcRoute();

  }, function() {
    handleNoGeolocation(true);
    });
  } else {
    // Browser doesn't support Geolocation
    handleNoGeolocation(false);
  }

  function handleNoGeolocation(errorFlag) {
    if (errorFlag) {
      var content = 'Error: The Geolocation service failed.';
    } else {
      var content = 'Error: Your browser doesn\'t support geolocation.';
    }

    var options = {
      map: map,
      position: new google.maps.LatLng(60, 105),
      content: content
    };

    var infowindow = new google.maps.InfoWindow(options);
    map.setCenter(options.position);
  }
}

function updateMap(latitude, longitude) {
  centerAt = new google.maps.LatLng(latitude, longitude);
  map.setCenter(centerAt);
  addToForm(latitude, longitude);
}

function calcRoute() {
  var $end = $('#end').val();
  var parsedEnd = parseCoordinates($end);
  var end = new google.maps.LatLng(parsedEnd[0], parsedEnd[1]);

  var request = {
    origin: pos,
    destination: end,
    travelMode: google.maps.TravelMode.WALKING
  };

  directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);
    }
  });
}

function parseCoordinates(coord) {
  var separateCoord = coord.split(", ");
  separateCoord[0] = separateCoord[0].replace("(", "");
  separateCoord[1] = separateCoord[1].replace(")", "");
  var finalCoord = [parseFloat(separateCoord[0]),
                    parseFloat(separateCoord[1])];
  return finalCoord;
}

google.maps.event.addDomListener(window, 'load', initialize);<|endoftext|>


<commit_before>var page = require("webpage").create();

var port = 45001;

// Provide a console.log for the test output
page.onConsoleMessage = function(msg) {
    console.log(msg);

    if (msg === "Jasmine Testing Completed") {
        phantom.exit();
    }
};

var runTest = function(failCount) {
    page.open("http://localhost:" + port, function(status) {
        if (status !== "success") {
            failCount++;
            if (failCount > 20) {
                console.log("Fatal: No webserver started@https://localhost:" + port, status);
                phantom.exit();
            } else {
                console.log("Waiting for web server...");

                // Recurse till the webserver is alive
                runTest(failCount);
            }
        } else {

            // Call into the jasmine test code
            page.evaluate(function() {
                require(["main_test"], function(tester) {
                    tester.runConsoleReport();
                });
            });
        }
    });
};

runTest(0);
<commit_msg>Major simplification of phantomjs script<commit_after>var page = require("webpage").create();

var port = 45001;

// Provide a console.log for the test output
page.onConsoleMessage = function(msg) {
    console.log(msg);

    if (msg === "Jasmine Testing Completed") {
        phantom.exit();
    }
};

var runTest = function() {
    page.open("http://localhost:" + port, function() {
        // Call into the jasmine test code
        page.evaluate(function() {
            require(["main_test"], function(tester) {
                tester.runConsoleReport();
            });
        });
    });
};

runTest();
<|endoftext|>


<commit_before>// @inheritedComponent Paper

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import withStyles from '../styles/withStyles';
import Paper from '../Paper';
import { capitalize } from '../utils/helpers';
import { LinearProgress } from '../Progress';

export const styles = theme => ({
  root: {
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    background: theme.palette.background.default,
    padding: theme.spacing.unit,
  },
  positionBottom: {
    position: 'fixed',
    bottom: 0,
    left: 0,
    right: 0,
    zIndex: theme.zIndex.mobileStepper,
  },
  positionTop: {
    position: 'fixed',
    top: 0,
    left: 0,
    right: 0,
    zIndex: theme.zIndex.mobileStepper,
  },
  positionStatic: {},
  dots: {
    display: 'flex',
    flexDirection: 'row',
  },
  dot: {
    backgroundColor: theme.palette.action.disabled,
    borderRadius: '50%',
    width: theme.spacing.unit,
    height: theme.spacing.unit,
    margin: '0 2px',
  },
  dotActive: {
    backgroundColor: theme.palette.primary.main,
  },
  progress: {
    width: '50%',
  },
});

function MobileStepper(props) {
  const {
    activeStep,
    backButton,
    classes,
    className: classNameProp,
    nextButton,
    position,
    steps,
    variant,
    ...other
  } = props;

  const className = classNames(
    classes.root,
    classes[`position${capitalize(position)}`],
    classNameProp,
  );

  return (
    <Paper square elevation={0} className={className} {...other}>
      {backButton}
      {variant === 'dots' && (

          {[...new Array(steps)].map((_, step) => {
            const dotClassName = classNames(
              {
                [classes.dotActive]: step === activeStep,
              },
              classes.dot,
            );
            // eslint-disable-next-line react/no-array-index-key
            return
;
          })}

      )}
      {variant === 'progress' && (

          <LinearProgress mode="determinate" value={Math.ceil(activeStep / (steps - 1) * 100)} />

      )}
      {nextButton}
    </Paper>
  );
}

MobileStepper.propTypes = {
  /**
   * Set the active step (zero based index).
   * Defines which dot is highlighted when the variant is 'dots'.
   */
  activeStep: PropTypes.number,
  /**
   * A back button element. For instance, it can be be a `Button` or a `IconButton`.
   */
  backButton: PropTypes.node,
  /**
   * Useful to extend the style applied to components.
   */
  classes: PropTypes.object.isRequired,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * A next button element. For instance, it can be be a `Button` or a `IconButton`.
   */
  nextButton: PropTypes.node,
  /**
   * Set the positioning type.
   */
  position: PropTypes.oneOf(['bottom', 'top', 'static']),
  /**
   * The total steps.
   */
  steps: PropTypes.number.isRequired,
  /**
   * The type of mobile stepper to use.
   */
  variant: PropTypes.oneOf(['text', 'dots', 'progress']),
};

MobileStepper.defaultProps = {
  activeStep: 0,
  position: 'bottom',
  variant: 'dots',
};

export default withStyles(styles, { name: 'MuiMobileStepper' })(MobileStepper);
<commit_msg>[Stepper] Mobile Stepper variant determinate (#10190)<commit_after>// @inheritedComponent Paper

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import withStyles from '../styles/withStyles';
import Paper from '../Paper';
import { capitalize } from '../utils/helpers';
import { LinearProgress } from '../Progress';

export const styles = theme => ({
  root: {
    display: 'flex',
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    background: theme.palette.background.default,
    padding: theme.spacing.unit,
  },
  positionBottom: {
    position: 'fixed',
    bottom: 0,
    left: 0,
    right: 0,
    zIndex: theme.zIndex.mobileStepper,
  },
  positionTop: {
    position: 'fixed',
    top: 0,
    left: 0,
    right: 0,
    zIndex: theme.zIndex.mobileStepper,
  },
  positionStatic: {},
  dots: {
    display: 'flex',
    flexDirection: 'row',
  },
  dot: {
    backgroundColor: theme.palette.action.disabled,
    borderRadius: '50%',
    width: theme.spacing.unit,
    height: theme.spacing.unit,
    margin: '0 2px',
  },
  dotActive: {
    backgroundColor: theme.palette.primary.main,
  },
  progress: {
    width: '50%',
  },
});

function MobileStepper(props) {
  const {
    activeStep,
    backButton,
    classes,
    className: classNameProp,
    nextButton,
    position,
    steps,
    variant,
    ...other
  } = props;

  const className = classNames(
    classes.root,
    classes[`position${capitalize(position)}`],
    classNameProp,
  );

  return (
    <Paper square elevation={0} className={className} {...other}>
      {backButton}
      {variant === 'dots' && (

          {[...new Array(steps)].map((_, step) => {
            const dotClassName = classNames(
              {
                [classes.dotActive]: step === activeStep,
              },
              classes.dot,
            );
            // eslint-disable-next-line react/no-array-index-key
            return
;
          })}

      )}
      {variant === 'progress' && (

          <LinearProgress variant="determinate" value={Math.ceil(activeStep / (steps - 1) * 100)} />

      )}
      {nextButton}
    </Paper>
  );
}

MobileStepper.propTypes = {
  /**
   * Set the active step (zero based index).
   * Defines which dot is highlighted when the variant is 'dots'.
   */
  activeStep: PropTypes.number,
  /**
   * A back button element. For instance, it can be be a `Button` or a `IconButton`.
   */
  backButton: PropTypes.node,
  /**
   * Useful to extend the style applied to components.
   */
  classes: PropTypes.object.isRequired,
  /**
   * @ignore
   */
  className: PropTypes.string,
  /**
   * A next button element. For instance, it can be be a `Button` or a `IconButton`.
   */
  nextButton: PropTypes.node,
  /**
   * Set the positioning type.
   */
  position: PropTypes.oneOf(['bottom', 'top', 'static']),
  /**
   * The total steps.
   */
  steps: PropTypes.number.isRequired,
  /**
   * The type of mobile stepper to use.
   */
  variant: PropTypes.oneOf(['text', 'dots', 'progress']),
};

MobileStepper.defaultProps = {
  activeStep: 0,
  position: 'bottom',
  variant: 'dots',
};

export default withStyles(styles, { name: 'MuiMobileStepper' })(MobileStepper);
<|endoftext|>