<commit_before>import update from 'react-addons-update'

const projects = (state = {
  isFetching: false,
  all: null,
  active: null,
  filter: {
    searchText: null
  }
}, action) => {
  let projects, sources, projectIndex, sourceIndex, versionIndex, activeProject, activeIndex, feeds, activeProjectId, project, newState, deployment
  switch (action.type) {
    case 'SET_PROJECT_VISIBILITY_SEARCH_TEXT':
      return update(state, {filter: {searchText: {$set: action.text}}})
    case 'CREATE_PROJECT':
      projects = [{
        isCreating: true,
        name: ''
      }, ...state.all]
      return update(state, { all: { $set: projects }})

    case 'CREATE_FEEDSOURCE':
      projectIndex = state.all.findIndex(p => p.id === action.projectId)
      project = state.all[projectIndex]
      newState = null
      console.log("adding fs to project", state.all[projectIndex]);

      // if project's feedSources array is undefined, add it
      if(!project.feedSources) {
        console.log('adding new fs array');
        newState = update(state, {all: {[projectIndex]: {$merge: {feedSources: []}}}})
      }

      // add new empty feed source to feedSources array
      const feedSource = {
        isCreating: true,
        name: '',
        projectId: project.id
      }
      return update(newState || state, {all: {[projectIndex]: {feedSources: {$unshift: [feedSource]}}}})

    case 'CREATE_DEPLOYMENT':
      projectIndex = state.all.findIndex(p => p.id === action.projectId)
      project = state.all[projectIndex]
      newState = null
      console.log("adding fs to project", state.all[projectIndex]);

      // if project's deployment array is undefined, add it
      if(!project.deployments) {
        console.log('adding new fs array');
        newState = update(state, {all: {[projectIndex]: {$merge: {deployments: []}}}})
      }

      // add new empty feed source to feedSources array
      deployment = {
        isCreating: true,
        name: '',
        project: project
      }
      return update(newState || state, {all: {[projectIndex]: {deployments: {$unshift: [deployment]}}}})

    case 'REQUEST_PROJECTS':
      return update(state, { isFetching: { $set: true }})

    case 'RECEIVE_PROJECTS':
      activeProjectId = state.active ? state.active.id : DT_CONFIG.application.active_project
      activeIndex = action.projects.findIndex(p => p.id === activeProjectId)
      return {
        isFetching: false,
        all: action.projects,
        active: activeIndex !== -1 ? action.projects[activeIndex] : null,
        filter: {
          searchText: null
        }
      }
    case 'SET_ACTIVE_PROJECT':
      return update(state, { active: { $set: action.project }})
    case 'RECEIVE_PROJECT':
      if (!state.all) { // there are no current projects loaded
        projects = [action.project]
      } else { // projects already loaded
        projectIndex = state.all.findIndex(p => p.id === action.project.id)
        if (projectIndex === -1) { // projects loaded but not this one; add it
          projects = [
            ...state.all,
            action.project
          ]
        } else { // projects loaded including this one, replace it
          projects = [
            ...state.all.slice(0, projectIndex),
            action.project,
            ...state.all.slice(projectIndex + 1)
          ]
        }
      }
      activeProjectId = state.active ? state.active.id : DT_CONFIG.application.active_project
      activeProject = action.project.id === activeProjectId ? action.project : null
      if (state.active && !activeProject) { // active project already exists and received project does not match active project
        activeProject = state.active
      }
      return update(state, {active: { $set: activeProject }, all: { $set: projects }})

    case 'RECEIVE_FEEDSOURCES':
      projectIndex = state.all.findIndex(p => p.id === action.projectId)
      if (state.active && action.projectId === state.active.id) {
        return update(state,
        {
          active: {$merge: {feedSources: action.feedSources}},
          all: {
            [projectIndex]: {$merge: {feedSources: action.feedSources}}
          }
        })
      } else { // if projectId does not match active project
        return update(state,
          {
            all: {
              [projectIndex]: {$merge: {feedSources: action.feedSources}}
            }
          }
        )
      }

    case 'RECEIVE_FEEDSOURCE':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      let existingSources = state.all[projectIndex].feedSources || [], updatedSources
      sourceIndex = existingSources.findIndex(s => s.id === action.feedSource.id)
      if (sourceIndex === -1) { // source does not currently; add it
        updatedSources = [
          ...existingSources,
          action.feedSource
        ]
      } else { // existing feedsource array includes this one, replace it
        updatedSources = [
          ...existingSources.slice(0, sourceIndex),
          action.feedSource,
          ...existingSources.slice(sourceIndex + 1)
        ]
      }
      return update(state,
        {all:
          {[projectIndex]:
            {$merge: {feedSources: updatedSources}}
          }
        }
      )

    case 'RECEIVE_FEEDVERSIONS':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedSource.id)
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {$merge: {feedVersions: action.feedVersions}}
              }
            }
          }
        }
      )

    case 'RECEIVE_VALIDATION_RESULT':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedSource.id)
      versionIndex = state.all[projectIndex].feedSources[sourceIndex].feedVersions.findIndex(v => v.id === action.feedVersion.id)
      // let result = {}
      // action.validationResult.map(error => {
      //   if (!result[error.file]) {
      //     result[error.file] = []
      //   }
      //   result[error.file].push(error)
      // })
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {feedVersions:
                  {[versionIndex]:
                    {$merge: {validationResult: action.validationResult}}
                  }
                }
              }
            }
          }
        }
      )
    case 'RECEIVE_FEEDVERSION_ISOCHRONES':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedSource.id)
      versionIndex = state.all[projectIndex].feedSources[sourceIndex].feedVersions.findIndex(v => v.id === action.feedVersion.id)
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {feedVersions:
                  {[versionIndex]:
                    {$merge: {isochrones: action.isochrones}}
                  }
                }
              }
            }
          }
        }
      )

      case 'RECEIVE_DEPLOYMENTS':
        projectIndex = state.all.findIndex(p => p.id === action.projectId)
        if (state.active && action.projectId === state.active.id) {
          return update(state,
          {
            active: {$merge: {deployments: action.deployments}},
            all: {
              [projectIndex]: {$merge: {deployments: action.deployments}}
            }
          })
        } else { // if projectId does not match active project
          return update(state,
            {
              all: {
                [projectIndex]: {$merge: {deployments: action.deployments}}
              }
            }
          )
        }

      case 'RECEIVE_DEPLOYMENT':
        projectIndex = state.all.findIndex(p => p.id === action.deployment.project.id)
        let existingDeployments = state.all[projectIndex].deployments || [], updatedDeployments
        sourceIndex = existingDeployments.findIndex(s => s.id === action.deployment.id)
        if (sourceIndex === -1) { // source does not currently; add it
          updatedDeployments = [
            ...existingDeployments,
            action.deployment
          ]
        } else { // existing feedsource array includes this one, replace it
          updatedDeployments = [
            ...existingDeployments.slice(0, sourceIndex),
            action.deployment,
            ...existingDeployments.slice(sourceIndex + 1)
          ]
        }
        return update(state,
          {all:
            {[projectIndex]:
              {$merge: {deployments: updatedDeployments}}
            }
          }
        )

    case 'RECEIVE_NOTES_FOR_FEEDSOURCE':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedSource.id)
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {$merge: {notes: action.notes}}
              }
            }
          }
        }
      )

    case 'RECEIVE_NOTES_FOR_FEEDVERSION':
      projectIndex = state.all.findIndex(p => p.id === action.feedVersion.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedVersion.feedSource.id)
      versionIndex = state.all[projectIndex].feedSources[sourceIndex].feedVersions.findIndex(v => v.id === action.feedVersion.id)
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {feedVersions:
                  {[versionIndex]:
                    {$merge: {notes: action.notes}}
                  }
                }
              }
            }
          }
        }
      )

    default:
      return state
  }
}

export default projects
<commit_msg>request feed version reducer<commit_after>import update from 'react-addons-update'

const projects = (state = {
  isFetching: false,
  all: null,
  active: null,
  filter: {
    searchText: null
  }
}, action) => {
  let projects, sources, projectIndex, sourceIndex, versionIndex, activeProject, activeIndex, feeds, activeProjectId, project, newState, deployment
  switch (action.type) {
    case 'SET_PROJECT_VISIBILITY_SEARCH_TEXT':
      return update(state, {filter: {searchText: {$set: action.text}}})
    case 'CREATE_PROJECT':
      projects = [{
        isCreating: true,
        name: ''
      }, ...state.all]
      return update(state, { all: { $set: projects }})

    case 'CREATE_FEEDSOURCE':
      projectIndex = state.all.findIndex(p => p.id === action.projectId)
      project = state.all[projectIndex]
      newState = null
      console.log("adding fs to project", state.all[projectIndex]);

      // if project's feedSources array is undefined, add it
      if(!project.feedSources) {
        console.log('adding new fs array');
        newState = update(state, {all: {[projectIndex]: {$merge: {feedSources: []}}}})
      }

      // add new empty feed source to feedSources array
      const feedSource = {
        isCreating: true,
        name: '',
        projectId: project.id
      }
      return update(newState || state, {all: {[projectIndex]: {feedSources: {$unshift: [feedSource]}}}})

    case 'CREATE_DEPLOYMENT':
      projectIndex = state.all.findIndex(p => p.id === action.projectId)
      project = state.all[projectIndex]
      newState = null
      console.log("adding fs to project", state.all[projectIndex]);

      // if project's deployment array is undefined, add it
      if(!project.deployments) {
        console.log('adding new fs array');
        newState = update(state, {all: {[projectIndex]: {$merge: {deployments: []}}}})
      }

      // add new empty feed source to feedSources array
      deployment = {
        isCreating: true,
        name: '',
        project: project
      }
      return update(newState || state, {all: {[projectIndex]: {deployments: {$unshift: [deployment]}}}})

    case 'REQUEST_PROJECTS':
      return update(state, { isFetching: { $set: true }})

    case 'RECEIVE_PROJECTS':
      activeProjectId = state.active ? state.active.id : DT_CONFIG.application.active_project
      activeIndex = action.projects.findIndex(p => p.id === activeProjectId)
      return {
        isFetching: false,
        all: action.projects,
        active: activeIndex !== -1 ? action.projects[activeIndex] : null,
        filter: {
          searchText: null
        }
      }
    case 'SET_ACTIVE_PROJECT':
      return update(state, { active: { $set: action.project }})
    case 'RECEIVE_PROJECT':
      if (!state.all) { // there are no current projects loaded
        projects = [action.project]
      } else { // projects already loaded
        projectIndex = state.all.findIndex(p => p.id === action.project.id)
        if (projectIndex === -1) { // projects loaded but not this one; add it
          projects = [
            ...state.all,
            action.project
          ]
        } else { // projects loaded including this one, replace it
          projects = [
            ...state.all.slice(0, projectIndex),
            action.project,
            ...state.all.slice(projectIndex + 1)
          ]
        }
      }
      activeProjectId = state.active ? state.active.id : DT_CONFIG.application.active_project
      activeProject = action.project.id === activeProjectId ? action.project : null
      if (state.active && !activeProject) { // active project already exists and received project does not match active project
        activeProject = state.active
      }
      return update(state, {active: { $set: activeProject }, all: { $set: projects }})

    case 'RECEIVE_FEEDSOURCES':
      projectIndex = state.all.findIndex(p => p.id === action.projectId)
      if (state.active && action.projectId === state.active.id) {
        return update(state,
        {
          active: {$merge: {feedSources: action.feedSources}},
          all: {
            [projectIndex]: {$merge: {feedSources: action.feedSources}}
          }
        })
      } else { // if projectId does not match active project
        return update(state,
          {
            all: {
              [projectIndex]: {$merge: {feedSources: action.feedSources}}
            }
          }
        )
      }

    case 'RECEIVE_FEEDSOURCE':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      let existingSources = state.all[projectIndex].feedSources || [], updatedSources
      sourceIndex = existingSources.findIndex(s => s.id === action.feedSource.id)
      if (sourceIndex === -1) { // source does not currently; add it
        updatedSources = [
          ...existingSources,
          action.feedSource
        ]
      } else { // existing feedsource array includes this one, replace it
        updatedSources = [
          ...existingSources.slice(0, sourceIndex),
          action.feedSource,
          ...existingSources.slice(sourceIndex + 1)
        ]
      }
      return update(state,
        {all:
          {[projectIndex]:
            {$merge: {feedSources: updatedSources}}
          }
        }
      )

    case 'RECEIVE_FEEDVERSIONS':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedSource.id)
      let versionSort = (a, b) => {
        if(a.version < b.version) return -1
        if(a.version > b.version) return 1
        return 0
      }
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {$merge: {feedVersions: action.feedVersions.sort(versionSort)}}
              }
            }
          }
        }
      )

    case 'RECEIVE_FEEDVERSION':
      projectIndex = state.all.findIndex(p => p.id === action.feedVersion.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedVersion.feedSource.id)
      console.log(sourceIndex)
      versionIndex = state.all[projectIndex].feedSources[sourceIndex].feedVersions
        ? state.all[projectIndex].feedSources[sourceIndex].feedVersions.findIndex(v => v.id === action.feedVersion.id)
        : -1
      let existingVersions = state.all[projectIndex].feedSources[sourceIndex].feedVersions || [], updatedVersions
      if (versionIndex === -1) { // version does not currently; add it
        updatedVersions = [
          ...existingVersions,
          action.feedVersion
        ]
      } else { // existing feedversion array includes this one, replace it
        updatedVersions = [
          ...existingVersions.slice(0, versionIndex),
          action.feedVersion,
          ...existingVersions.slice(versionIndex + 1)
        ]
      }
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {$merge: {feedVersions: updatedVersions}}
              }
            }
          }
        }
      )

    case 'RECEIVE_VALIDATION_RESULT':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedSource.id)
      versionIndex = state.all[projectIndex].feedSources[sourceIndex].feedVersions.findIndex(v => v.id === action.feedVersion.id)
      // let result = {}
      // action.validationResult.map(error => {
      //   if (!result[error.file]) {
      //     result[error.file] = []
      //   }
      //   result[error.file].push(error)
      // })
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {feedVersions:
                  {[versionIndex]:
                    {$merge: {validationResult: action.validationResult}}
                  }
                }
              }
            }
          }
        }
      )
    case 'RECEIVE_FEEDVERSION_ISOCHRONES':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedSource.id)
      versionIndex = state.all[projectIndex].feedSources[sourceIndex].feedVersions.findIndex(v => v.id === action.feedVersion.id)
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {feedVersions:
                  {[versionIndex]:
                    {$merge: {isochrones: action.isochrones}}
                  }
                }
              }
            }
          }
        }
      )

      case 'RECEIVE_DEPLOYMENTS':
        projectIndex = state.all.findIndex(p => p.id === action.projectId)
        if (state.active && action.projectId === state.active.id) {
          return update(state,
          {
            active: {$merge: {deployments: action.deployments}},
            all: {
              [projectIndex]: {$merge: {deployments: action.deployments}}
            }
          })
        } else { // if projectId does not match active project
          return update(state,
            {
              all: {
                [projectIndex]: {$merge: {deployments: action.deployments}}
              }
            }
          )
        }

      case 'RECEIVE_DEPLOYMENT':
        projectIndex = state.all.findIndex(p => p.id === action.deployment.project.id)
        let existingDeployments = state.all[projectIndex].deployments || [], updatedDeployments
        sourceIndex = existingDeployments.findIndex(s => s.id === action.deployment.id)
        if (sourceIndex === -1) { // source does not currently; add it
          updatedDeployments = [
            ...existingDeployments,
            action.deployment
          ]
        } else { // existing feedsource array includes this one, replace it
          updatedDeployments = [
            ...existingDeployments.slice(0, sourceIndex),
            action.deployment,
            ...existingDeployments.slice(sourceIndex + 1)
          ]
        }
        return update(state,
          {all:
            {[projectIndex]:
              {$merge: {deployments: updatedDeployments}}
            }
          }
        )

    case 'RECEIVE_NOTES_FOR_FEEDSOURCE':
      projectIndex = state.all.findIndex(p => p.id === action.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedSource.id)
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {$merge: {notes: action.notes}}
              }
            }
          }
        }
      )

    case 'RECEIVE_NOTES_FOR_FEEDVERSION':
      projectIndex = state.all.findIndex(p => p.id === action.feedVersion.feedSource.projectId)
      sourceIndex = state.all[projectIndex].feedSources.findIndex(s => s.id === action.feedVersion.feedSource.id)
      versionIndex = state.all[projectIndex].feedSources[sourceIndex].feedVersions.findIndex(v => v.id === action.feedVersion.id)
      return update(state,
        {all:
          {[projectIndex]:
            {feedSources:
              {[sourceIndex]:
                {feedVersions:
                  {[versionIndex]:
                    {$merge: {notes: action.notes}}
                  }
                }
              }
            }
          }
        }
      )

    default:
      return state
  }
}

export default projects
<|endoftext|>


<commit_before>'use strict';

// Call this function when the page loads (the "ready" event)
$(document).ready(function() {
	$.slidebars();
    $('#hamburger').load('static/hamburger.html');
	initializePage();
})

/*
 * Function that is called when the document is ready.
 */
function initializePage() {
	$('#submitBtn').click(function(e) {
		// console.log('clicked');
		var description = $('#addPostForm #description').val();
		var location = $('#addPostForm #location').val();
		// var date = $('#addPostForm #date').val();
		// var summary = $('#new-project-form #summary').val();
		var json = {
			'post_description': title,
			'location': location
		};
		$.post('/add', json, function() {
			window.location.href = '/most_recent'; // reload the page
		});
	});

  $(".version_a").click(function(){
    //add your Woopra tracking code for version A's like button click event
    woopra.track("a_version_feature1_click");
  })

  $(".version_b").click(function(){
    //add your Woopra tracking code for version A's like button click event
    woopra.track("b_version_feature1_click");
  })
}<commit_msg>wooooopra<commit_after>'use strict';

// Call this function when the page loads (the "ready" event)
$(document).ready(function() {
	$.slidebars();
    $('#hamburger').load('static/hamburger.html');
	initializePage();
})

/*
 * Function that is called when the document is ready.
 */
function initializePage() {
	$('#submitBtn').click(function(e) {
		// console.log('clicked');
		var description = $('#addPostForm #description').val();
		var location = $('#addPostForm #location').val();
		// var date = $('#addPostForm #date').val();
		// var summary = $('#new-project-form #summary').val();
		var json = {
			'post_description': title,
			'location': location
		};
		$.post('/add', json, function() {
			window.location.href = '/most_recent'; // reload the page
		});
	});

  $(".version_a").click(function(){
    //add your Woopra tracking code for version A's like button click event
    woopra.track("a_version_feature1_click");
  });

  $(".version_b").click(function(){
    //add your Woopra tracking code for version A's like button click event
    woopra.track("b_version_feature1_click");
  });
}<|endoftext|>


<commit_before>let updateID;

$(document).ready(() => {
  $('#newDialog').dialog({
    title: 'Add New Todo',
    autoOpen: false,
    modal: true,
    show: {
      effect: 'blind',
      duration: 1000
    },
    hide: {
      effect: 'blind',
      duration: 1000
    },
    buttons: [{
      text: 'Add',
      click: function() {

        let data = $('#new-form-data').serialize();
        postNewTodo(data)
        $(this).dialog('close')
      }
    }]
  });

  $('#updateDialog').dialog({
    title: 'Update Todo',
    autoOpen: false,
    modal: true,
    show: {
      effect: 'blind',
      duration: 1000
    },
    hide: {
      effect: 'blind',
      duration: 1000
    },
    buttons: [{
      text: 'Update',
      click: function() {
        let data = $('#update-form-data').serialize();
        updateTodo(updateID, data)
        $(this).dialog('close')
      }
    }]
  });

  $('#opener').click(() => {
    $('#newDesc').val('')
    $('#newDialog').dialog('open');
  })

// Click listener for todo items
  $('ul').click(() => {
    var target = $(event.target)
    // console.log(target)
    if (target.hasClass('list-item')) {
      target.toggleClass('completed')
    } else if (target.hasClass('fa-trash-o')) {
      var id = target[0].closest('li').id
      deleteTodo(id)
    } else if (target[0].className == 'fa fa-pencil') {
      var description = target[0].closest('li').innerText
      updateID = target[0].closest('li').id
      $('#updateDialog').dialog('open')
      $('#updDesc').val(description)
    }
  })
})

const postNewTodo = (data) => {
  $.post({
    url: 'http://localhost:3000/api/todos',
    data: data,
    dataType: 'json',
    headers: {
      'Content-Type':'application/json'
    }
  })
  .done((response) => {
    const html = `

    ${response.description}
`
    $(html).hide().appendTo('ul').fadeIn(1000);
  })
  .fail((err) => {
    console.log(`It failed ${err.message}`)
  })
}

const deleteTodo = (id) => {
  $.ajax({
    url: `http://localhost:3000/api/todos/${id}`,
    type: 'delete',
    headers: {
      'Content-Type':'application/json'
    }
  })
  .done((response) => {
    $(document.getElementById(id)).fadeOut(500, () => {
      $(this).remove()
    })
  })
  .fail(err => console.log(err))
}

const updateTodo = (id, data) => {
  $.ajax({
    url: `http://localhost:3000/api/todos/${id}`,
    type: 'put',
    data: data,
    dataType: 'json'
    headers: {
      'Content-Type':'application/json'
    }
  })
  .done((response) => {
    $(document.getElementById(id))[0].childNodes[1].nodeValue = response.description
  })
  .fail(err => console.log(err))
}
<commit_msg>Fix typo<commit_after>let updateID;

$(document).ready(() => {
  $('#newDialog').dialog({
    title: 'Add New Todo',
    autoOpen: false,
    modal: true,
    show: {
      effect: 'blind',
      duration: 1000
    },
    hide: {
      effect: 'blind',
      duration: 1000
    },
    buttons: [{
      text: 'Add',
      click: function() {

        let data = $('#new-form-data').serialize();
        postNewTodo(data)
        $(this).dialog('close')
      }
    }]
  });

  $('#updateDialog').dialog({
    title: 'Update Todo',
    autoOpen: false,
    modal: true,
    show: {
      effect: 'blind',
      duration: 1000
    },
    hide: {
      effect: 'blind',
      duration: 1000
    },
    buttons: [{
      text: 'Update',
      click: function() {
        let data = $('#update-form-data').serialize();
        updateTodo(updateID, data)
        $(this).dialog('close')
      }
    }]
  });

  $('#opener').click(() => {
    $('#newDesc').val('')
    $('#newDialog').dialog('open');
  })

// Click listener for todo items
  $('ul').click(() => {
    var target = $(event.target)
    // console.log(target)
    if (target.hasClass('list-item')) {
      target.toggleClass('completed')
    } else if (target.hasClass('fa-trash-o')) {
      var id = target[0].closest('li').id
      deleteTodo(id)
    } else if (target[0].className == 'fa fa-pencil') {
      var description = target[0].closest('li').innerText
      updateID = target[0].closest('li').id
      $('#updateDialog').dialog('open')
      $('#updDesc').val(description)
    }
  })
})

const postNewTodo = (data) => {
  $.post({
    url: 'http://localhost:3000/api/todos',
    data: data,
    dataType: 'json',
    headers: {
      'Content-Type':'application/json'
    }
  })
  .done((response) => {
    const html = `

    ${response.description}
`
    $(html).hide().appendTo('ul').fadeIn(1000);
  })
  .fail((err) => {
    console.log(`It failed ${err.message}`)
  })
}

const deleteTodo = (id) => {
  $.ajax({
    url: `http://localhost:3000/api/todos/${id}`,
    type: 'delete',
    headers: {
      'Content-Type':'application/json'
    }
  })
  .done((response) => {
    $(document.getElementById(id)).fadeOut(500, () => {
      $(this).remove()
    })
  })
  .fail(err => console.log(err))
}

const updateTodo = (id, data) => {
  $.ajax({
    url: `http://localhost:3000/api/todos/${id}`,
    type: 'put',
    data: data,
    dataType: 'json',
    headers: {
      'Content-Type':'application/json'
    }
  })
  .done((response) => {
    $(document.getElementById(id))[0].childNodes[1].nodeValue = response.description
  })
  .fail(err => console.log(err))
}
<|endoftext|>


<commit_before>define([
    'preact',
    'htm',

    'bootstrap'
], (
    preact,
    htm
) => {
    'use strict';

    const {h, Component, Fragment } = preact;
    const html = htm.bind(h);

    const REDIRECT_IF_FOUND = true;
    const DOCS_HOST = 'docs.kbase.us';
    const MARKETING_HOST = 'www.kbase.us';

    const TRY_UPSTREAM_SITES = true;

    class NotFound extends Component {
        constructor(props) {
            super(props);
            this.state = {
                status: 'none',
                messages: []
            };
        }

        async findOn(site, path) {
            const tryURI = `/__poke/${site}/${path}`;
            const response = await fetch(tryURI, {
                method: 'HEAD',
                mode: 'cors'
            });
            if (response.status >=200 && response.status <= 300) {
                return true;
            }
            return false;
        }

        redirect(url) {
            window.location.assign(url);
        }

        async setState2(newState) {
            return new Promise((resolve) => {
                this.setState(newState, () => {
                    resolve();
                });
            });
        }

        async componentDidMount() {

            const request = this.props.params.request;
            if (!TRY_UPSTREAM_SITES) {
                console.warn('not trying upstream sites', request);
                if (request.realPath.length === 1 &&
                    request.realPath[0] === '' &&
                    request.path.length === 0) {
                    // if we got here with no paths, go to the dashboard
                    window.location.hash = '#dashboard';
                    return
                }

                if (request.path.length > 0) {
                    this.setState({
                        status: 'path-does-not-exist',
                        path: request.path.join('/')
                    });
                } else {
                    this.setState({
                        status: 'does-not-exist',
                        path: request.realPath.join('/')
                    });
                }
                return;
            }

            if (request.realPath.length === 1 &&
                request.realPath[0] === '' &&
                request.path.length === 0 &&
                !this.props.runtime.service('session').isAuthenticated()) {
                this.props.runtime.send('ui', 'setTitle', 'Redirecting to Homepage...');
                this.redirect(`https://${MARKETING_HOST}`);
                return;
            }

            const path = request.realPath.join('/');
            try {
                if (path.length === 0) {
                    this.setState({
                        status: 'path-does-not-exist',
                        path: request.path.join('/')
                    });
                    return;
                }

                // Try homepage/marketing
                await this.setState2({
                    messages: [...this.state.messages, 'Looking on Homepage...']
                });
                if (await this.findOn('marketing', path)) {
                    this.setState({
                        status: 'found-on-marketing',
                        path
                    });
                    return;
                }
                await this.setState2({
                    messages: [...this.state.messages.slice(0, -1), this.state.messages[this.state.messages.length -1] + 'nope']
                });

                // Try docs
                await this.setState2({
                    messages: [...this.state.messages, 'Looking on Docs...']
                });
                if (await this.findOn('docs', path)) {
                    this.setState({
                        status: 'found-on-docs',
                        path
                    });
                    return;
                }
                await this.setState2({
                    messages: [...this.state.messages.slice(0, -1), this.state.messages[this.state.messages.length -1] + 'nope']
                });

                this.setState({
                    status: 'does-not-exist',
                    path
                });
            } catch (ex) {
                this.setState({
                    status: 'error',
                    error: {
                        message: ex.message
                    },
                    path
                });
            }
        }

        renderNotFound() {
            this.props.runtime.send('ui', 'setTitle', `Not Found - ${this.state.path}`);
            return html`

                                Sorry, "${this.state.path}" was not found.

                            ${this.renderKBaseLinks()}

            `;
        }

        renderPathNotFound() {
            this.props.runtime.send('ui', 'setTitle', `Path Not Found - ${this.state.path}`);
            return html`

                                Sorry, "#${this.state.path}" was not found.

                            ${this.renderKBaseLinks()}

            `;
        }

        renderExistsOnMarketingSite() {
            const marketingURL = new URL(`https://${MARKETING_HOST}/${this.state.path}`);
            const query = marketingURL.searchParams;
            Object.entries(this.props.params.request.query).forEach(([key, value]) => {
                query.set(key, value);
            });

            if (REDIRECT_IF_FOUND) {
                this.props.runtime.send('ui', 'setTitle', `Redirecting to ${marketingURL}`);
                this.redirect(marketingURL.toString());
                return;
            }

            this.props.runtime.send('ui', 'setTitle', 'Path Not Found');

            return html`

                        ${' '}Path Not Found

                        The path you requested, "${this.state.path}", was not found on this site.

                        However, it does exist on the KBase Homepage Site.

            `;
        }

        renderExistsOnOutreachSite() {
            const marketingURL = new URL(`https://${MARKETING_HOST}/${this.state.path}`);
            const query = marketingURL.searchParams;
            Object.entries(this.props.params.request.query).forEach(([key, value]) => {
                query.set(key, value);
            });

            if (REDIRECT_IF_FOUND) {
                this.props.runtime.send('ui', 'setTitle', `Redirecting to ${marketingURL}`);
                this.redirect(marketingURL.toString());
                return;
            }

            this.props.runtime.send('ui', 'setTitle', 'Path Not Found');

            return html`

                        ${' '}Path Not Found

                        The path you requested, "${this.state.path}", was not found on this site.

                        However, it does exist on the KBase Homepage Site.

            `;
        }

        renderExistsOnDocsSite() {
            const docsURL = new URL(`https://${DOCS_HOST}/${this.state.path}`);
            const query = docsURL.searchParams;
            Object.entries(this.props.params.request.query).forEach(([key, value]) => {
                query.set(key, value);
            });

            if (REDIRECT_IF_FOUND) {
                this.props.runtime.send('ui', 'setTitle', `Redirecting to ${docsURL}`);
                this.redirect(docsURL.toString());
                return;
            }

            this.props.runtime.send('ui', 'setTitle', 'Path Not Found');

            return html`

                        ${' '}Path Not Found

                        The path you requested, "${this.state.path}", was not found on this site.

                        However, it does exist on the KBase Documentation Site.

            `;
        }

        renderKBaseLinks() {
            return html`
                <${Fragment}>

                        You may find what you are looking for on one of the following KBase sites:

Homepage

Documentation

Narrative

Dashboard

                        Or you may wish to reach out the KBase for further assistance.

                <//>
            `;
        }

        renderError() {
            this.props.runtime.send('ui', 'setTitle', `Not Found - ${this.state.path}`);
            return html`

                                Sorry, "${this.state.path}" was not found. *

                            ${this.renderKBaseLinks()}

                                * Actually, an error was encountered checking for this path: "${this.state.error.message}"

            `;
        }

        renderLoading() {
            const path = this.props.params.request.realPath.join('/');
            this.props.runtime.send('ui', 'setTitle', `Not Found - ${path}`);
            const messages = this.state.messages.map((message) => {
                return html`

${message}

                `;
            })
            return html`

Analyzing request...

                    ${messages}

            `;
            return;
        }

        renderSwitch() {
            switch (this.state.status) {
                case 'none':
                    return this.renderLoading();
                case 'does-not-exist':
                    return this.renderNotFound();
                case 'path-does-not-exist':
                    return this.renderPathNotFound();
                case 'found-on-marketing':
                    return this.renderExistsOnMarketingSite();
                case 'found-on-outreach':
                    return this.renderExistsOnOutreachSite();
                case 'found-on-docs':
                    return this.renderExistsOnDocsSite();
                case 'error':
                    return this.renderError();
                }
        }

        render() {
            return html`

                ${this.renderSwitch()}

            `;
        }
    }

    return NotFound;
});<commit_msg>home page and documentation should open a new tab or window<commit_after>define([
    'preact',
    'htm',

    'bootstrap'
], (
    preact,
    htm
) => {
    'use strict';

    const {h, Component, Fragment } = preact;
    const html = htm.bind(h);

    const REDIRECT_IF_FOUND = true;
    const DOCS_HOST = 'docs.kbase.us';
    const MARKETING_HOST = 'www.kbase.us';

    const TRY_UPSTREAM_SITES = true;

    class NotFound extends Component {
        constructor(props) {
            super(props);
            this.state = {
                status: 'none',
                messages: []
            };
        }

        async findOn(site, path) {
            const tryURI = `/__poke/${site}/${path}`;
            const response = await fetch(tryURI, {
                method: 'HEAD',
                mode: 'cors'
            });
            if (response.status >=200 && response.status <= 300) {
                return true;
            }
            return false;
        }

        redirect(url) {
            window.location.assign(url);
        }

        async setState2(newState) {
            return new Promise((resolve) => {
                this.setState(newState, () => {
                    resolve();
                });
            });
        }

        async componentDidMount() {

            const request = this.props.params.request;
            if (!TRY_UPSTREAM_SITES) {
                console.warn('not trying upstream sites', request);
                if (request.realPath.length === 1 &&
                    request.realPath[0] === '' &&
                    request.path.length === 0) {
                    // if we got here with no paths, go to the dashboard
                    window.location.hash = '#dashboard';
                    return
                }

                if (request.path.length > 0) {
                    this.setState({
                        status: 'path-does-not-exist',
                        path: request.path.join('/')
                    });
                } else {
                    this.setState({
                        status: 'does-not-exist',
                        path: request.realPath.join('/')
                    });
                }
                return;
            }

            if (request.realPath.length === 1 &&
                request.realPath[0] === '' &&
                request.path.length === 0 &&
                !this.props.runtime.service('session').isAuthenticated()) {
                this.props.runtime.send('ui', 'setTitle', 'Redirecting to Homepage...');
                this.redirect(`https://${MARKETING_HOST}`);
                return;
            }

            const path = request.realPath.join('/');
            try {
                if (path.length === 0) {
                    this.setState({
                        status: 'path-does-not-exist',
                        path: request.path.join('/')
                    });
                    return;
                }

                // Try homepage/marketing
                await this.setState2({
                    messages: [...this.state.messages, 'Looking on Homepage...']
                });
                if (await this.findOn('marketing', path)) {
                    this.setState({
                        status: 'found-on-marketing',
                        path
                    });
                    return;
                }
                await this.setState2({
                    messages: [...this.state.messages.slice(0, -1), this.state.messages[this.state.messages.length -1] + 'nope']
                });

                // Try docs
                await this.setState2({
                    messages: [...this.state.messages, 'Looking on Docs...']
                });
                if (await this.findOn('docs', path)) {
                    this.setState({
                        status: 'found-on-docs',
                        path
                    });
                    return;
                }
                await this.setState2({
                    messages: [...this.state.messages.slice(0, -1), this.state.messages[this.state.messages.length -1] + 'nope']
                });

                this.setState({
                    status: 'does-not-exist',
                    path
                });
            } catch (ex) {
                this.setState({
                    status: 'error',
                    error: {
                        message: ex.message
                    },
                    path
                });
            }
        }

        renderNotFound() {
            this.props.runtime.send('ui', 'setTitle', `Not Found - ${this.state.path}`);
            return html`

                                Sorry, "${this.state.path}" was not found.

                            ${this.renderKBaseLinks()}

            `;
        }

        renderPathNotFound() {
            this.props.runtime.send('ui', 'setTitle', `Path Not Found - ${this.state.path}`);
            return html`

                                Sorry, "#${this.state.path}" was not found.

                            ${this.renderKBaseLinks()}

            `;
        }

        renderExistsOnMarketingSite() {
            const marketingURL = new URL(`https://${MARKETING_HOST}/${this.state.path}`);
            const query = marketingURL.searchParams;
            Object.entries(this.props.params.request.query).forEach(([key, value]) => {
                query.set(key, value);
            });

            if (REDIRECT_IF_FOUND) {
                this.props.runtime.send('ui', 'setTitle', `Redirecting to ${marketingURL}`);
                this.redirect(marketingURL.toString());
                return;
            }

            this.props.runtime.send('ui', 'setTitle', 'Path Not Found');

            return html`

                        ${' '}Path Not Found

                        The path you requested, "${this.state.path}", was not found on this site.

                        However, it does exist on the KBase Homepage Site.

            `;
        }

        renderExistsOnOutreachSite() {
            const marketingURL = new URL(`https://${MARKETING_HOST}/${this.state.path}`);
            const query = marketingURL.searchParams;
            Object.entries(this.props.params.request.query).forEach(([key, value]) => {
                query.set(key, value);
            });

            if (REDIRECT_IF_FOUND) {
                this.props.runtime.send('ui', 'setTitle', `Redirecting to ${marketingURL}`);
                this.redirect(marketingURL.toString());
                return;
            }

            this.props.runtime.send('ui', 'setTitle', 'Path Not Found');

            return html`

                        ${' '}Path Not Found

                        The path you requested, "${this.state.path}", was not found on this site.

                        However, it does exist on the KBase Homepage Site.

            `;
        }

        renderExistsOnDocsSite() {
            const docsURL = new URL(`https://${DOCS_HOST}/${this.state.path}`);
            const query = docsURL.searchParams;
            Object.entries(this.props.params.request.query).forEach(([key, value]) => {
                query.set(key, value);
            });

            if (REDIRECT_IF_FOUND) {
                this.props.runtime.send('ui', 'setTitle', `Redirecting to ${docsURL}`);
                this.redirect(docsURL.toString());
                return;
            }

            this.props.runtime.send('ui', 'setTitle', 'Path Not Found');

            return html`

                        ${' '}Path Not Found

                        The path you requested, "${this.state.path}", was not found on this site.

                        However, it does exist on the KBase Documentation Site.

            `;
        }

        renderKBaseLinks() {
            return html`
                <${Fragment}>

                        You may find what you are looking for on one of the following KBase sites:

Homepage

Documentation

Narrative

Dashboard

                        Or you may wish to reach out the KBase for further assistance.

                <//>
            `;
        }

        renderError() {
            this.props.runtime.send('ui', 'setTitle', `Not Found - ${this.state.path}`);
            return html`

                                Sorry, "${this.state.path}" was not found. *

                            ${this.renderKBaseLinks()}

                                * Actually, an error was encountered checking for this path: "${this.state.error.message}"

            `;
        }

        renderLoading() {
            const path = this.props.params.request.realPath.join('/');
            this.props.runtime.send('ui', 'setTitle', `Not Found - ${path}`);
            const messages = this.state.messages.map((message) => {
                return html`

${message}

                `;
            })
            return html`

Analyzing request...

                    ${messages}

            `;
            return;
        }

        renderSwitch() {
            switch (this.state.status) {
                case 'none':
                    return this.renderLoading();
                case 'does-not-exist':
                    return this.renderNotFound();
                case 'path-does-not-exist':
                    return this.renderPathNotFound();
                case 'found-on-marketing':
                    return this.renderExistsOnMarketingSite();
                case 'found-on-outreach':
                    return this.renderExistsOnOutreachSite();
                case 'found-on-docs':
                    return this.renderExistsOnDocsSite();
                case 'error':
                    return this.renderError();
                }
        }

        render() {
            return html`

                ${this.renderSwitch()}

            `;
        }
    }

    return NotFound;
});<|endoftext|>


<commit_before>/**
 *@fileoverview Implementation of code generating engine
 *@author Raghav Dua
 */

'use strict';

function getDefaultOptions () {
	return {
		format: {
			indent: {
				style: '\t',
				base: 0
			},
			newline: '\n',
			space: ' ',
			quotes: 'single',
			minify: false
		}
	};
}

function getMinifyOptions () {
	return {
		format: {
			indent: {
				style: '',
				base: 0
			},
			newline: '',
			space: ' ',
			quotes: 'single',
			minify: true
		}
	};
}

function isStatement (node) {
	return CodeGenerator.Statement.hasOwnProperty (node.type);
}

function isExpression (node) {
	return CodeGenerator.Expression.hasOwnProperty (node.type);
}

function mergeObjects (target, source) {
	Object.keys (source).forEach (function (key) {
		target [key] = source [key];
	});

	return target;
}

function repeatString (str, times) {
	return Array (times+1).join (str);
}

function fillGapsDeeply (defaultOpts, opts) {
	var options = {};

	Object.keys (defaultOpts).forEach (function (key) {
 		var defOpt = defaultOpts [key];

 		if (typeof defOpt === 'object') {
 			options [key] = fillGapsDeeply (defOpt, opts [key] || {})
 		} else {
 			options [key] = opts [key] || defOpt;
 		}
 	});

 	return options;
}

var CodeGenerator = function CodeGenerator () {
	if (!(this instanceof CodeGenerator)) {
		return new CodeGenerator ();
	}
}

CodeGenerator.prototype.init = function (config) {
	var format = config.format;

	this._indent = repeatString (format.indent.style, format.indent.base);
	this._space = format.space;
	this._lineBreak = format.newline;

	switch (format.quotes) {
		case 'single':
			this._quote = '\'';
			break;
		case 'double':
			this._quote = '\"';
			break;
		default:
			throw new Error ('Invalid value specified for quotes (use \'single\' or \'double\')');
	}
};

CodeGenerator.prototype.generateStatement = function (node) {
	return this.Statement [node.type] (node);
};

CodeGenerator.prototype.generateExpression = function (node) {
	return this.Expression [node.type] (node);
};

CodeGenerator.prototype.generate = function (node) {
	if (isStatement (node)) {
		return this.generateStatement (node);
	}
	if (isExpression (node)) {
		return this.generateExpression (node);
	}

	throw new Error ('Unknown node type: ' + node.type);
};

CodeGenerator.Statement = {

};

mergeObjects (CodeGenerator.prototype, CodeGenerator.Statement);

CodeGenerator.Expression = {

};

mergeObjects (CodeGenerator.prototype, CodeGenerator.Expression);

module.exports = function (node, options) {
	var defaultOptions = options.format.minify ? getMinifyOptions () : getDefaultOptions (),
		sourceCode;

 	//make sure any un-specified options are set to their default values
 	options = fillGapsDeeply (defaultOptions, options);
 	sourceCode = new CodeGenerator ()
		.init (options)
		.generate (node);

 	return sourceCode;
};<commit_msg>Statements & Expressions (func declarations)<commit_after>/**
 *@fileoverview Implementation of code generating engine
 *@author Raghav Dua
 */

'use strict';

function getDefaultOptions () {
	return {
		format: {
			indent: {
				style: '\t',
				base: 0
			},
			newline: '\n',
			space: ' ',
			quotes: 'single',
			minify: false
		}
	};
}

function getMinifyOptions () {
	return {
		format: {
			indent: {
				style: '',
				base: 0
			},
			newline: '',
			space: ' ',
			quotes: 'single',
			minify: true
		}
	};
}

function isStatement (node) {
	return CodeGenerator.Statement.hasOwnProperty (node.type);
}

function isExpression (node) {
	return CodeGenerator.Expression.hasOwnProperty (node.type);
}

function mergeObjects (target, source) {
	Object.keys (source).forEach (function (key) {
		target [key] = source [key];
	});

	return target;
}

function repeatString (str, times) {
	return Array (times+1).join (str);
}

function fillGapsDeeply (defaultOpts, opts) {
	var options = {};

	Object.keys (defaultOpts).forEach (function (key) {
 		var defOpt = defaultOpts [key];

 		if (typeof defOpt === 'object') {
 			options [key] = fillGapsDeeply (defOpt, opts [key] || {})
 		} else {
 			options [key] = opts [key] || defOpt;
 		}
 	});

 	return options;
}

var CodeGenerator = function CodeGenerator () {
	if (!(this instanceof CodeGenerator)) {
		return new CodeGenerator ();
	}
}

CodeGenerator.prototype.init = function (config) {
	var format = config.format;

	this._indent = repeatString (format.indent.style, format.indent.base);
	this._space = format.space;
	this._lineBreak = format.newline;

	switch (format.quotes) {
		case 'single':
			this._quote = '\'';
			break;
		case 'double':
			this._quote = '\"';
			break;
		default:
			throw new Error ('Invalid value specified for quotes (use \'single\' or \'double\')');
	}
};

CodeGenerator.prototype.generateStatement = function (node) {
	return this.Statement [node.type] (node);
};

CodeGenerator.prototype.generateExpression = function (node) {
	return this.Expression [node.type] (node);
};

CodeGenerator.prototype.generate = function (node) {
	if (isStatement (node)) {
		return this.generateStatement (node);
	}
	if (isExpression (node)) {
		return this.generateExpression (node);
	}

	throw new Error ('Unknown node type: ' + node.type);
};

CodeGenerator.Statement = {
	BlockStatement: function (node) {},
	VariableDeclaration: function (node) {},
	VariableDeclarator: function (node) {},
	EmptyStatement: function (node) {},
	ExpressionStatement: function (node) {},
	IfStatement: function (node) {},
	ImportStatement: function (node) {},
	Symbol: function (node) {},
	DoWhileStatement: function (node) {},
	WhileStatement: function (node) {},
	ForStatement: function (node) {},
	ForInStatement: function (node) {},
	ContinueStatement: function (node) {},
	BreakStatement: function (node) {},
	ReturnStatement: function (node) {},
	WithStatement: function (node) {},
	SwitchStatement: function (node) {},
	SwitchCase: function (node) {},
	LabeledStatement: function (node) {},
	ThrowStatement: function (node) {},
	TryStatement: function (node) {},
	CatchClause: function (node) {},
	DebuggerStatement: function (node) {},
	ContractStatement: function (node) {},
	LibraryStatement: function (node) {},
	IsStatement: function (node) {},
	EventDeclaration: function (node) {},
	ModifierDeclaration: function (node) {},
	FunctionDeclaration: function (node) {},
	FunctionName: function (node) {},
	ModifierName: function (node) {},
	InformalParameter: function (node) {},
	EnumDeclaration: function (node) {},
	StructDeclaration: function (node) {},
	DeclarativeExpressionList: function (node) {},
	Program: function (node) {}
};

mergeObjects (CodeGenerator.prototype, CodeGenerator.Statement);

CodeGenerator.Expression = {
	ThisExpression: function (node) {},
	ArrayExpression: function (node) {},
	ObjectExpression: function (node) {},
	NewExpression: function (node) {},
	MemberExpression: function (node) {},
	CallExpression: function (node) {},
	Type: function (node) {},
	DeclarativeExpression: function (node) {},
	MappingExpression: function (node) {},
	UpdateExpression: function (node) {},
	ConditionalExpression: function (node) {},
	AssignmentExpression: function (node) {},
	SequenceExpression: function (node) {}
};

mergeObjects (CodeGenerator.prototype, CodeGenerator.Expression);

module.exports = function (node, options) {
	var defaultOptions = options.format.minify ? getMinifyOptions () : getDefaultOptions (),
		sourceCode;

 	//make sure any un-specified options are set to their default values
 	options = fillGapsDeeply (defaultOptions, options);
 	sourceCode = new CodeGenerator ()
		.init (options)
		.generate (node);

 	return sourceCode;
};<|endoftext|>


<commit_before>/**
 * Common utility values and functions for jsSART
 */

// Reuseable stimuli
// ------------------------

// HTML for text plugin
var spacebar_html = "<SPACEBAR>";
var continue_html = "
Press the " + spacebar_html + " to continue.
";

// fixation stimulus
var fixation_cross_path = "../img/fixation-cross.png";
var fixation_trial = {
  type: 'single-stim',
  stimulus: [fixation_cross_path],
  timing_stim: jsSART.TIMING_STIM_DISPLAY[1],
  timing_response: jsSART.TIMING_STIM_DISPLAY[1],
  timing_post_trial: 0
};

// Functions
// ------------------------

// sum a list of values
function sum(list) {
  return _.reduce(list, function(memo, num){ return memo + num; });
}

// get url parameters
function getUrlParams() {
  var url_params = window.location.search.slice(1);
  return $.deparam(url_params);
}

// try to get a participant ID
function getParticipantId() {
  var pid;

  // first attempt to get PID via URL params
  params = getUrlParams();
  pid = params.pid;

  // next, get PID via window prompt
  pid = pid || window.prompt("Please enter a participant ID.");

  // as a last resort, use 99999 with 5-digit random integer appended
  pid = pid || "99999" + _.random(10000, 99999);

  return pid;
}

// create a 'text' plugin block with some defaults
function createTextBlock(text_html) {
  return {
    type: "text",
    text: text_html + continue_html,
    cont_key: [32, 13]
  };
}

// add results data to the last trial
function addTrialResults(trial_data, extra_data) {
  extra_data = extra_data || {};
  var expected, response, correct;

  var trial_stimulus = JSON.parse(trial_data.stimulus);
  var stimulus_text = $(trial_stimulus[0]).text();
  var stimulus = parseInt(stimulus_text);

  // expected (correct) response for the last trial
  if (stimulus === jsSART.STIMULI.NO_GO_VALUE) {
    expected = false;
  } else {
    expected = true;
  }

  // check whether an expected key was pressed
  var key_press = JSON.parse(trial_data.key_press);
  response = _.contains(jsSART.STIMULI.ALLOW_KEYCODES, key_press[0]);

  // was the response given as expected (correct)?
  correct = (expected === response) ? true : false;

  var trial_results = $.extend({
    expected: expected,
    response: response,
    correct: correct
  }, extra_data);  // merge with given data

  return trial_results;
}

// display trial feedback, based on response judgement
function displayTrialFeedback(data) {
  if (typeof data.correct !== "undefined") {
    var feedback_text = data.correct ? "Correct!" : "Incorrect";
    var feedback_class = data.correct ? "correct" : "incorrect";
    var feedback_html = '
'+feedback_text+'
';

    // show feedback
    $('#jspsych-feedback').html(feedback_html);
    // hide feedback
    window.setTimeout(function() {
      $('#jspsych-feedback').empty();
    }, 350);
  }
}

// create a formatted list of trial stimuli for a block
function formatBlockStimuli(trials, font_sizes_px) {
  // make smallest font size by default
  font_sizes_px = (typeof font_sizes_px !== "undefined") ?
    font_sizes_px : jsSART.STIMULI.FONT_SIZES;

  var block_stimuli = [];
  for (var i = 0; i < trials.length; i++) {
    // create formatted stimulus with randomly sampled font size
    var trial_stimuli = {
      stimuli: [
        "
" +
        trials[i] +
        "
",
        ""
      ]
    };
    block_stimuli.push(trial_stimuli);
  }
  return block_stimuli;
}

// create a block of trials
function createSartBlock(stimuli, options) {
  options = options || {};
  var give_feedback = options.give_feedback || false;
  var extra_data = options.extra_data || {};

  var block = {
    type: "multi-stim-multi-response",

    timeline: formatBlockStimuli(stimuli),
    is_html: true,
    choices: [jsSART.STIMULI.ALLOW_KEYCODES],

    timing_stim: jsSART.TIMING_STIM_DISPLAY,
    timing_response: sum(jsSART.TIMING_STIM_DISPLAY),
    response_ends_trial: false,

    data: {block_stimuli: stimuli},
    on_finish: function() {
      // add results to trial data
      var trial_data = jsPsych.data.getLastTrialData();
      var added_data = addTrialResults(trial_data, extra_data);
      jsPsych.data.addDataToLastTrial(added_data);

      if (give_feedback) {
        displayTrialFeedback(added_data);
      }
    }
  };
  if (give_feedback) {
    // add post-trial time for feedback display
    block.timing_post_trial = 350;
  }

  return block;
}

// generate a complete experiment chunk, complete with survey
function generateExperimentChunk(stimuli, options) {
  var notice = createTextBlock("When you're ready to continue, a trial block will begin.");

  var block = createSartBlock(stimuli, options),
      survey_questions = jsSART.POST_BLOCK_QUESTIONS,
      // make all questions required
      required = _.map(survey_questions, function(){ return true; });

  var survey = {
      type: 'survey-multi-choice',
      questions: [survey_questions],
      options: [[jsSART.LIKERT_SCALE_1, jsSART.LIKERT_SCALE_1]],
      required: [required],
      horizontal: true
  };

  var chunk = {
    chunk_type: 'linear',
    timeline: [notice, fixation_trial, block, survey]
  };
  return chunk;
}

// generate random conditions
function generateConditions() {
  var conditions = {
    num_trials: _.sample(jsSART.CONDITIONS.NUM_TRIALS),
    trials_per_block: _.sample(jsSART.CONDITIONS.TRIALS_PER_BLOCK)
  };
  return conditions;
}

// generate a formatted and complete set of jsPsych blocks
// Note: return an object with block stimuli lists and formatted stimuli
function generateSartBlockStimuli(block_types) {
  // get random stimuli for each block
  var block_stimuli = _.map(block_types, function(difficulty) {
    return generateStimuli(difficulty);
  });

  // generate jsPsych block objects
  var stimuli_types = _.zip(block_stimuli, block_types);
  var formatted_stimuli = _.map(stimuli_types, function(stimuli_type) {
    var added_data = {block_type: stimuli_type[1]};

    return generateExperimentChunk(stimuli_type[0], {
      added_data: added_data
    });
  });

  return {
    block_stimuli: block_stimuli,
    formatted_stimuli: formatted_stimuli
  };
}

// generate quasi-random stimuli for SART blocks
// return list of trial values
function generateStimuli(num_trials) {
  var stimuli = [];
  var quasi_random_counter = -1;
  var last_trial;

  while (stimuli.length < num_trials) {
    // prohibit 3s unless quasi-random counter equals zero
    if (last_trial === 3 && quasi_random_counter < 0) {
      // select a random countdown number from list
      quasi_random_counter = _.sample(jsSART.STIMULI.QUASI_RANDOM_RANGE);
    }

    // select random stimuli
    var trial = _.sample(jsSART.STIMULI.VALUES);

    // add trial to stimuli if allowable
    if (quasi_random_counter < 0 ||
        (quasi_random_counter >= 0 && trial !== 3)) {
      stimuli.push(trial);
      last_trial = trial;
      if (quasi_random_counter > -1) quasi_random_counter--;
    }
  }

  return stimuli;
}

// divide all experiment stimuli into specified block lengths
// return list of lists
function divideStimuliIntoBlocks(stimuli, trials_per_block) {
  var blocks = [];

  while (stimuli.length) {
    // create blocks
    var block = [];
    for (var i=0; i < trials_per_block; i++) {
      var stimulus = stimuli.shift();
      block.push(stimulus);

      if (!stimuli.length) {
        // stop looping when run out of stimuli
        // NOTE: for last block
        break;
      }
    }
    blocks.push(block);
  }
  return blocks;
}

// post data to the server using an AJAX call
function postDataToDb(data, filename, redirect) {
  var pathname = window.location.pathname.slice(1);
  $.ajax({
    type: "POST",
    url: "/experiment-data",
    data: JSON.stringify({filename: filename, pathname: pathname, data: data}),
    contentType: "application/json"
  })
  .done(function() {
    if (typeof redirect === "string") {
      window.location.href = redirect;
    }
  })
  .fail(function() {
    alert("A problem occurred while writing to the database. We cannot continue. Please contact the researcher for more information.");
  });
}
<commit_msg>Correct SART block display<commit_after>/**
 * Common utility values and functions for jsSART
 */

// Reuseable stimuli
// ------------------------

// HTML for text plugin
var spacebar_html = "<SPACEBAR>";
var continue_html = "
Press the " + spacebar_html + " to continue.
";

// fixation stimulus
var fixation_cross_path = "../img/fixation-cross.png";
var fixation_trial = {
  type: 'single-stim',
  stimulus: [fixation_cross_path],
  timing_stim: jsSART.TIMING_STIM_DISPLAY[1],
  timing_response: jsSART.TIMING_STIM_DISPLAY[1],
  timing_post_trial: 0
};

// Functions
// ------------------------

// sum a list of values
function sum(list) {
  return _.reduce(list, function(memo, num){ return memo + num; });
}

// get url parameters
function getUrlParams() {
  var url_params = window.location.search.slice(1);
  return $.deparam(url_params);
}

// try to get a participant ID
function getParticipantId() {
  var pid;

  // first attempt to get PID via URL params
  params = getUrlParams();
  pid = params.pid;

  // next, get PID via window prompt
  pid = pid || window.prompt("Please enter a participant ID.");

  // as a last resort, use 99999 with 5-digit random integer appended
  pid = pid || "99999" + _.random(10000, 99999);

  return pid;
}

// create a 'text' plugin block with some defaults
function createTextBlock(text_html) {
  return {
    type: "text",
    text: text_html + continue_html,
    cont_key: [32, 13]
  };
}

// add results data to the last trial
function addTrialResults(trial_data, extra_data) {
  extra_data = extra_data || {};
  var expected, response, correct;

  var trial_stimulus = JSON.parse(trial_data.stimulus);
  var stimulus_text = $(trial_stimulus[0]).text();
  var stimulus = parseInt(stimulus_text);

  // expected (correct) response for the last trial
  if (stimulus === jsSART.STIMULI.NO_GO_VALUE) {
    expected = false;
  } else {
    expected = true;
  }

  // check whether an expected key was pressed
  var key_press = JSON.parse(trial_data.key_press);
  response = _.contains(jsSART.STIMULI.ALLOW_KEYCODES, key_press[0]);

  // was the response given as expected (correct)?
  correct = (expected === response) ? true : false;

  var trial_results = $.extend({
    expected: expected,
    response: response,
    correct: correct
  }, extra_data);  // merge with given data

  return trial_results;
}

// display trial feedback, based on response judgement
function displayTrialFeedback(data) {
  if (typeof data.correct !== "undefined") {
    var feedback_text = data.correct ? "Correct!" : "Incorrect";
    var feedback_class = data.correct ? "correct" : "incorrect";
    var feedback_html = '
'+feedback_text+'
';

    // show feedback
    $('#jspsych-feedback').html(feedback_html);
    // hide feedback
    window.setTimeout(function() {
      $('#jspsych-feedback').empty();
    }, 350);
  }
}

// create a formatted list of trial stimuli for a block
function formatBlockStimuli(trials, font_sizes_px) {
  // make smallest font size by default
  font_sizes_px = (typeof font_sizes_px !== "undefined") ?
    font_sizes_px : jsSART.STIMULI.FONT_SIZES;

  var block_stimuli = [];
  for (var i = 0; i < trials.length; i++) {
    // create formatted stimulus with randomly sampled font size
    var trial_stimuli = {
      stimuli: [
        "
" +
        trials[i] +
        "
",
        ""
      ]
    };
    block_stimuli.push(trial_stimuli);
  }
  return block_stimuli;
}

// create a block of trials
function createSartBlock(stimuli, options) {
  options = options || {};
  var give_feedback = options.give_feedback || false;
  var extra_data = options.extra_data || {};

  var block = {
    type: "multi-stim-multi-response",

    timeline: formatBlockStimuli(stimuli),
    is_html: true,
    choices: [jsSART.STIMULI.ALLOW_KEYCODES],

    timing_stim: jsSART.TIMING_STIM_DISPLAY,
    timing_response: sum(jsSART.TIMING_STIM_DISPLAY),
    timing_post_trial: 0,
    response_ends_trial: false,

    data: {block_stimuli: stimuli},
    on_finish: function() {
      // add results to trial data
      var trial_data = jsPsych.data.getLastTrialData();
      var added_data = addTrialResults(trial_data, extra_data);
      jsPsych.data.addDataToLastTrial(added_data);

      if (give_feedback) {
        displayTrialFeedback(added_data);
      }
    }
  };
  if (give_feedback) {
    // add post-trial time for feedback display
    block.timing_post_trial = 350;
  }

  return block;
}

// generate a complete experiment chunk, complete with survey
function generateExperimentChunk(stimuli, options) {
  var notice = createTextBlock("When you're ready to continue, a trial block will begin.");

  var block = createSartBlock(stimuli, options),
      survey_questions = jsSART.POST_BLOCK_QUESTIONS,
      // make all questions required
      required = _.map(survey_questions, function(){ return true; });

  var survey = {
      type: 'survey-multi-choice',
      questions: [survey_questions],
      options: [[jsSART.LIKERT_SCALE_1, jsSART.LIKERT_SCALE_1]],
      required: [required],
      horizontal: true
  };

  var chunk = {
    chunk_type: 'linear',
    timeline: [notice, fixation_trial, block, survey]
  };
  return chunk;
}

// generate random conditions
function generateConditions() {
  var conditions = {
    num_trials: _.sample(jsSART.CONDITIONS.NUM_TRIALS),
    trials_per_block: _.sample(jsSART.CONDITIONS.TRIALS_PER_BLOCK)
  };
  return conditions;
}

// generate a formatted and complete set of jsPsych blocks
// Note: return an object with block stimuli lists and formatted stimuli
function generateSartBlockStimuli(block_types) {
  // get random stimuli for each block
  var block_stimuli = _.map(block_types, function(difficulty) {
    return generateStimuli(difficulty);
  });

  // generate jsPsych block objects
  var stimuli_types = _.zip(block_stimuli, block_types);
  var formatted_stimuli = _.map(stimuli_types, function(stimuli_type) {
    var added_data = {block_type: stimuli_type[1]};

    return generateExperimentChunk(stimuli_type[0], {
      added_data: added_data
    });
  });

  return {
    block_stimuli: block_stimuli,
    formatted_stimuli: formatted_stimuli
  };
}

// generate quasi-random stimuli for SART blocks
// return list of trial values
function generateStimuli(num_trials) {
  var stimuli = [];
  var quasi_random_counter = -1;
  var last_trial;

  while (stimuli.length < num_trials) {
    // prohibit 3s unless quasi-random counter equals zero
    if (last_trial === 3 && quasi_random_counter < 0) {
      // select a random countdown number from list
      quasi_random_counter = _.sample(jsSART.STIMULI.QUASI_RANDOM_RANGE);
    }

    // select random stimuli
    var trial = _.sample(jsSART.STIMULI.VALUES);

    // add trial to stimuli if allowable
    if (quasi_random_counter < 0 ||
        (quasi_random_counter >= 0 && trial !== 3)) {
      stimuli.push(trial);
      last_trial = trial;
      if (quasi_random_counter > -1) quasi_random_counter--;
    }
  }

  return stimuli;
}

// divide all experiment stimuli into specified block lengths
// return list of lists
function divideStimuliIntoBlocks(stimuli, trials_per_block) {
  var blocks = [];

  while (stimuli.length) {
    // create blocks
    var block = [];
    for (var i=0; i < trials_per_block; i++) {
      var stimulus = stimuli.shift();
      block.push(stimulus);

      if (!stimuli.length) {
        // stop looping when run out of stimuli
        // NOTE: for last block
        break;
      }
    }
    blocks.push(block);
  }
  return blocks;
}

// post data to the server using an AJAX call
function postDataToDb(data, filename, redirect) {
  var pathname = window.location.pathname.slice(1);
  $.ajax({
    type: "POST",
    url: "/experiment-data",
    data: JSON.stringify({filename: filename, pathname: pathname, data: data}),
    contentType: "application/json"
  })
  .done(function() {
    if (typeof redirect === "string") {
      window.location.href = redirect;
    }
  })
  .fail(function() {
    alert("A problem occurred while writing to the database. We cannot continue. Please contact the researcher for more information.");
  });
}
<|endoftext|>


<commit_before>"use strict";
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import { FormMixin, Input } from '../../libs/bootstrap/form';
import { external_url_map } from '../globals';

import { DiseaseModal } from './modal';

/**
 * Component for adding disease when creating a new gene-disease record
 * and for editing disease (in the header) after a gdm had been created
 * (but not after a pmid had been added to the gdm)
 */
const GdmDisease = module.exports.GdmDisease = React.createClass({
    mixins: [FormMixin],

    propTypes: {
        gdm: PropTypes.object, // For editing disease (passed to Modal)
        updateDiseaseObj: PropTypes.func,
        clearErrorInParent: PropTypes.func,
        error: PropTypes.string,
        session: PropTypes.object
    },

    getInitialState() {
        return {
            gdm: this.props.gdm,
            error: this.props.error,
            diseaseId: '',
            diseaseTerm: null,
            diseaseOntology: null,
            diseaseDescription: null,
            synonyms: [],
            phenotypes: [],
            diseaseFreeTextConfirm: false,
            diseaseObj: {}
        };
    },

    componentDidMount() {
        let gdm = this.state.gdm;
        if (gdm && gdm.disease) {
            this.setDiseaseObjectStates(gdm.disease);
        }
    },

    componentWillReceiveProps(nextProps)  {
        if (nextProps.gdm) {
            this.setState({gdm: nextProps.gdm}, () => {
                let gdm = this.state.gdm;
                if (gdm && gdm.disease) {
                    this.setDiseaseObjectStates(gdm.disease);
                }
            });
        }
        if (nextProps.error) {
            this.setState({error: nextProps.error});
        }
    },

    /**
     * Shared method called by componentDidMount(), componentWillReceiveProps(nextProps)
     * @param {*} disease
     */
    setDiseaseObjectStates(disease) {
        if (disease.id) { this.setState({diseaseId: disease.id}); }
        if (disease.term) { this.setState({diseaseTerm: disease.term}) ;}
        disease.ontology ? this.setState({diseaseOntology: disease.ontology}) : this.setState({diseaseOntology: null});
        disease.description ? this.setState({diseaseDescription: disease.description}) : this.setState({diseaseDescription: null});
        if (disease.synonyms) { this.setState({synonyms: disease.synonyms}); }
        if (disease.phenotypes) { this.setState({phenotypes: disease.phenotypes}); }
        disease.freetext ? this.setState({diseaseFreeTextConfirm: disease.freetext}) : this.setState({diseaseFreeTextConfirm: false});
    },

    passDataToParent(id, term, ontology, description, synonyms, phenotypes, freetext) {
        let diseaseObj = this.state.diseaseObj;
        this.setState({error: null}, () => {
            this.props.clearErrorInParent();
        });
        if (id) {
            /**
             * Changing colon to underscore in id string for database
             */
            diseaseObj['id'] = id.replace(':', '_');
            this.setState({diseaseId: id});
        }
        if (term) {
            diseaseObj['term'] = term;
            this.setState({diseaseTerm: term});
        }
        if (ontology) {
            diseaseObj['ontology'] = ontology;
            this.setState({diseaseOntology: ontology});
        } else {
            if (diseaseObj['ontology']) { delete diseaseObj['ontology']; }
            this.setState({diseaseOntology: null});
        }
        if (description) {
            diseaseObj['description'] = description;
            this.setState({diseaseDescription: description});
        } else {
            if (diseaseObj['description']) { delete diseaseObj['description']; }
            this.setState({diseaseDescription: null});
        }
        if (synonyms) {
            diseaseObj['synonyms'] = synonyms;
            this.setState({synonyms: synonyms});
        } else {
            if (diseaseObj['synonyms']) { delete diseaseObj['synonyms']; }
            this.setState({synonyms: []});
        }
        if (phenotypes) {
            diseaseObj['phenotypes'] = phenotypes;
            this.setState({phenotypes: phenotypes});
        } else {
            if (diseaseObj['phenotypes']) { delete diseaseObj['phenotypes']; }
            this.setState({phenotypes: []});
        }
        if (freetext) {
            diseaseObj['freetext'] = true;
            this.setState({diseaseFreeTextConfirm: true});
        } else {
            if (diseaseObj['freetext']) { delete diseaseObj['freetext']; }
            this.setState({diseaseFreeTextConfirm: false});
        }
        this.setState({diseaseObj: diseaseObj}, () => {
            // Pass data object back to parent
            this.props.updateDiseaseObj(this.state.diseaseObj);
        });
    },

    renderDiseaseData(id, term, desc, hpo, freetext) {
        let source = !freetext ? id : this.props.session.user_properties.title;
        if (term && term.length) {
            return (

                    {term + ' (' + source + ')'}
                    {desc && desc.length ? Definition: {desc} : null}
                    {hpo && hpo.length ? HPO terms: {hpo.join(', ')} : null}

            );
        }
    },

    render() {
        let diseaseId = this.state.diseaseId;
        let diseaseTerm = this.state.diseaseTerm;
        let diseaseOntology = this.state.diseaseOntology;
        let diseaseDescription = this.state.diseaseDescription;
        let diseaseFreeTextConfirm = this.state.diseaseFreeTextConfirm;
        let phenotypes = this.state.phenotypes;
        let synonyms = this.state.synonyms;
        let addDiseaseModalBtn = diseaseTerm ? Disease : Disease;
        let error = this.state.error;
        let inputLabel = diseaseFreeTextConfirm ? Non-ID term: : Select disease:;

        return (

                    {inputLabel} *Search MonDO using OLS

                        {error ?
                            {error}
                            :

                                {this.renderDiseaseData(diseaseId, diseaseTerm, diseaseDescription, phenotypes, diseaseFreeTextConfirm)}

                        }

                    <DiseaseModal
                        addDiseaseModalBtn={addDiseaseModalBtn}
                        diseaseId={diseaseId}
                        diseaseTerm={diseaseTerm}
                        diseaseOntology={diseaseOntology}
                        diseaseDescription={diseaseDescription}
                        diseaseFreeTextConfirm={diseaseFreeTextConfirm}
                        phenotypes={phenotypes}
                        synonyms={synonyms}
                        passDataToParent={this.passDataToParent}
                        addDiseaseModalBtnLayoutClass={diseaseTerm || error ? ' pull-right' : ''}
                        resetAllowed={true}
                    />

        );
    }
});
<commit_msg>Added handling to filter empty arrays of synonyms and phenotypes<commit_after>"use strict";
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import { FormMixin, Input } from '../../libs/bootstrap/form';
import { external_url_map } from '../globals';

import { DiseaseModal } from './modal';

/**
 * Component for adding disease when creating a new gene-disease record
 * and for editing disease (in the header) after a gdm had been created
 * (but not after a pmid had been added to the gdm)
 */
const GdmDisease = module.exports.GdmDisease = React.createClass({
    mixins: [FormMixin],

    propTypes: {
        gdm: PropTypes.object, // For editing disease (passed to Modal)
        updateDiseaseObj: PropTypes.func,
        clearErrorInParent: PropTypes.func,
        error: PropTypes.string,
        session: PropTypes.object
    },

    getInitialState() {
        return {
            gdm: this.props.gdm,
            error: this.props.error,
            diseaseId: '',
            diseaseTerm: null,
            diseaseOntology: null,
            diseaseDescription: null,
            synonyms: [],
            phenotypes: [],
            diseaseFreeTextConfirm: false,
            diseaseObj: {}
        };
    },

    componentDidMount() {
        let gdm = this.state.gdm;
        if (gdm && gdm.disease) {
            this.setDiseaseObjectStates(gdm.disease);
        }
    },

    componentWillReceiveProps(nextProps)  {
        if (nextProps.gdm) {
            this.setState({gdm: nextProps.gdm}, () => {
                let gdm = this.state.gdm;
                if (gdm && gdm.disease) {
                    this.setDiseaseObjectStates(gdm.disease);
                }
            });
        }
        if (nextProps.error) {
            this.setState({error: nextProps.error});
        }
    },

    /**
     * Shared method called by componentDidMount(), componentWillReceiveProps(nextProps)
     * @param {*} disease
     */
    setDiseaseObjectStates(disease) {
        if (disease.id) { this.setState({diseaseId: disease.id}); }
        if (disease.term) { this.setState({diseaseTerm: disease.term}) ;}
        disease.ontology ? this.setState({diseaseOntology: disease.ontology}) : this.setState({diseaseOntology: null});
        disease.description ? this.setState({diseaseDescription: disease.description}) : this.setState({diseaseDescription: null});
        if (disease.synonyms) { this.setState({synonyms: disease.synonyms}); }
        if (disease.phenotypes) { this.setState({phenotypes: disease.phenotypes}); }
        disease.freetext ? this.setState({diseaseFreeTextConfirm: disease.freetext}) : this.setState({diseaseFreeTextConfirm: false});
    },

    passDataToParent(id, term, ontology, description, synonyms, phenotypes, freetext) {
        let diseaseObj = this.state.diseaseObj;
        this.setState({error: null}, () => {
            this.props.clearErrorInParent();
        });
        if (id) {
            /**
             * Changing colon to underscore in id string for database
             */
            diseaseObj['id'] = id.replace(':', '_');
            this.setState({diseaseId: id});
        }
        if (term) {
            diseaseObj['term'] = term;
            this.setState({diseaseTerm: term});
        }
        if (ontology) {
            diseaseObj['ontology'] = ontology;
            this.setState({diseaseOntology: ontology});
        } else {
            if (diseaseObj['ontology']) { delete diseaseObj['ontology']; }
            this.setState({diseaseOntology: null});
        }
        if (description) {
            diseaseObj['description'] = description;
            this.setState({diseaseDescription: description});
        } else {
            if (diseaseObj['description']) { delete diseaseObj['description']; }
            this.setState({diseaseDescription: null});
        }
        if (synonyms && synonyms.length) {
            diseaseObj['synonyms'] = synonyms;
            this.setState({synonyms: synonyms});
        } else {
            if (diseaseObj['synonyms']) { delete diseaseObj['synonyms']; }
            this.setState({synonyms: []});
        }
        if (phenotypes && phenotypes.length) {
            diseaseObj['phenotypes'] = phenotypes;
            this.setState({phenotypes: phenotypes});
        } else {
            if (diseaseObj['phenotypes']) { delete diseaseObj['phenotypes']; }
            this.setState({phenotypes: []});
        }
        if (freetext) {
            diseaseObj['freetext'] = true;
            this.setState({diseaseFreeTextConfirm: true});
        } else {
            if (diseaseObj['freetext']) { delete diseaseObj['freetext']; }
            this.setState({diseaseFreeTextConfirm: false});
        }
        this.setState({diseaseObj: diseaseObj}, () => {
            // Pass data object back to parent
            this.props.updateDiseaseObj(this.state.diseaseObj);
        });
    },

    renderDiseaseData(id, term, desc, hpo, freetext) {
        let source = !freetext ? id : this.props.session.user_properties.title;
        if (term && term.length) {
            return (

                    {term + ' (' + source + ')'}
                    {desc && desc.length ? Definition: {desc} : null}
                    {hpo && hpo.length ? HPO terms: {hpo.join(', ')} : null}

            );
        }
    },

    render() {
        let diseaseId = this.state.diseaseId;
        let diseaseTerm = this.state.diseaseTerm;
        let diseaseOntology = this.state.diseaseOntology;
        let diseaseDescription = this.state.diseaseDescription;
        let diseaseFreeTextConfirm = this.state.diseaseFreeTextConfirm;
        let phenotypes = this.state.phenotypes;
        let synonyms = this.state.synonyms;
        let addDiseaseModalBtn = diseaseTerm ? Disease : Disease;
        let error = this.state.error;
        let inputLabel = diseaseFreeTextConfirm ? Non-ID term: : Select disease:;

        return (

                    {inputLabel} *Search MonDO using OLS

                        {error ?
                            {error}
                            :

                                {this.renderDiseaseData(diseaseId, diseaseTerm, diseaseDescription, phenotypes, diseaseFreeTextConfirm)}

                        }

                    <DiseaseModal
                        addDiseaseModalBtn={addDiseaseModalBtn}
                        diseaseId={diseaseId}
                        diseaseTerm={diseaseTerm}
                        diseaseOntology={diseaseOntology}
                        diseaseDescription={diseaseDescription}
                        diseaseFreeTextConfirm={diseaseFreeTextConfirm}
                        phenotypes={phenotypes}
                        synonyms={synonyms}
                        passDataToParent={this.passDataToParent}
                        addDiseaseModalBtnLayoutClass={diseaseTerm || error ? ' pull-right' : ''}
                        resetAllowed={true}
                    />

        );
    }
});
<|endoftext|>


<commit_before>window.utils = {};

window.utils.b64EncodeUnicode = function(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
};

window.utils.getLongNameForFeature = function(feature) {
	switch (feature) {
		case "overview":
			return "Overview";

		case "planner":
			return "Planner";

		case "hwView":
			return "Homework View";

		case "myDay":
			return "My Day";

		case "admin":
			return "Administrative panel";

		case "admin-feedback":
			return "Feedback";

		case "admin-stats":
			return "Statistics";

		case "admin-about":
			return "About server";
	}
};

window.utils.getMonthName = function(month) {
	switch (month) {
		case 0:
			return "January";
		case 1:
			return "February";
		case 2:
			return "March";
		case 3:
			return "April";
		case 4:
			return "May";
		case 5:
			return "June";
		case 6:
			return "July";
		case 7:
			return "August";
		case 8:
			return "September";
		case 9:
			return "October";
		case 10:
			return "November";
		case 11:
			return "December";
		default:
			return "Unknown";
	}
};

window.utils.getDayOfWeek = function(dow) {
	switch (dow) {
		case 0:
			return "Sunday";
		case 1:
			return "Monday";
		case 2:
			return "Tuesday";
		case 3:
			return "Wednesday";
		case 4:
			return "Thursday";
		case 5:
			return "Friday";
		case 6:
			return "Saturday";
		default:
			return "Unknown";
	}
};

window.utils.formatDate_api = function(dateObj) {
	var month = (dateObj.getMonth() + 1).toString();
	var date = dateObj.getDate().toString();
	if (month.length == 1) {
		month = "0" + month;
	}
	if (date.length == 1) {
		date = "0" + date;
	}
	return dateObj.getFullYear() + "-" + month + "-" + date;
};

window.utils.formatDate_pretty = function(dateObj) {
	return (dateObj.getMonth() + 1) + "/" + dateObj.getDate();
};

window.utils.formatDate_english = function(date) {
	return window.utils.getDayOfWeek(date.getDay()) + ", " + window.utils.getMonthName(date.getMonth()) + " " + date.getDate() + ", " + (date.getYear() + 1900);
};

window.utils.getPrefix = function(text) {
	return text.split(' ')[0].trim().substr(0, 12); // limit to 12 chars
};

window.utils.getPrefixes = function() {
	return [
		{
			color: "cal_hw",
			words: ["hw", "read", "reading"],
			tabSystem: true
		},
		{
			color: "cal_project",
			words: ["project"],
			tabSystem: true
		},
		{
			color: "cal_paper",
			words: ["report", "essay", "paper"],
			tabSystem: true
		},
		{
			color: "cal_quiz",
			words: ["quiz"],
			tabSystem: true
		},
		{
			color: "cal_quiz",
			words: ["popquiz"],
			tabSystem: false
		},
		{
			color: "cal_test",
			words: ["test", "final", "exam", "midterm"],
			tabSystem: true
		},
		{
			color: "cal_ica",
			words: ["ica"],
			tabSystem: true
		},
		{
			color: "cal_lab",
			words: ["lab", "study", "memorize"],
			tabSystem: true
		},
		{
			color: "cal_docid",
			words: ["docid"],
			tabSystem: true
		},
		{
			color: "cal_hex",
			words: ["trojun", "hex"],
			tabSystem: false
		},
		{
			color: "cal_no_hw",
			words: ["nohw", "none"],
			tabSystem: true
		}
	];
};

window.utils.getPrefixClass = function(prefix) {
	var chkPrefix = prefix.toLowerCase();
	var prefixes = window.utils.getPrefixes();
	for (var prefixIndex in prefixes) {
		var prefix = prefixes[prefixIndex];
		if (prefix.indexOf(chkPrefix) > -1) {
			return prefix.color;
		}
	}
	return "cal_no_prefix";
};
<commit_msg>Appeasing bitHound<commit_after>window.utils = {};

window.utils.b64EncodeUnicode = function(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
};

window.utils.getLongNameForFeature = function(feature) {
	var features = {
		overview: "Overview",
		planner: "Planner",
		hwView: "Homework View",
		myDay: "My Day",
		admin: "Administrative panel",
		"admin-feedback": "Feedback",
		"admin-stats": "Feedback",
		"admin-about": "Feedback"
	};
	return features[feature];
};

window.utils.getMonthName = function(month) {
	var months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
	return months[month];
};

window.utils.getDayOfWeek = function(dow) {
	switch (dow) {
		case 0:
			return "Sunday";
		case 1:
			return "Monday";
		case 2:
			return "Tuesday";
		case 3:
			return "Wednesday";
		case 4:
			return "Thursday";
		case 5:
			return "Friday";
		case 6:
			return "Saturday";
		default:
			return "Unknown";
	}
};

window.utils.formatDate_api = function(dateObj) {
	var month = (dateObj.getMonth() + 1).toString();
	var date = dateObj.getDate().toString();
	if (month.length == 1) {
		month = "0" + month;
	}
	if (date.length == 1) {
		date = "0" + date;
	}
	return dateObj.getFullYear() + "-" + month + "-" + date;
};

window.utils.formatDate_pretty = function(dateObj) {
	return (dateObj.getMonth() + 1) + "/" + dateObj.getDate();
};

window.utils.formatDate_english = function(date) {
	return window.utils.getDayOfWeek(date.getDay()) + ", " + window.utils.getMonthName(date.getMonth()) + " " + date.getDate() + ", " + (date.getYear() + 1900);
};

window.utils.getPrefix = function(text) {
	return text.split(' ')[0].trim().substr(0, 12); // limit to 12 chars
};

window.utils.getPrefixes = function() {
	return [
		{
			color: "cal_hw",
			words: ["hw", "read", "reading"],
			tabSystem: true
		},
		{
			color: "cal_project",
			words: ["project"],
			tabSystem: true
		},
		{
			color: "cal_paper",
			words: ["report", "essay", "paper"],
			tabSystem: true
		},
		{
			color: "cal_quiz",
			words: ["quiz"],
			tabSystem: true
		},
		{
			color: "cal_quiz",
			words: ["popquiz"],
			tabSystem: false
		},
		{
			color: "cal_test",
			words: ["test", "final", "exam", "midterm"],
			tabSystem: true
		},
		{
			color: "cal_ica",
			words: ["ica"],
			tabSystem: true
		},
		{
			color: "cal_lab",
			words: ["lab", "study", "memorize"],
			tabSystem: true
		},
		{
			color: "cal_docid",
			words: ["docid"],
			tabSystem: true
		},
		{
			color: "cal_hex",
			words: ["trojun", "hex"],
			tabSystem: false
		},
		{
			color: "cal_no_hw",
			words: ["nohw", "none"],
			tabSystem: true
		}
	];
};

window.utils.getPrefixClass = function(prefix) {
	var chkPrefix = prefix.toLowerCase();
	var prefixes = window.utils.getPrefixes();
	for (var prefixIndex in prefixes) {
		var prefix = prefixes[prefixIndex];
		if (prefix.indexOf(chkPrefix) > -1) {
			return prefix.color;
		}
	}
	return "cal_no_prefix";
};
<|endoftext|>


<commit_before>var mercury = require('../../index')
var h = mercury.h
var inlineMdEditor = require('./component/inlineMdEditor')
var sideBySideMdEditor = require('./component/sideBySideMdEditor')

app.render = appRender

module.exports = app

function app() {
	var state = mercury.hash({
		inlineEditor: inlineMdEditor({
			placeholder: 'Enter some markdown...'
		}),
		sideBySideEditor: sideBySideMdEditor({
			placeholder: 'Enter some markdown...',
			value: [
				'#Hello World',
				'',
				'* sample',
				'* bullet',
				'* points'
			].join('\n')
		})
	})

	return state
}

function appRender(state) {

	return h('.page', {
		style: { visibility: 'hidden' }
	}, [
		h('link', {
			rel: 'stylesheet',
			href: '/mercury/examples/markdown/style.css'
		}),
		h('.content', [
			h('h2', 'Side-by-side Markdown Editor'),
			h('p', 'Enter some markdown and click outside of the textarea to ' +
					'see the parsed result. Click the output to edit again.'),
			sideBySideMdEditor.render(state.sideBySideEditor),
			h('h2', 'Inline Markdown Editor'),
			h('p', 'Enter some markdown and click outside of the textarea to ' +
					'see the parsed result. Click the output to edit again.'),
			inlineMdEditor.render(state.inlineEditor)
		])
	])
}
<commit_msg>fix typo in markdown instructions<commit_after>var mercury = require('../../index')
var h = mercury.h
var inlineMdEditor = require('./component/inlineMdEditor')
var sideBySideMdEditor = require('./component/sideBySideMdEditor')

app.render = appRender

module.exports = app

function app() {
	var state = mercury.hash({
		inlineEditor: inlineMdEditor({
			placeholder: 'Enter some markdown...'
		}),
		sideBySideEditor: sideBySideMdEditor({
			placeholder: 'Enter some markdown...',
			value: [
				'#Hello World',
				'',
				'* sample',
				'* bullet',
				'* points'
			].join('\n')
		})
	})

	return state
}

function appRender(state) {

	return h('.page', {
		style: { visibility: 'hidden' }
	}, [
		h('link', {
			rel: 'stylesheet',
			href: '/mercury/examples/markdown/style.css'
		}),
		h('.content', [
			h('h2', 'Side-by-side Markdown Editor'),
			h('p', 'Enter some markdown in the left pane and see it rendered ' +
				'in the pane on the right.'),
			sideBySideMdEditor.render(state.sideBySideEditor),
			h('h2', 'Inline Markdown Editor'),
			h('p', 'Enter some markdown and click outside of the textarea to ' +
				'see the parsed result. Click the output to edit again.'),
			inlineMdEditor.render(state.inlineEditor)
		])
	])
}
<|endoftext|>


<commit_before>var path = require('path');
var SG = require('strong-globalize');

SG.SetRootDir(path.join(__dirname, '..'), {autonomousMsgLoading: 'all'});
module.exports = SG();
<commit_msg>Add license text<commit_after>// Copyright IBM Corp. 2016. All Rights Reserved.
// Node module: loopback-connector-ibmdb
// This file is licensed under the Artistic License 2.0.
// License text available at https://opensource.org/licenses/Artistic-2.0

var path = require('path');
var SG = require('strong-globalize');

SG.SetRootDir(path.join(__dirname, '..'), {autonomousMsgLoading: 'all'});
module.exports = SG();
<|endoftext|>