<commit_before>import { getCohortByName } from '../../../../../../database-controller/AcademicCohort/methods';
import { getGradRequirementModules,
         getGradRequirementMCs } from '../../../../../../database-controller/graduation-requirement/methods';
import { getFocusAreaPrimaryRequirement,
         getFocusArea4KRequirement,
         getFocusAreaNonPrimaryRequirement,
         getFocusAreaPrimary4KRequirement } from '../../../../../../database-controller/focus-area/methods';
import { findFoundationRequirementModules } from './foundation/methods';
import { findITProfessionalismModules } from './IT-professionalism/methods';
import { findMathSciRequirementModules } from './math-science/methods';
import { findTeamProjectRequirementModules } from './breadth-depth/team-project/methods';
import { findIndustrialExperienceTrainingModules } from './breadth-depth/industrial-experience/methods';
import { checkFocusAreaFulfilmentMCs,
         findFocusAreaModules } from './breadth-depth/focus-area/methods';
import { findULRRequirementModules } from '../../../../university-level-requirements/AY-1415/methods';
import { findUnrestrictedElectivesRequirementModules } from './unrestricted-electives/methods';

/* Explanation for new AY creation
 * Grad checker handler retrieves all the graduation requirements from each of the
 * sub requirements.
 * It also converts the graduation format to fit the display format
 *
 * Thus, you should only modify the UI conversion method if any of the grad requirements
 * changes its form from the UI display format
 *
 * UI display JSON format:
 * Requirement {
 *  name:
 *  children:
 *  isFulfilled:
 * }
 *
 * name -> name of what will be displayed on the screen
 * children -> array of JSON as displayed under the "Requirement"
 * isFulfilled -> is the current JSON has fulfilled. All children must be fulfilled
 *                for the current JSON to be fulfilled
 */

/**
* retrieves an object of string boolean objects for each graduation requirement
*  @param {objects}  a full appended object list of all the modules in a student planner
*  @param {number}  current student academic year
*  @param {objects}  modules which are exempted by student
*  @param {objects}  modules which are waived by student
*  @return {{objects}}  UI formatted list of graduation requirements
*
*/
export const AY1415CSGradChecker = function AY1415CSGradChecker(studentSemesters, studentAcademicCohort, studentExemptedModules, studentWaivedModules) {
  const graduationMCs = 160;
  const moduleRequirementTitle = ['Computer Science Foundation',
                                  'Computer Science Focus Area',
                                  'Computer Systems Team Project',
                                  'Industrial Experience Training',
                                  'IT Professionalism','Mathematics and Sciences',
                                  'University Level Requirement', 'Unrestricted Electives'];
  const focusAreaTitles = ['Algorithms & Theory', 'Artificial Intelligence',
                           'Computer Graphics and Games', 'Computer Security',
                           'Database Systems', 'Multimedia Information Retrieval',
                           'Networking and Distributed Systems', 'Parallel Computing',
                           'Programming Languages', 'Software Engineering'];

  let graduationRequirements = {};

  let UIFormatGraduationRequirement = {
    name: 'Graduation Requirements',
    children: [],
    isFulfilled: false
  };

  if (!studentSemesters) {
    return graduationRequirements;
  }

  const cohortInformation = getCohortByName(studentAcademicCohort);

  if (!cohortInformation) {
    return graduationRequirements;
  }

  // retrieve foundation, IT-professionalism, Math-Sci and Breadth and Depth requirements here
  const cohortGradRequirementIDs = cohortInformation.cohortGradRequirementID;
  const allGradRequirements = getGradRequirementModules(cohortGradRequirementIDs);
  const allGraduationRequirementMCs = getGradRequirementMCs(cohortGradRequirementIDs);

  // retrieve focus area modules
  const allFocusAreaPrimaryRequirements = getFocusAreaPrimaryRequirement(cohortInformation.cohortFocusAreaID);
  const allFocusArea4KRequirements = getFocusArea4KRequirement(cohortInformation.cohortFocusAreaID);
  const allFocusArea4KPrimaryRequirements = getFocusAreaPrimary4KRequirement(cohortInformation.cohortFocusAreaID);
  const allFocusAreaNonPrimaryRequirements = getFocusAreaNonPrimaryRequirement(cohortInformation.cohortFocusAreaID);

  if (Object.keys(allGradRequirements).length === 0 || !allGradRequirements ||
      !allGraduationRequirementMCs) {
    return graduationRequirements;
  }

  // append objects of string:bool objects into a list of objects and return to UI
  for (var i=0; i<moduleRequirementTitle.length; i++) {
    graduationRequirements[moduleRequirementTitle[i]] = {};
  }

  /*
   * Send all planner information to every requirement check
   */

  // find university-level-requirements here
  const ULRRequirements = allGradRequirements[moduleRequirementTitle[6]];
  const requiredMCsULR = allGraduationRequirementMCs[moduleRequirementTitle[6]];
  graduationRequirements[moduleRequirementTitle[6]] = findULRRequirementModules(studentAcademicCohort, studentSemesters, ULRRequirements, studentExemptedModules, studentWaivedModules, requiredMCsULR);
  if (Object.keys(graduationRequirements[moduleRequirementTitle[6]]).length > 0)  {
  UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[6]].name,
                                                                 graduationRequirements[moduleRequirementTitle[6]].markedULRModules,
                                                                 graduationRequirements[moduleRequirementTitle[6]].isFulfilled));
  }

  // find foundation requirement modules objects and call function from relevant academic year
  const foundationRequirements = allGradRequirements[moduleRequirementTitle[0]];
  const requiredMCsFoundation = allGraduationRequirementMCs[moduleRequirementTitle[0]];
  graduationRequirements[moduleRequirementTitle[0]] = findFoundationRequirementModules(studentAcademicCohort, studentSemesters, foundationRequirements, studentExemptedModules, studentWaivedModules, requiredMCsFoundation);
  if (Object.keys(graduationRequirements[moduleRequirementTitle[0]]).length > 0)  {
    UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[0]].name,
                                                                   graduationRequirements[moduleRequirementTitle[0]].markedFoundationModules,
                                                                   graduationRequirements[moduleRequirementTitle[0]].isFulfilled));
  }

  // find computer science breadth and depth requirement modules
    // find focus area requirement modules object
    let focusAreaMCSFulfilment = {};
    let focusAreaRequirements = {
      name: moduleRequirementTitle[1],
      children: [],
      isFulfilled: false
    };

    let focusAreaPrimaries = {
      name: "Area Primaries",
      children: [],
      isFulfilled: false
    }

    let focusAreaAtLeast12MCs = {
      name: "At least 12 MCs of 4K modules",
      children: [],
      isFulfilled: false
    }

    const allStudentFocusAreas = {
      focusAreaPrimaryModules: allFocusAreaPrimaryRequirements,
      focusArea4KModules: allFocusArea4KRequirements,
      focusAreaPrimary4KModules :allFocusArea4KPrimaryRequirements,
      focusAreaNonPrimaryModules: allFocusAreaNonPrimaryRequirements
    };

    // for all focus area, find the ones fulfilled by the current planner
    for (var i=0; i<focusAreaTitles.length; i++)  {
      let focusArea = {
        focusAreaPrimaryModules: allStudentFocusAreas.focusAreaPrimaryModules[focusAreaTitles[i]],
        focusArea4KModules: allStudentFocusAreas.focusArea4KModules[focusAreaTitles[i]],
        focusAreaPrimary4KModules: allStudentFocusAreas.focusAreaPrimary4KModules[focusAreaTitles[i]],
        focusAreaNonPrimaryModules: allStudentFocusAreas.focusAreaNonPrimaryModules[focusAreaTitles[i]]
      }

      if (!focusArea.focusAreaPrimaryModules || !focusArea.focusArea4KModules || !focusArea.focusArea4KModules)  {
        continue;
      }

      let oneFocusArea = findFocusAreaModules(focusAreaTitles[i], studentAcademicCohort, studentSemesters, focusArea, studentExemptedModules, studentWaivedModules);
      focusAreaPrimaries.children.push(UIFormatFocusAreaConversion(oneFocusArea));
      if (oneFocusArea.isPrimaryTrue)  {
        focusAreaPrimaries.isFulfilled = true;
      }
      if (oneFocusArea.is4KTrue) {
        focusAreaAtLeast12MCs.isFulfilled = true;
      }
    }

    // check if student planner meet 24 MCs requirement
    focusAreaMCSFulfilment = checkFocusAreaFulfilmentMCs(studentSemesters, allStudentFocusAreas, allGraduationRequirementMCs[moduleRequirementTitle[1]]);
    graduationRequirements[moduleRequirementTitle[1]] = focusAreaMCSFulfilment;

    if (focusAreaPrimaries.isFulfilled && focusAreaAtLeast12MCs.isFulfilled &&
        focusAreaMCSFulfilment.isFulfilled)  {
      focusAreaRequirements.isFulfilled =  true;
    }

    focusAreaRequirements.children.push(focusAreaPrimaries);
    focusAreaRequirements.children.push(focusAreaAtLeast12MCs);
    UIFormatGraduationRequirement.children.push(focusAreaRequirements);

    //console.log(JSON.stringify(UIFormatGraduationRequirement));

    // find computer systems team project requirement modules
    const teamProjectRequirements = allGradRequirements[moduleRequirementTitle[2]];
    const requiredMCsTeamProject = allGraduationRequirementMCs[moduleRequirementTitle[2]];
    graduationRequirements[moduleRequirementTitle[2]] = findTeamProjectRequirementModules(studentAcademicCohort, studentSemesters, teamProjectRequirements, studentExemptedModules, studentWaivedModules, requiredMCsTeamProject);
    if (Object.keys(graduationRequirements[moduleRequirementTitle[2]]).length > 0)  {
      UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[2]].name,
                                                                     graduationRequirements[moduleRequirementTitle[2]].markedTeamProjectModules,
                                                                     graduationRequirements[moduleRequirementTitle[2]].isFulfilled));
    }

    // find Industrial experience training requirement modules
    const industrialExperienceRequirements = allGradRequirements[moduleRequirementTitle[3]];
    const requiredMCsIndustrialExperience = allGraduationRequirementMCs[moduleRequirementTitle[3]];
    graduationRequirements[moduleRequirementTitle[3]] = findIndustrialExperienceTrainingModules(studentAcademicCohort, studentSemesters, industrialExperienceRequirements, studentExemptedModules, studentWaivedModules, requiredMCsIndustrialExperience);
    if (Object.keys(graduationRequirements[moduleRequirementTitle[3]]).length > 0)  {
      UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[3]].name,
                                                                     graduationRequirements[moduleRequirementTitle[3]].markedIndustrialExperienceTrainingModules,
                                                                     graduationRequirements[moduleRequirementTitle[3]].isFulfilled));
    }

  // find IT-professionalism requirement modules objects
  const ITRequirements = allGradRequirements[moduleRequirementTitle[4]];
  const requiredMCsIT = allGraduationRequirementMCs[moduleRequirementTitle[4]];
  graduationRequirements[moduleRequirementTitle[4]] = findITProfessionalismModules(studentAcademicCohort, studentSemesters, ITRequirements, studentExemptedModules, studentWaivedModules, requiredMCsIT);
  if (Object.keys(graduationRequirements[moduleRequirementTitle[4]]).length > 0)  {
    UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[4]].name,
                                                                   graduationRequirements[moduleRequirementTitle[4]].markedITProfessionalismModules,
                                                                   graduationRequirements[moduleRequirementTitle[4]].isFulfilled));
  }

  // find math-science requirement modules objects
  const mathScienceRequirements = allGradRequirements[moduleRequirementTitle[5]];
  const requiredMCsMathSci = allGraduationRequirementMCs[moduleRequirementTitle[5]];
  graduationRequirements[moduleRequirementTitle[5]] = findMathSciRequirementModules(studentAcademicCohort, studentSemesters, mathScienceRequirements, studentExemptedModules, studentWaivedModules, requiredMCsMathSci);
  if (Object.keys(graduationRequirements[moduleRequirementTitle[5]]).length > 0)  {
    UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[5]].name,
                                                                   graduationRequirements[moduleRequirementTitle[5]].markedMathSciModules,
                                                                   graduationRequirements[moduleRequirementTitle[5]].isFulfilled));
  }

  // find unrestricted-electives requirement modules objects
    // pass in required number of MCs from each requirement checks earlier,
    // pass in semesters
    let totalRequiredMCs = 0
    for (var i=0; i<moduleRequirementTitle.length-1; i++) {
      totalRequiredMCs += graduationRequirements[moduleRequirementTitle[i]].requiredMCs;
    }
    graduationRequirements[moduleRequirementTitle[7]] = findUnrestrictedElectivesRequirementModules(totalRequiredMCs, graduationMCs, studentSemesters);
    UIFormatGraduationRequirement.children.push(UIFormatConversion(moduleRequirementTitle[7], [], graduationRequirements[moduleRequirementTitle[7]]));

  return UIFormatGraduationRequirement;
}

/**
* retrieves an object of UI formatted graduation requirements
*  @param {string}  name of requirement
*  @param {object}  the marked modules
*  @param {boolean}  boolean that states if module has been fulfilled or not
*  @return {{objects}}  UI formatted list of one requirements
*
*/

const UIFormatConversion = function UIFormatConversion(name, markedModules, isFulfilled) {
  let tempGradRequirement = {};
  switch(name)  {
    case 'Unrestricted Electives':
    tempGradRequirement = {
      name: name,
      children: [],
      isFulfilled: isFulfilled
    }
    break;

    default:
    tempGradRequirement = {
      name: name,
      children: [],
      isFulfilled: false
    }
    tempGradRequirement = createUIFormat(tempGradRequirement, markedModules);
    tempGradRequirement.isFulfilled = isFulfilled;
    break;
  }

  return tempGradRequirement;
}

/**
* retrieves an object of UI formatted graduation requirements for a focus area
*  @param {object}  focus area object containing all the graduation requirements for 1 focus area
*  @return {{objects}}  UI formatted list of one requirements
*
*/
const UIFormatFocusAreaConversion = function UIFormatFocusAreaConversion(oneFocusArea)  {
  let tempGradRequirement = {
    name: oneFocusArea.name,
    children: [],
    isFulfilled: false
  }
  // create primary here
  let primaryModules =  {
    name: 'Focus Area Primary',
    children: [],
    isFulfilled: false
  }
  primaryModules = createUIFormat(primaryModules, oneFocusArea.markedFocusAreaPrimaryModules);
  primaryModules.isFulfilled = oneFocusArea.threePrimaryModules;

  // create 4k here
  let fourThousandModules =  {
    name: 'Focus Area Primary 4K and above',
    children: [],
    isFulfilled: false
  }
  fourThousandModules = createUIFormat(fourThousandModules, oneFocusArea.markedFocusAreaPrimary4KModules);
  fourThousandModules.isFulfilled = oneFocusArea.one4KModules;

  tempGradRequirement.children.push(primaryModules);
  tempGradRequirement.children.push(fourThousandModules);
  tempGradRequirement.isFulfilled = oneFocusArea.isPrimaryTrue;

  return tempGradRequirement;
}

/**
* retrieves an object of UI formatted marked graduation requirement
*  @param {object}  parent grad requirement object
*  @param {object}  an object containing a list of modules in the format of modueCode:bool
*  @return {{objects}}  UI formatted list for one set of marked requirements
*
*/
const createUIFormat = function createUIFormat(tempGradRequirement, modules)  {
  const keys = Object.keys(modules);

  for (var i=0; i<keys.length; i++)  {
    let gradRequirement = {
      name: keys[i],
      children: [],
      isFulfilled: modules[keys[i]]
    }
    tempGradRequirement.children.push(gradRequirement);
  }

  return tempGradRequirement;
}
<commit_msg>Update AY1415GradCheckerHandler.js<commit_after>import { getCohortByName } from '../../../../../../database-controller/AcademicCohort/methods';
import { getGradRequirementModules,
         getGradRequirementMCs } from '../../../../../../database-controller/graduation-requirement/methods';
import { getFocusAreaPrimaryRequirement,
         getFocusArea4KRequirement,
         getFocusAreaNonPrimaryRequirement,
         getFocusAreaPrimary4KRequirement } from '../../../../../../database-controller/focus-area/methods';
import { findFoundationRequirementModules } from './foundation/methods';
import { findITProfessionalismModules } from './IT-professionalism/methods';
import { findMathSciRequirementModules } from './math-science/methods';
import { findTeamProjectRequirementModules } from './breadth-depth/team-project/methods';
import { findIndustrialExperienceTrainingModules } from './breadth-depth/industrial-experience/methods';
import { checkFocusAreaFulfilmentMCs,
         findFocusAreaModules } from './breadth-depth/focus-area/methods';
import { findULRRequirementModules } from '../../../../university-level-requirements/AY-1415/methods';
import { findUnrestrictedElectivesRequirementModules } from './unrestricted-electives/methods';

/* Explanation for new AY creation
 * Grad checker handler retrieves all the graduation requirements from each of the
 * sub requirements.
 * It also converts the graduation format to fit the display format
 *
 * Thus, you should only modify the UI conversion method if any of the grad requirements
 * changes its form from the UI display format
 *
 * UI display JSON format:
 * Requirement {
 *  name:
 *  children:
 *  isFulfilled:
 * }
 *
 * name -> name of what will be displayed on the screen
 * children -> array of JSON as displayed under the "Requirement"
 * isFulfilled -> is the current JSON has fulfilled. All children must be fulfilled
 *                for the current JSON to be fulfilled
 */

/**
* retrieves an object of string boolean objects for each graduation requirement
*  @param {objects}  a full appended object list of all the modules in a student planner
*  @param {number}  current student academic year
*  @param {objects}  modules which are exempted by student
*  @param {objects}  modules which are waived by student
*  @return {{objects}}  UI formatted list of graduation requirements
*
*/
export const AY1415CSGradChecker = function AY1415CSGradChecker(studentSemesters, studentAcademicCohort, studentExemptedModules, studentWaivedModules) {
  const graduationMCs = 160;
  const moduleRequirementTitle = ['Computer Science Foundation',
                                  'Computer Science Focus Area',
                                  'Computer Systems Team Project',
                                  'Industrial Experience Training',
                                  'IT Professionalism','Mathematics and Sciences',
                                  'University Level Requirement', 'Unrestricted Electives'];
  const focusAreaTitles = ['Algorithms & Theory', 'Artificial Intelligence',
                           'Computer Graphics and Games', 'Computer Security',
                           'Database Systems', 'Multimedia Information Retrieval',
                           'Networking and Distributed Systems', 'Parallel Computing',
                           'Programming Languages', 'Software Engineering', 'Interactive Media',
                           'Visual Computing'];

  let graduationRequirements = {};

  let UIFormatGraduationRequirement = {
    name: 'Graduation Requirements',
    children: [],
    isFulfilled: false
  };

  if (!studentSemesters) {
    return graduationRequirements;
  }

  const cohortInformation = getCohortByName(studentAcademicCohort);

  if (!cohortInformation) {
    return graduationRequirements;
  }

  // retrieve foundation, IT-professionalism, Math-Sci and Breadth and Depth requirements here
  const cohortGradRequirementIDs = cohortInformation.cohortGradRequirementID;
  const allGradRequirements = getGradRequirementModules(cohortGradRequirementIDs);
  const allGraduationRequirementMCs = getGradRequirementMCs(cohortGradRequirementIDs);

  // retrieve focus area modules
  const allFocusAreaPrimaryRequirements = getFocusAreaPrimaryRequirement(cohortInformation.cohortFocusAreaID);
  const allFocusArea4KRequirements = getFocusArea4KRequirement(cohortInformation.cohortFocusAreaID);
  const allFocusArea4KPrimaryRequirements = getFocusAreaPrimary4KRequirement(cohortInformation.cohortFocusAreaID);
  const allFocusAreaNonPrimaryRequirements = getFocusAreaNonPrimaryRequirement(cohortInformation.cohortFocusAreaID);

  if (Object.keys(allGradRequirements).length === 0 || !allGradRequirements ||
      !allGraduationRequirementMCs) {
    return graduationRequirements;
  }

  // append objects of string:bool objects into a list of objects and return to UI
  for (var i=0; i<moduleRequirementTitle.length; i++) {
    graduationRequirements[moduleRequirementTitle[i]] = {};
  }

  /*
   * Send all planner information to every requirement check
   */

  // find university-level-requirements here
  const ULRRequirements = allGradRequirements[moduleRequirementTitle[6]];
  const requiredMCsULR = allGraduationRequirementMCs[moduleRequirementTitle[6]];
  graduationRequirements[moduleRequirementTitle[6]] = findULRRequirementModules(studentAcademicCohort, studentSemesters, ULRRequirements, studentExemptedModules, studentWaivedModules, requiredMCsULR);
  if (Object.keys(graduationRequirements[moduleRequirementTitle[6]]).length > 0)  {
  UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[6]].name,
                                                                 graduationRequirements[moduleRequirementTitle[6]].markedULRModules,
                                                                 graduationRequirements[moduleRequirementTitle[6]].isFulfilled));
  }

  // find foundation requirement modules objects and call function from relevant academic year
  const foundationRequirements = allGradRequirements[moduleRequirementTitle[0]];
  const requiredMCsFoundation = allGraduationRequirementMCs[moduleRequirementTitle[0]];
  graduationRequirements[moduleRequirementTitle[0]] = findFoundationRequirementModules(studentAcademicCohort, studentSemesters, foundationRequirements, studentExemptedModules, studentWaivedModules, requiredMCsFoundation);
  if (Object.keys(graduationRequirements[moduleRequirementTitle[0]]).length > 0)  {
    UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[0]].name,
                                                                   graduationRequirements[moduleRequirementTitle[0]].markedFoundationModules,
                                                                   graduationRequirements[moduleRequirementTitle[0]].isFulfilled));
  }

  // find computer science breadth and depth requirement modules
    // find focus area requirement modules object
    let focusAreaMCSFulfilment = {};
    let focusAreaRequirements = {
      name: moduleRequirementTitle[1],
      children: [],
      isFulfilled: false
    };

    let focusAreaPrimaries = {
      name: "Area Primaries",
      children: [],
      isFulfilled: false
    }

    let focusAreaAtLeast12MCs = {
      name: "At least 12 MCs of 4K modules",
      children: [],
      isFulfilled: false
    }

    const allStudentFocusAreas = {
      focusAreaPrimaryModules: allFocusAreaPrimaryRequirements,
      focusArea4KModules: allFocusArea4KRequirements,
      focusAreaPrimary4KModules :allFocusArea4KPrimaryRequirements,
      focusAreaNonPrimaryModules: allFocusAreaNonPrimaryRequirements
    };

    // for all focus area, find the ones fulfilled by the current planner
    for (var i=0; i<focusAreaTitles.length; i++)  {
      let focusArea = {
        focusAreaPrimaryModules: allStudentFocusAreas.focusAreaPrimaryModules[focusAreaTitles[i]],
        focusArea4KModules: allStudentFocusAreas.focusArea4KModules[focusAreaTitles[i]],
        focusAreaPrimary4KModules: allStudentFocusAreas.focusAreaPrimary4KModules[focusAreaTitles[i]],
        focusAreaNonPrimaryModules: allStudentFocusAreas.focusAreaNonPrimaryModules[focusAreaTitles[i]]
      }

      if (!focusArea.focusAreaPrimaryModules || !focusArea.focusArea4KModules || !focusArea.focusArea4KModules)  {
        continue;
      }

      let oneFocusArea = findFocusAreaModules(focusAreaTitles[i], studentAcademicCohort, studentSemesters, focusArea, studentExemptedModules, studentWaivedModules);
      focusAreaPrimaries.children.push(UIFormatFocusAreaConversion(oneFocusArea));
      if (oneFocusArea.isPrimaryTrue)  {
        focusAreaPrimaries.isFulfilled = true;
      }
      if (oneFocusArea.is4KTrue) {
        focusAreaAtLeast12MCs.isFulfilled = true;
      }
    }

    // check if student planner meet 24 MCs requirement
    focusAreaMCSFulfilment = checkFocusAreaFulfilmentMCs(studentSemesters, allStudentFocusAreas, allGraduationRequirementMCs[moduleRequirementTitle[1]]);
    graduationRequirements[moduleRequirementTitle[1]] = focusAreaMCSFulfilment;

    if (focusAreaPrimaries.isFulfilled && focusAreaAtLeast12MCs.isFulfilled &&
        focusAreaMCSFulfilment.isFulfilled)  {
      focusAreaRequirements.isFulfilled =  true;
    }

    focusAreaRequirements.children.push(focusAreaPrimaries);
    focusAreaRequirements.children.push(focusAreaAtLeast12MCs);
    UIFormatGraduationRequirement.children.push(focusAreaRequirements);

    //console.log(JSON.stringify(UIFormatGraduationRequirement));

    // find computer systems team project requirement modules
    const teamProjectRequirements = allGradRequirements[moduleRequirementTitle[2]];
    const requiredMCsTeamProject = allGraduationRequirementMCs[moduleRequirementTitle[2]];
    graduationRequirements[moduleRequirementTitle[2]] = findTeamProjectRequirementModules(studentAcademicCohort, studentSemesters, teamProjectRequirements, studentExemptedModules, studentWaivedModules, requiredMCsTeamProject);
    if (Object.keys(graduationRequirements[moduleRequirementTitle[2]]).length > 0)  {
      UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[2]].name,
                                                                     graduationRequirements[moduleRequirementTitle[2]].markedTeamProjectModules,
                                                                     graduationRequirements[moduleRequirementTitle[2]].isFulfilled));
    }

    // find Industrial experience training requirement modules
    const industrialExperienceRequirements = allGradRequirements[moduleRequirementTitle[3]];
    const requiredMCsIndustrialExperience = allGraduationRequirementMCs[moduleRequirementTitle[3]];
    graduationRequirements[moduleRequirementTitle[3]] = findIndustrialExperienceTrainingModules(studentAcademicCohort, studentSemesters, industrialExperienceRequirements, studentExemptedModules, studentWaivedModules, requiredMCsIndustrialExperience);
    if (Object.keys(graduationRequirements[moduleRequirementTitle[3]]).length > 0)  {
      UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[3]].name,
                                                                     graduationRequirements[moduleRequirementTitle[3]].markedIndustrialExperienceTrainingModules,
                                                                     graduationRequirements[moduleRequirementTitle[3]].isFulfilled));
    }

  // find IT-professionalism requirement modules objects
  const ITRequirements = allGradRequirements[moduleRequirementTitle[4]];
  const requiredMCsIT = allGraduationRequirementMCs[moduleRequirementTitle[4]];
  graduationRequirements[moduleRequirementTitle[4]] = findITProfessionalismModules(studentAcademicCohort, studentSemesters, ITRequirements, studentExemptedModules, studentWaivedModules, requiredMCsIT);
  if (Object.keys(graduationRequirements[moduleRequirementTitle[4]]).length > 0)  {
    UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[4]].name,
                                                                   graduationRequirements[moduleRequirementTitle[4]].markedITProfessionalismModules,
                                                                   graduationRequirements[moduleRequirementTitle[4]].isFulfilled));
  }

  // find math-science requirement modules objects
  const mathScienceRequirements = allGradRequirements[moduleRequirementTitle[5]];
  const requiredMCsMathSci = allGraduationRequirementMCs[moduleRequirementTitle[5]];
  graduationRequirements[moduleRequirementTitle[5]] = findMathSciRequirementModules(studentAcademicCohort, studentSemesters, mathScienceRequirements, studentExemptedModules, studentWaivedModules, requiredMCsMathSci);
  if (Object.keys(graduationRequirements[moduleRequirementTitle[5]]).length > 0)  {
    UIFormatGraduationRequirement.children.push(UIFormatConversion(graduationRequirements[moduleRequirementTitle[5]].name,
                                                                   graduationRequirements[moduleRequirementTitle[5]].markedMathSciModules,
                                                                   graduationRequirements[moduleRequirementTitle[5]].isFulfilled));
  }

  // find unrestricted-electives requirement modules objects
    // pass in required number of MCs from each requirement checks earlier,
    // pass in semesters
    let totalRequiredMCs = 0
    for (var i=0; i<moduleRequirementTitle.length-1; i++) {
      totalRequiredMCs += graduationRequirements[moduleRequirementTitle[i]].requiredMCs;
    }
    graduationRequirements[moduleRequirementTitle[7]] = findUnrestrictedElectivesRequirementModules(totalRequiredMCs, graduationMCs, studentSemesters);
    UIFormatGraduationRequirement.children.push(UIFormatConversion(moduleRequirementTitle[7], [], graduationRequirements[moduleRequirementTitle[7]]));

  return UIFormatGraduationRequirement;
}

/**
* retrieves an object of UI formatted graduation requirements
*  @param {string}  name of requirement
*  @param {object}  the marked modules
*  @param {boolean}  boolean that states if module has been fulfilled or not
*  @return {{objects}}  UI formatted list of one requirements
*
*/

const UIFormatConversion = function UIFormatConversion(name, markedModules, isFulfilled) {
  let tempGradRequirement = {};
  switch(name)  {
    case 'Unrestricted Electives':
    tempGradRequirement = {
      name: name,
      children: [],
      isFulfilled: isFulfilled
    }
    break;

    default:
    tempGradRequirement = {
      name: name,
      children: [],
      isFulfilled: false
    }
    tempGradRequirement = createUIFormat(tempGradRequirement, markedModules);
    tempGradRequirement.isFulfilled = isFulfilled;
    break;
  }

  return tempGradRequirement;
}

/**
* retrieves an object of UI formatted graduation requirements for a focus area
*  @param {object}  focus area object containing all the graduation requirements for 1 focus area
*  @return {{objects}}  UI formatted list of one requirements
*
*/
const UIFormatFocusAreaConversion = function UIFormatFocusAreaConversion(oneFocusArea)  {
  let tempGradRequirement = {
    name: oneFocusArea.name,
    children: [],
    isFulfilled: false
  }
  // create primary here
  let primaryModules =  {
    name: 'Focus Area Primary',
    children: [],
    isFulfilled: false
  }
  primaryModules = createUIFormat(primaryModules, oneFocusArea.markedFocusAreaPrimaryModules);
  primaryModules.isFulfilled = oneFocusArea.threePrimaryModules;

  // create 4k here
  let fourThousandModules =  {
    name: 'Focus Area Primary 4K and above',
    children: [],
    isFulfilled: false
  }
  fourThousandModules = createUIFormat(fourThousandModules, oneFocusArea.markedFocusAreaPrimary4KModules);
  fourThousandModules.isFulfilled = oneFocusArea.one4KModules;

  tempGradRequirement.children.push(primaryModules);
  tempGradRequirement.children.push(fourThousandModules);
  tempGradRequirement.isFulfilled = oneFocusArea.isPrimaryTrue;

  return tempGradRequirement;
}

/**
* retrieves an object of UI formatted marked graduation requirement
*  @param {object}  parent grad requirement object
*  @param {object}  an object containing a list of modules in the format of modueCode:bool
*  @return {{objects}}  UI formatted list for one set of marked requirements
*
*/
const createUIFormat = function createUIFormat(tempGradRequirement, modules)  {
  const keys = Object.keys(modules);

  for (var i=0; i<keys.length; i++)  {
    let gradRequirement = {
      name: keys[i],
      children: [],
      isFulfilled: modules[keys[i]]
    }
    tempGradRequirement.children.push(gradRequirement);
  }

  return tempGradRequirement;
}
<|endoftext|>


<commit_before>/*

// the full question list
var questions = [["Find the textbook title 'Anthropologist on Mars'."],  // 0
                 ["Find a book by Hemingway, Ernest as an author."],  // 1
                 [ "Check to see if the book The Goldfinch is available to borrow for a four week period."], // 2
                 ["Search for scholarly articles on 'community college students'."],  // 3
                 ["Find the database 'Academic Search Complete'."],  // 4
                 ["Find the database 'JSTOR'."],  // 5
                 ["Find circulation policies."],  // 6
                 ["Calculate fines for a book that is five days overdue."], // 7
                 ["Find the library hours for the Spring semester of 2017."],  // 8
                 ["Use the 'Ask a Librarian' menu."],  // 9
                 ["Search to see if a document is available on eReserve."],  // 10
                 ["Open a new interlibrary loan account."],  // 11
                 ["Request an interlibrary loan."],  // 12
                 ["Find the library's Twitter feed."],  // 13
                 ["Find the library's Goodreads profile."]]  // 14
*/

// the urls for the activities, with random questions
var urls = ["http://kbcc.cuny.libguides.com/prototype1?questiongroup=0",
            "http://kbcc.cuny.libguides.com/prototype4?questiongroup=1",
            "http://kbcc.cuny.libguides.com/prototype5?questiongroup=2",
            "http://kbcc.cuny.libguides.com/prototype6?questiongroup=3",
            "http://kbcc.cuny.libguides.com/prototype8?questiongroup=4"]

// make the table using js
var tableHTML1 = '

Activity #';
var tableHTML2 = ' Try it now!

';

$(document).ready(function() {
	for (i = 0; i < urls.length; i++) {
		$("tbody").append(tableHTML1 + parseInt(i + 1) + tableHTML2 + i + tableHTML3);
        document.getElementById(i).href = urls[i];
	};
    $(".btn").click(function() {
        $(this).text('completed!').removeClass('active').addClass('disabled');
    });
});
<commit_msg>used multiple windows approach, non-randomized, for use with pythonanywhere<commit_after>// the full question list
var questions = [["Find the textbook title 'Anthropologist on Mars'."],  // 0
                 ["Find a book by Hemingway, Ernest as an author."],  // 1
                 [ "Check to see if the book The Goldfinch is available to borrow for a four week period."], // 2
                 ["Search for scholarly articles on 'community college students'."],  // 3
                 ["Find the database 'Academic Search Complete'."],  // 4
                 ["Find the database 'JSTOR'."],  // 5
                 ["Find circulation policies."],  // 6
                 ["Calculate fines for a book that is five days overdue."], // 7
                 ["Find the library hours for the Spring semester of 2017."],  // 8
                 ["Use the 'Ask a Librarian' menu."],  // 9
                 ["Search to see if a document is available on eReserve."],  // 10
                 ["Open a new interlibrary loan account."],  // 11
                 ["Request an interlibrary loan."],  // 12
                 ["Find the library's Twitter feed."],  // 13
                 ["Find the library's Goodreads profile."]]  // 14

// the urls for the activities, with random questions
var urls = ["http://kbcc.cuny.libguides.com/prototype9",
            "http://kbcc.cuny.libguides.com/prototype10",
            "http://kbcc.cuny.libguides.com/prototype11",
            "http://kbcc.cuny.libguides.com/prototype12",
            "http://kbcc.cuny.libguides.com/prototype13"]

// make the table using js
var tableHTML1 = '

Activity #';
var tableHTML2 = ' Try it now!

';

// set some variables in preparation for gotoactivity()
var startHTML = '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
Activity #'
var midHTML = '

';
var endHTML = '
';
var timer = undefined;

// what to do when the user clicks on an activity
function gotoactivity(id) {
    displayid = parseInt(id) + 1;
    var instructions = window.open('', 'instructions', 'left=20,top=20,width=160,height=300,menubar=no,titlebar=no');
    var workspace = window.open(urls[id], 'workspace', 'left=200,top=20,width=1195,height=750,menubar=no,titlebar=no,scrollbars=yes');
    instructions.document.body.innerHTML = startHTML + displayid + midHTML + questions[id] + endHTML;

    // closes one window when the other is closed
    timer = setInterval(function() {
        $(this).focus(function() {
            workspace.close();
            instructions.close();
        });
        if (instructions.closed) {
            workspace.close();
            clearInterval(timer);
        }
        else if (workspace.closed) {
            instructions.close();
            clearInterval(timer);
        }
    }, 50);
};

$(document).ready(function() {
	for (i = 0; i < urls.length; i++) {
		$("tbody").append(tableHTML1 + parseInt(i + 1) + tableHTML2 + i + tableHTML3 + i + tableHTML4);
	};
    $(".btn").click(function() {
        $(this).text('completed!').removeClass('active').addClass('disabled');
    });
});

<|endoftext|>


<commit_before>// Setup your quiz text and questions here

// NOTE: pay attention to commas, IE struggles with those bad boys

var quizJSON = {
    "info": {
        "name":    "Test Your Knowledge!!",
        "main":    "
Think you're smart enough to be on Jeopardy? Find out with this super crazy knowledge quiz!
",
        "results": "
Learn More

Etiam scelerisque, nunc ac egestas consequat, odio nibh euismod nulla, eget auctor orci nibh vel nisi. Aliquam erat volutpat. Mauris vel neque sit amet nunc gravida congue sed sit amet purus.
",
        "level1":  "Jeopardy Ready",
        "level2":  "Jeopardy Contender",
        "level3":  "Jeopardy Amateur",
        "level4":  "Jeopardy Newb",
        "level5":  "Stay in school, kid..." // no comma here
    },
    "questions": [
        { // Question 1 - Multiple Choice, Single True Answer
            "q": "What number is the letter A in the English alphabet?",
            "a": [
                {"option": "8",      "correct": false},
                {"option": "14",     "correct": false},
                {"option": "1",      "correct": true},
                {"option": "23",     "correct": false} // no comma here
            ],
            "correct": "
That's right! The letter A is the first letter in the alphabet!
",
            "incorrect": "
Uhh no. It's the first letter of the alphabet. Did you actually go to kindergarden?
" // no comma here
        },
        { // Question 2 - Multiple Choice, Multiple True Answers, Select Any
            "q": "Which of the following best represents your preferred breakfast?",
            "a": [
                {"option": "Bacon and eggs",               "correct": false},
                {"option": "Fruit, oatmeal, and yogurt",   "correct": true},
                {"option": "Leftover pizza",               "correct": false},
                {"option": "Eggs, fruit, toast, and milk", "correct": true} // no comma here
            ],
            "select_any": true,
            "correct": "
Nice! Your cholestoral level is probably doing alright.
",
            "incorrect": "
Hmmm. You might want to reconsider your options.
" // no comma here
        },
        { // Question 3 - Multiple Choice, Multiple True Answers, Select All
            "q": "Where are you right now? Select ALL that apply.",
            "a": [
                {"option": "Planet Earth",           "correct": true},
                {"option": "Pluto",                  "correct": false},
                {"option": "At a computing device",  "correct": true},
                {"option": "The Milky Way",          "correct": true} // no comma here
            ],
            "correct": "
Brilliant! You're seriously a genius, (wo)man.
",
            "incorrect": "
Not Quite. You're actually on Planet Earth, in The Milky Way, At a computer. But nice try.
" // no comma here
        },
        { // Question 4
            "q": "How many inches of rain does Michigan get on average per year?",
            "a": [
                {"option": "149",    "correct": false},
                {"option": "32",     "correct": true},
                {"option": "3",      "correct": false},
                {"option": "1291",   "correct": false} // no comma here
            ],
            "correct": "
Holy bananas! I didn't actually expect you to know that! Correct!
",
            "incorrect": "
Fail. Sorry. You lose. It actually rains approximately 32 inches a year in Michigan.
" // no comma here
        },
        { // Question 5
            "q": "Is Earth bigger than a basketball?",
            "a": [
                {"option": "Yes",    "correct": true},
                {"option": "No",     "correct": false} // no comma here
            ],
            "correct": "
Good Job! You must be very observant!
",
            "incorrect": "
ERRRR! What planet Earth are you living on?!?
" // no comma here
        } // no comma here
    ]
};
<commit_msg>everything but questions fleshed out<commit_after>// Setup your quiz text and questions here

// NOTE: pay attention to commas, IE struggles with those bad boys

var quizJSON = {
    "info": {
        "name":    "Practice for the Technician Amateur Radio Exam!!",
        "main":    "
Think you're smart enough to be on Jeopardy? Find out with this super crazy knowledge quiz!
",
        "results": "
Learn More

Questions for this website were taken from the freely available Technician exam pool at www.ncvec.org/
",
        "level1":  "Test Ready",
        "level2":  "Test Contender",
        "level3":  "Test Amateur",
        "level4":  "Ham Radio Newb",
        "level5":  "Stay in school, kid..." // no comma here
    },
    "questions": [
        { // Question 1 - Multiple Choice, Single True Answer
            "q": "What number is the letter A in the English alphabet?",
            "a": [
                {"option": "8",      "correct": false},
                {"option": "14",     "correct": false},
                {"option": "1",      "correct": true},
                {"option": "23",     "correct": false} // no comma here
            ],
            "correct": "
That's right! The letter A is the first letter in the alphabet!
",
            "incorrect": "
Uhh no. It's the first letter of the alphabet. Did you actually go to kindergarden?
" // no comma here
        },
        { // Question 2 - Multiple Choice, Multiple True Answers, Select Any
            "q": "Which of the following best represents your preferred breakfast?",
            "a": [
                {"option": "Bacon and eggs",               "correct": false},
                {"option": "Fruit, oatmeal, and yogurt",   "correct": true},
                {"option": "Leftover pizza",               "correct": false},
                {"option": "Eggs, fruit, toast, and milk", "correct": true} // no comma here
            ],
            "select_any": true,
            "correct": "
Nice! Your cholestoral level is probably doing alright.
",
            "incorrect": "
Hmmm. You might want to reconsider your options.
" // no comma here
        },
        { // Question 3 - Multiple Choice, Multiple True Answers, Select All
            "q": "Where are you right now? Select ALL that apply.",
            "a": [
                {"option": "Planet Earth",           "correct": true},
                {"option": "Pluto",                  "correct": false},
                {"option": "At a computing device",  "correct": true},
                {"option": "The Milky Way",          "correct": true} // no comma here
            ],
            "correct": "
Brilliant! You're seriously a genius, (wo)man.
",
            "incorrect": "
Not Quite. You're actually on Planet Earth, in The Milky Way, At a computer. But nice try.
" // no comma here
        },
        { // Question 4
            "q": "How many inches of rain does Michigan get on average per year?",
            "a": [
                {"option": "149",    "correct": false},
                {"option": "32",     "correct": true},
                {"option": "3",      "correct": false},
                {"option": "1291",   "correct": false} // no comma here
            ],
            "correct": "
Holy bananas! I didn't actually expect you to know that! Correct!
",
            "incorrect": "
Fail. Sorry. You lose. It actually rains approximately 32 inches a year in Michigan.
" // no comma here
        },
        { // Question 5
            "q": "Is Earth bigger than a basketball?",
            "a": [
                {"option": "Yes",    "correct": true},
                {"option": "No",     "correct": false} // no comma here
            ],
            "correct": "
Good Job! You must be very observant!
",
            "incorrect": "
ERRRR! What planet Earth are you living on?!?
" // no comma here
        } // no comma here
    ]
};
<|endoftext|>


<commit_before>EmuLabeller.Drawer.SpectogramDrawer = {

    init: function (params) {
        var my = this;
        my.myWindow = {
                BARTLETT:       1,
                BARTLETTHANN:   2,
                BLACKMAN:       3,
                COSINE:         4,
                GAUSS:          5,
                HAMMING:        6,
                HANN:           7,
                LANCZOS:        8,
                RECTANGULAR:    9,
                TRIANGULAR:     10
        }

        // various mathematical vars
        my.PI = 3.141592653589793;                        // value : Math.PI
        my.TWO_PI = 6.283185307179586;                    // value : 2 * Math.PI
        my.OCTAVE_FACTOR=3.321928094887363;               // value : 1.0/log10(2)
        my.emphasisPerOctave=3.9810717055349722;          // value : toLinearLevel(6);
        my.dynamicRange=5000;                             // value : toLinearLevel(50);
        my.dynRangeInDB=50;                               // value : toLevelInDB(dynamicRange);
        my.params = params;
        // FFT default vars
        my.N = 512;                                       // default FFT Window Size
        my.alpha = 0.16;                                  // default alpha for Window Function
        my.windowFunction = my.myWindow.BARTLETTHANN;     // default Window Function
        my.sampleRate = 44100;                            // default sample rate
        my.channels = 1;                                  // default number of channels
        my.freq_lower = 0;                                // default upper Frequency
        my.freq = 8000;                                   // default upper Frequency
        my.canvas = params.specCanvas;
        my.context = params.specCanvas.getContext("2d");
        my.pcmperpixel = 0;
        my.myImage = new Image();
        my.font = params.font;
        window.URL = window.URL || window.webkitURL;
        my.devicePixelRatio = window.devicePixelRatio || 1;
        my.response = spectroworker.textContent;
        my.blob;
        try { my.blob = new Blob([my.response], { "type" : "text\/javascript" }); }
        catch (e) { // Backwards-compatibility
                window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
                my.blob.append(my.response);
                my.blob = my.blob.getBlob();
        }
        my.primeWorker = new Worker(URL.createObjectURL(my.blob));
		my.setupEvent();
		my.clearImageCache();

		$("#specDialog").dialog({
         bgiframe: true,
         autoOpen: false,
         width: 500,
         closeOnEscape: true,
         show: 'fade',
         hide: 'fade',
         position: 'center',
         stack: false,
         buttons: {
            OK: function() {
                var nN = $("#windowLength").val();
                var nvrf = $("#viewrange_from").val();
                var nvrt = $("#viewrange_to").val();
                var ndr = $("#dynamicRange").val();
                var nwf = $("#windowFunction").val();
                if (isNaN(nN) || isNaN(nvrf) || isNaN(nvrt) || isNaN(ndr)) {
                    alert("Please enter valid numbers !");
                } else {
                    my.N = parseInt(nN, 10);
                    my.freq = parseInt(nvrt, 10);
                    my.freq_lower = parseInt(nvrf, 10);
                    my.dynRangeInDB = parseInt(ndr, 10);
                    my.windowFunction = parseInt(nwf, 10);
                    my.clearImageCache();
                    my.killSpectroRenderingThread();
                    my.uiDraw();
                    my.drawTimeLine();
                    $(this).dialog('close');
                }
            },
            Cancel: function() {
                $(this).dialog('close');
            }
         }
        });

        },

        setupEvent: function () {
            var my = this;
            my.primeWorker.addEventListener('message', function(event){
            	my.worker_img = event.data.img;
            	my.worker_start = event.data.start;
            	my.worker_end = event.data.end;
            	my.worker_cache_width = event.data.cacheWidth;
            	my.worker_cache_side = event.data.cacheSide;
                my.render_width = my.canvas.width - my.worker_cache_width;
                my.myImage.onload = function() {
                    if(my.worker_cache_side==0)
    	    	        my.context.drawImage(my.myImage, 0, 0, my.canvas.width, my.canvas.height, 0, 0, my.canvas.width, my.canvas.height);
    	    	    if(my.worker_cache_side==1)
    	    	        my.context.drawImage(my.myImage, 0, 0, my.render_width, my.canvas.height, 0, 0, my.render_width, my.canvas.height);
    	    	    if(my.worker_cache_side==2)
    	    	        my.context.drawImage(my.myImage, my.worker_cache_width, 0, my.render_width, my.canvas.height, my.worker_cache_width, 0, my.render_width, my.canvas.height);

    	    	    my.buildImageCache(my.worker_start,my.worker_end,my.canvas.toDataURL("image/png"));
    	    	    my.drawTimeLineContext();
                }
                my.myImage.src = my.worker_img;

            });
        },

        buildImageCache: function (cstart,cend,imgData) {
            var my = this;
    	    if(my.imageCache[my.pcmperpixel]==null)
    	    	my.imageCache[my.pcmperpixel] = new Array();

    	    if(my.imageCacheCounter[my.pcmperpixel]==null)
    	        my.imageCacheCounter[my.pcmperpixel] = 0;

    	    if(my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]]==null) {
    	    	my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]] = new Array();
    	    	my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]][0] = cstart;
    	    	my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]][1] = cend;
    	    	my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]][2] = imgData;
    	    	++my.imageCacheCounter[my.pcmperpixel];
    	    }
        },

        drawTimeLineContext: function () {
            var my = this;
            var posS = emulabeller.viewPort.getPos(my.canvas.width, emulabeller.viewPort.selectS);
            var posE = emulabeller.viewPort.getPos(my.canvas.width, emulabeller.viewPort.selectE);
            var sDist = emulabeller.viewPort.getSampleDist(my.canvas.width);
            var curPos = posS + sDist / 2;
            if(curPos!=0 &&  emulabeller.viewPort.selectS==emulabeller.viewPort.selectE) {
                my.context.fillStyle = my.params.selectLineColor;
                my.context.fillRect(curPos, 0, 1, my.canvas.height);
            }
            if (curPos!=0 && emulabeller.viewPort.selectS!=emulabeller.viewPort.selectE){
                my.context.fillStyle = my.params.selectedAreaColor;
                my.context.fillRect(posS, 0, posE-posS+sDist, my.canvas.height);
                my.context.strokeStyle = my.params.selectLineColor;
                my.context.beginPath();
                my.context.moveTo(posS,0);
                my.context.lineTo(posS,my.canvas.height);
                my.context.moveTo(posE+sDist,0);
                my.context.lineTo(posE+sDist,my.canvas.height);
                my.context.closePath();
                my.context.stroke();
            }
        },

        drawTimeLine: function (){
            var my = this;
            var image = new Image();
            image.onload = function() {
                my.context.drawImage(image, 0, 0);
                my.drawTimeLineContext();
            };
            image.src = this.myImage.src;
        },

        killSpectroRenderingThread: function () {
            var my = this;
            my.context.fillStyle = my.params.selectedBorderColor;
        	my.context.fillRect(0,0,my.canvas.width,my.canvas.height);
        	my.context.font = my.params.fontPxSize+"px "+my.params.fontType;
        	my.context.fillStyle = my.params.loadingBackground;
        	my.context.fillText(my.params.loadingText, 10, 25);
            if(my.primeWorker!=null) {
            	my.primeWorker.terminate();
        		my.primeWorker = null;
        	}
        },

        clearImageCache: function () {
            var my = this;
            my.imageCache = null;
            my.imageCacheCounter = null;
            my.imageCache = new Array();
            my.imageCacheCounter = new Array();
        },

        uiDraw: function() {
            var my = this;
            my.newpcmperpixel = Math.round((emulabeller.viewPort.eS-emulabeller.viewPort.sS)/my.canvas.width);
            if(my.imageCache!=null) {
                if(my.imageCache[my.newpcmperpixel]!=null) {
					//my.found_parts = false;
					//my.pixel_covering = 0;
					//my.pixel_cache_selected = 0;

                    for (var i = 0; i < my.imageCache[my.newpcmperpixel].length; ++i) {
                        // check for complete image
                    	if(my.imageCache[my.newpcmperpixel][i][0]==emulabeller.viewPort.sS &&
                    	   my.imageCache[my.newpcmperpixel][i][1]==emulabeller.viewPort.eS) {
    	    	            my.myImage.src = my.imageCache[my.newpcmperpixel][i][2];
    	    	            my.drawTimeLine();
    	    	            return;
                    	}
                    }
            	    my.killSpectroRenderingThread();
                    my.startSpectroRenderingThread();
                }
                else {
            	    my.killSpectroRenderingThread();
                    my.startSpectroRenderingThread();
                }
            }
                    	/* check for cache on left side
                        if(my.imageCache[my.newpcmperpixel][i][0] > emulabeller.viewPort.sS &&
                    	    my.imageCache[my.newpcmperpixel][i][0] < emulabeller.viewPort.eS) {
                    	    my.pixel_cover = Math.floor((my.myend-my.imageCache[my.newpcmperpixel][i][0])/my.newpcmperpixel);
                    	    if(my.pixel_cover > my.pixel_covering ) {
                			    my.pixel_covering = my.pixel_cover;
                		        my.pixel_cache_selected = i;
                		        my.pixel_side = 1;
                    		    my.found_parts = true;
                    		}
                    	}

                    	// check for image on right side
                        if(my.imageCache[my.newpcmperpixel][i][1] > emulabeller.viewPort.sS &&
                	        my.imageCache[my.newpcmperpixel][i][1] < emulabeller.viewPort.eS) {
                		    my.pixel_cover = Math.floor((my.imageCache[my.newpcmperpixel][i][1]-my.mystart)/my.newpcmperpixel);
                		    if(my.pixel_cover > my.pixel_covering ) {
                			    my.pixel_covering = my.pixel_cover;
                		        my.pixel_cache_selected = i;
                    		    my.pixel_side = 2;
                    		    my.found_parts = true;
                    	    }
                        }
                    }
                   f(my.found_parts && my.pixel_covering > 0) {
                    	my.killSpectroRenderingThread();
                	    my.tempImage = new Image(my.pixel_covering,my.canvas.height);

                        if(my.pixel_side==1) {
                            my.tempImage.onload = function() {
    	    	                my.context.drawImage(my.tempImage,                         // image
    	    	                                     0, 0,                                     // sx,sy
    	    	                                     my.canvas.width,my.canvas.height,       // swidth, sheight
    	    	                                     (my.canvas.width-my.pixel_covering),0,    // x,y
    	    	                                     my.canvas.width,my.canvas.height);      // width, height
                            }
                            my.startSpectroRenderingThread(mybuf,
                                                           my.mystart,my.myend,
                                                           my.canvas.width,my.canvas.height,
                                                           my.pixel_covering,1);

                    	}

                        if(my.pixel_side==2) {
                            my.tempImage.onload = function() {
    	    	                my.context.drawImage(my.tempImage,                          // image
    	    	                                     (my.canvas.width-my.pixel_covering), 0,    // sx,sy
    	    	                                     my.pixel_covering,my.canvas.height,        // swidth, sheight
    	    	                                     0,0,                                       // x,y
    	    	                                     my.pixel_covering,my.canvas.height);       // width, height
                            }
                            my.startSpectroRenderingThread(mybuf,
                                                           my.mystart,my.myend,
                                                           my.canvas.width,my.canvas.height,
                                                           my.pixel_covering,2);
                    	}
                    	my.tempImage.src = my.imageCache[my.newpcmperpixel][my.pixel_cache_selected][2];

                    }

                    else {    // image has to be rendered completely
                    //}
                }*/
                else {    // image has to be rendered completely
                    my.killSpectroRenderingThread();
                    my.startSpectroRenderingThread();
                }
        },

        startSpectroRenderingThread: function () {
            var my = this;

            my.pcmperpixel = Math.round((emulabeller.viewPort.eS-emulabeller.viewPort.sS)/my.canvas.width);
            my.primeWorker = new Worker(URL.createObjectURL(my.blob));
            my.setupEvent();

            my.primeWorker.postMessage({'cmd': 'config', 'N': my.N});
            my.primeWorker.postMessage({'cmd': 'config', 'alpha': my.alpha});
            my.primeWorker.postMessage({'cmd': 'config', 'freq': my.freq});
            my.primeWorker.postMessage({'cmd': 'config', 'freq_low': my.freq_lower});
            my.primeWorker.postMessage({'cmd': 'config', 'start': Math.round(emulabeller.viewPort.sS)});
            my.primeWorker.postMessage({'cmd': 'config', 'end': Math.round(emulabeller.viewPort.eS)});
            my.primeWorker.postMessage({'cmd': 'config', 'myStep': my.pcmperpixel});
            my.primeWorker.postMessage({'cmd': 'config', 'window': my.windowFunction});
            my.primeWorker.postMessage({'cmd': 'config', 'cacheSide': 0});
            my.primeWorker.postMessage({'cmd': 'config', 'width': my.canvas.width});
            my.primeWorker.postMessage({'cmd': 'config', 'height': my.canvas.height});
            my.primeWorker.postMessage({'cmd': 'config', 'cacheWidth': 0});
            my.primeWorker.postMessage({'cmd': 'config', 'dynRangeInDB': my.dynRangeInDB});
            my.primeWorker.postMessage({'cmd': 'config', 'pixelRatio': my.devicePixelRatio});
            my.primeWorker.postMessage({'cmd': 'pcm', 'config': JSON.stringify(emulabeller.backend.currentBuffer)});
            my.primeWorker.postMessage({'cmd': 'pcm', 'stream': emulabeller.backend.currentBuffer.getChannelData(0).subarray(emulabeller.viewPort.sS, emulabeller.viewPort.eS+(2*my.N))});
            my.primeWorker.postMessage({'cmd': 'render'});
        }
};

<commit_msg>fixed selection on spectro tier<commit_after>EmuLabeller.Drawer.SpectogramDrawer = {

    init: function (params) {
        var my = this;
        my.myWindow = {
                BARTLETT:       1,
                BARTLETTHANN:   2,
                BLACKMAN:       3,
                COSINE:         4,
                GAUSS:          5,
                HAMMING:        6,
                HANN:           7,
                LANCZOS:        8,
                RECTANGULAR:    9,
                TRIANGULAR:     10
        }

        // various mathematical vars
        my.PI = 3.141592653589793;                        // value : Math.PI
        my.TWO_PI = 6.283185307179586;                    // value : 2 * Math.PI
        my.OCTAVE_FACTOR=3.321928094887363;               // value : 1.0/log10(2)
        my.emphasisPerOctave=3.9810717055349722;          // value : toLinearLevel(6);
        my.dynamicRange=5000;                             // value : toLinearLevel(50);
        my.dynRangeInDB=50;                               // value : toLevelInDB(dynamicRange);
        my.params = params;
        // FFT default vars
        my.N = 512;                                       // default FFT Window Size
        my.alpha = 0.16;                                  // default alpha for Window Function
        my.windowFunction = my.myWindow.BARTLETTHANN;     // default Window Function
        my.sampleRate = 44100;                            // default sample rate
        my.channels = 1;                                  // default number of channels
        my.freq_lower = 0;                                // default upper Frequency
        my.freq = 8000;                                   // default upper Frequency
        my.canvas = params.specCanvas;
        my.context = params.specCanvas.getContext("2d");
        my.pcmperpixel = 0;
        my.myImage = new Image();
        my.font = params.font;
        window.URL = window.URL || window.webkitURL;
        my.devicePixelRatio = window.devicePixelRatio || 1;
        my.response = spectroworker.textContent;
        my.blob;
        try { my.blob = new Blob([my.response], { "type" : "text\/javascript" }); }
        catch (e) { // Backwards-compatibility
                window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
                my.blob.append(my.response);
                my.blob = my.blob.getBlob();
        }
        my.primeWorker = new Worker(URL.createObjectURL(my.blob));
		my.setupEvent();
		my.clearImageCache();

		$("#specDialog").dialog({
         bgiframe: true,
         autoOpen: false,
         width: 500,
         closeOnEscape: true,
         show: 'fade',
         hide: 'fade',
         position: 'center',
         stack: false,
         buttons: {
            OK: function() {
                var nN = $("#windowLength").val();
                var nvrf = $("#viewrange_from").val();
                var nvrt = $("#viewrange_to").val();
                var ndr = $("#dynamicRange").val();
                var nwf = $("#windowFunction").val();
                if (isNaN(nN) || isNaN(nvrf) || isNaN(nvrt) || isNaN(ndr)) {
                    alert("Please enter valid numbers !");
                } else {
                    my.N = parseInt(nN, 10);
                    my.freq = parseInt(nvrt, 10);
                    my.freq_lower = parseInt(nvrf, 10);
                    my.dynRangeInDB = parseInt(ndr, 10);
                    my.windowFunction = parseInt(nwf, 10);
                    my.clearImageCache();
                    my.killSpectroRenderingThread();
                    my.uiDraw();
                    my.drawTimeLine();
                    $(this).dialog('close');
                }
            },
            Cancel: function() {
                $(this).dialog('close');
            }
         }
        });

        },

        setupEvent: function () {
            var my = this;
            my.primeWorker.addEventListener('message', function(event){
            	my.worker_img = event.data.img;
            	my.worker_start = event.data.start;
            	my.worker_end = event.data.end;
            	my.worker_cache_width = event.data.cacheWidth;
            	my.worker_cache_side = event.data.cacheSide;
                my.render_width = my.canvas.width - my.worker_cache_width;
                my.myImage.onload = function() {
                    if(my.worker_cache_side==0)
    	    	        my.context.drawImage(my.myImage, 0, 0, my.canvas.width, my.canvas.height, 0, 0, my.canvas.width, my.canvas.height);
    	    	    if(my.worker_cache_side==1)
    	    	        my.context.drawImage(my.myImage, 0, 0, my.render_width, my.canvas.height, 0, 0, my.render_width, my.canvas.height);
    	    	    if(my.worker_cache_side==2)
    	    	        my.context.drawImage(my.myImage, my.worker_cache_width, 0, my.render_width, my.canvas.height, my.worker_cache_width, 0, my.render_width, my.canvas.height);

    	    	    my.buildImageCache(my.worker_start,my.worker_end,my.canvas.toDataURL("image/png"));
    	    	    my.drawTimeLineContext();
                }
                my.myImage.src = my.worker_img;

            });
        },

        buildImageCache: function (cstart,cend,imgData) {
            var my = this;
    	    if(my.imageCache[my.pcmperpixel]==null)
    	    	my.imageCache[my.pcmperpixel] = new Array();

    	    if(my.imageCacheCounter[my.pcmperpixel]==null)
    	        my.imageCacheCounter[my.pcmperpixel] = 0;

    	    if(my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]]==null) {
    	    	my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]] = new Array();
    	    	my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]][0] = cstart;
    	    	my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]][1] = cend;
    	    	my.imageCache[my.pcmperpixel][my.imageCacheCounter[my.pcmperpixel]][2] = imgData;
    	    	++my.imageCacheCounter[my.pcmperpixel];
    	    }
        },

        drawTimeLineContext: function () {
            var my = this;
            var posS = emulabeller.viewPort.getPos(my.canvas.width, emulabeller.viewPort.selectS);
            var posE = emulabeller.viewPort.getPos(my.canvas.width, emulabeller.viewPort.selectE);
            var sDist = emulabeller.viewPort.getSampleDist(my.canvas.width)/2;
            var curPos = posS + sDist;
            if(posS!=0 &&  emulabeller.viewPort.selectS==emulabeller.viewPort.selectE) {
                my.context.fillStyle = my.params.selectLineColor;
                my.context.fillRect(posS, 0, 1, my.canvas.height);
            }
            if (curPos!=0 && emulabeller.viewPort.selectS!=emulabeller.viewPort.selectE){
                my.context.fillStyle = my.params.selectedAreaColor;
                my.context.fillRect(posS, 0, posE-posS, my.canvas.height);
                my.context.strokeStyle = my.params.selectLineColor;
                my.context.beginPath();
                my.context.moveTo(posS,0);
                my.context.lineTo(posS,my.canvas.height);
                my.context.moveTo(posE,0);
                my.context.lineTo(posE,my.canvas.height);
                my.context.closePath();
                my.context.stroke();
            }
        },

        drawTimeLine: function (){
            var my = this;
            var image = new Image();
            image.onload = function() {
                my.context.drawImage(image, 0, 0);
                my.drawTimeLineContext();
            };
            image.src = this.myImage.src;
        },

        killSpectroRenderingThread: function () {
            var my = this;
            my.context.fillStyle = my.params.selectedBorderColor;
        	my.context.fillRect(0,0,my.canvas.width,my.canvas.height);
        	my.context.font = my.params.fontPxSize+"px "+my.params.fontType;
        	my.context.fillStyle = my.params.loadingBackground;
        	my.context.fillText(my.params.loadingText, 10, 25);
            if(my.primeWorker!=null) {
            	my.primeWorker.terminate();
        		my.primeWorker = null;
        	}
        },

        clearImageCache: function () {
            var my = this;
            my.imageCache = null;
            my.imageCacheCounter = null;
            my.imageCache = new Array();
            my.imageCacheCounter = new Array();
        },

        uiDraw: function() {
            var my = this;
            my.newpcmperpixel = Math.round((emulabeller.viewPort.eS-emulabeller.viewPort.sS)/my.canvas.width);
            if(my.imageCache!=null) {
                if(my.imageCache[my.newpcmperpixel]!=null) {
					//my.found_parts = false;
					//my.pixel_covering = 0;
					//my.pixel_cache_selected = 0;

                    for (var i = 0; i < my.imageCache[my.newpcmperpixel].length; ++i) {
                        // check for complete image
                    	if(my.imageCache[my.newpcmperpixel][i][0]==emulabeller.viewPort.sS &&
                    	   my.imageCache[my.newpcmperpixel][i][1]==emulabeller.viewPort.eS) {
    	    	            my.myImage.src = my.imageCache[my.newpcmperpixel][i][2];
    	    	            my.drawTimeLine();
    	    	            return;
                    	}
                    }
            	    my.killSpectroRenderingThread();
                    my.startSpectroRenderingThread();
                }
                else {
            	    my.killSpectroRenderingThread();
                    my.startSpectroRenderingThread();
                }
            }
                    	/* check for cache on left side
                        if(my.imageCache[my.newpcmperpixel][i][0] > emulabeller.viewPort.sS &&
                    	    my.imageCache[my.newpcmperpixel][i][0] < emulabeller.viewPort.eS) {
                    	    my.pixel_cover = Math.floor((my.myend-my.imageCache[my.newpcmperpixel][i][0])/my.newpcmperpixel);
                    	    if(my.pixel_cover > my.pixel_covering ) {
                			    my.pixel_covering = my.pixel_cover;
                		        my.pixel_cache_selected = i;
                		        my.pixel_side = 1;
                    		    my.found_parts = true;
                    		}
                    	}

                    	// check for image on right side
                        if(my.imageCache[my.newpcmperpixel][i][1] > emulabeller.viewPort.sS &&
                	        my.imageCache[my.newpcmperpixel][i][1] < emulabeller.viewPort.eS) {
                		    my.pixel_cover = Math.floor((my.imageCache[my.newpcmperpixel][i][1]-my.mystart)/my.newpcmperpixel);
                		    if(my.pixel_cover > my.pixel_covering ) {
                			    my.pixel_covering = my.pixel_cover;
                		        my.pixel_cache_selected = i;
                    		    my.pixel_side = 2;
                    		    my.found_parts = true;
                    	    }
                        }
                    }
                   f(my.found_parts && my.pixel_covering > 0) {
                    	my.killSpectroRenderingThread();
                	    my.tempImage = new Image(my.pixel_covering,my.canvas.height);

                        if(my.pixel_side==1) {
                            my.tempImage.onload = function() {
    	    	                my.context.drawImage(my.tempImage,                         // image
    	    	                                     0, 0,                                     // sx,sy
    	    	                                     my.canvas.width,my.canvas.height,       // swidth, sheight
    	    	                                     (my.canvas.width-my.pixel_covering),0,    // x,y
    	    	                                     my.canvas.width,my.canvas.height);      // width, height
                            }
                            my.startSpectroRenderingThread(mybuf,
                                                           my.mystart,my.myend,
                                                           my.canvas.width,my.canvas.height,
                                                           my.pixel_covering,1);

                    	}

                        if(my.pixel_side==2) {
                            my.tempImage.onload = function() {
    	    	                my.context.drawImage(my.tempImage,                          // image
    	    	                                     (my.canvas.width-my.pixel_covering), 0,    // sx,sy
    	    	                                     my.pixel_covering,my.canvas.height,        // swidth, sheight
    	    	                                     0,0,                                       // x,y
    	    	                                     my.pixel_covering,my.canvas.height);       // width, height
                            }
                            my.startSpectroRenderingThread(mybuf,
                                                           my.mystart,my.myend,
                                                           my.canvas.width,my.canvas.height,
                                                           my.pixel_covering,2);
                    	}
                    	my.tempImage.src = my.imageCache[my.newpcmperpixel][my.pixel_cache_selected][2];

                    }

                    else {    // image has to be rendered completely
                    //}
                }*/
                else {    // image has to be rendered completely
                    my.killSpectroRenderingThread();
                    my.startSpectroRenderingThread();
                }
        },

        startSpectroRenderingThread: function () {
            var my = this;

            my.pcmperpixel = Math.round((emulabeller.viewPort.eS-emulabeller.viewPort.sS)/my.canvas.width);
            my.primeWorker = new Worker(URL.createObjectURL(my.blob));
            my.setupEvent();

            my.primeWorker.postMessage({'cmd': 'config', 'N': my.N});
            my.primeWorker.postMessage({'cmd': 'config', 'alpha': my.alpha});
            my.primeWorker.postMessage({'cmd': 'config', 'freq': my.freq});
            my.primeWorker.postMessage({'cmd': 'config', 'freq_low': my.freq_lower});
            my.primeWorker.postMessage({'cmd': 'config', 'start': Math.round(emulabeller.viewPort.sS)});
            my.primeWorker.postMessage({'cmd': 'config', 'end': Math.round(emulabeller.viewPort.eS)});
            my.primeWorker.postMessage({'cmd': 'config', 'myStep': my.pcmperpixel});
            my.primeWorker.postMessage({'cmd': 'config', 'window': my.windowFunction});
            my.primeWorker.postMessage({'cmd': 'config', 'cacheSide': 0});
            my.primeWorker.postMessage({'cmd': 'config', 'width': my.canvas.width});
            my.primeWorker.postMessage({'cmd': 'config', 'height': my.canvas.height});
            my.primeWorker.postMessage({'cmd': 'config', 'cacheWidth': 0});
            my.primeWorker.postMessage({'cmd': 'config', 'dynRangeInDB': my.dynRangeInDB});
            my.primeWorker.postMessage({'cmd': 'config', 'pixelRatio': my.devicePixelRatio});
            my.primeWorker.postMessage({'cmd': 'pcm', 'config': JSON.stringify(emulabeller.backend.currentBuffer)});
            my.primeWorker.postMessage({'cmd': 'pcm', 'stream': emulabeller.backend.currentBuffer.getChannelData(0).subarray(emulabeller.viewPort.sS, emulabeller.viewPort.eS+(2*my.N))});
            my.primeWorker.postMessage({'cmd': 'render'});
        }
};

<|endoftext|>


<commit_before>function write(text) {
	console.log(text);
}

/**
 * Interface with Janus Gateway Video Room and WebRTC-streamer API
 * @constructor
 * @param {string} janusUrl - url of Janus Gateway
 * @param {function} callback - callback to trig when state changes
 * @param {string} srvurl - url of WebRTC-streamer
*/
function JanusVideoRoom (janusUrl, callback, srvurl) {
	this.janusUrl    = janusUrl;
	this.callback    = callback || function() {};
	this.srvurl      = srvurl || location.protocol+"//"+window.location.hostname+":"+window.location.port;
	this.connection  = [];
}

/**
* Ask to publish a stream from WebRTC-streamer in a Janus Video Room user
 * @param {string} janusroomid - id of the Janus Video Room to join
 * @param {string} url - WebRTC stream to publish
 * @param {string} name - name in  Janus Video Room
*/
JanusVideoRoom.prototype.join = function(janusroomid, url, name) {
	// create a session
	var createReq = {janus: "create", transaction: Math.random().toString() }
	send(this.janusUrl, null, createReq, function(dataJson) { this.onCreateSession(dataJson, janusroomid, url, name) }, this.onError, this);
}

/**
* Ask to unpublish a stream from WebRTC-streamer in a Janus Video Room user
 * @param {string} janusroomid - id of the Janus Video Room to join
 * @param {string} url - WebRTC stream to publish
 * @param {string} name - name in  Janus Video Room
*/
JanusVideoRoom.prototype.leave = function(janusroomid, url, name) {
	var connection = this.connection[janusroomid + "_" + url + "_" + name];
	if (connection) {
		var sessionId = connection.sessionId;
		var pluginid  = connection.pluginId;

		var msg = { "janus": "message", "body": {"request": "unpublish"}, "transaction": Math.random().toString() };
		send(this.janusUrl + "/" + sessionId + "/" + pluginid, null, msg,  null, this.onError, this);
	}
}

// ------------------------------------------
// Janus callback for Session Creation
// ------------------------------------------
JanusVideoRoom.prototype.onCreateSession = function(dataJson, janusroomid, url, name) {
	var sessionId = dataJson.data.id;
	write("onCreateSession sessionId:" + sessionId);

	// attach to video room plugin
	var attach = { "janus": "attach", "plugin": "janus.plugin.videoroom", "transaction": Math.random().toString() };
	send(this.janusUrl + "/" + sessionId, null, attach, function(dataJson) { this.onPluginsAttached(dataJson, janusroomid, url, name, sessionId) }, this.onError, this );
}

// ------------------------------------------
// Janus callback for Video Room Plugins Connection
// ------------------------------------------
JanusVideoRoom.prototype.onPluginsAttached = function(dataJson, janusroomid, url, name, sessionId) {
	var pluginid = dataJson.data.id;
	write("onPluginsAttached pluginid:" + pluginid)

	this.callback(name, "joining");

	var join = {"janus":"message","body":{"request":"join","room":janusroomid,"ptype":"publisher","display":name},"transaction":Math.random().toString()}
	send(this.janusUrl + "/" + sessionId + "/" + pluginid, null, join, function(dataJson) { this.onJoinRoom(dataJson,janusroomid,name,url,sessionId,pluginid) }, this.onError, this );
}

// ------------------------------------------
// Janus callback for Video Room Joined
// ------------------------------------------
JanusVideoRoom.prototype.onJoinRoom = function(dataJson,janusroomid,name,url,sessionId,pluginid) {
	write("onJoinRoom:" + JSON.stringify(dataJson))

	var answer = sendSync(this.janusUrl + "/" + sessionId + "?rid=" + new Date().getTime() + "&maxev=1");
	write("onJoinRoom evt:" + JSON.stringify(answer))
	if (answer.plugindata.data.videoroom === "joined") {
		// register connection
		this.connection[janusroomid + "_" + url + "_" + name] = {"sessionId":sessionId, "pluginId": pluginid };

		// notify new state
		this.callback(name, "joined");

		var peerid = Math.random().toString();
		send(this.srvurl + "/createOffer?peerid="+ peerid+"&url="+encodeURIComponent(url), null, null, function(dataJson) { this.onCreateOffer(dataJson,name,peerid,sessionId,pluginid) }, this.onError, this);
	} else {
		this.callback(name, "joining room failed");
	}
}

// ------------------------------------------
// WebRTC streamer callback for Offer
// ------------------------------------------
JanusVideoRoom.prototype.onCreateOffer = function(dataJson,name,peerid,sessionId,pluginid) {
	write("onCreateOffer:" + JSON.stringify(dataJson))

	this.callback(name, "publishing");

	var msg = { "janus": "message", "body": {"request": "publish", "video": true, "audio": false}, "jsep": dataJson, "transaction": Math.random().toString() };
	send(this.janusUrl + "/" + sessionId + "/" + pluginid, null, msg,  function(dataJson) { this.onPublishStream(dataJson,name,peerid,sessionId,pluginid) }, this.onError, this);
}

// ------------------------------------------
// Janus callback for WebRTC stream is published
// ------------------------------------------
JanusVideoRoom.prototype.onPublishStream = function(dataJson,name,peerid,sessionId,pluginid) {
	write("onPublishStream:" + JSON.stringify(dataJson))

	var answer = sendSync(this.janusUrl + "/" + sessionId + "?rid=" + new Date().getTime() + "&maxev=1");
	write("onPublishStream evt:" + JSON.stringify(answer))

	if (answer.jsep) {
		send(this.srvurl + "/setAnswer?peerid="+ peerid, null, answer.jsep, function(dataJson) { this.onSetAnswer(dataJson,name,peerid,sessionId,pluginid) }, this.onError, this);
	} else {
		this.callback(name, "publishing failed (no SDP)");
	}
}

// ------------------------------------------
// WebRTC streamer callback for Answer
// ------------------------------------------
JanusVideoRoom.prototype.onSetAnswer = function(dataJson,name,peerid,sessionId,pluginid) {
	write("onSetAnswer:" + JSON.stringify(dataJson))

	send(this.srvurl + "/getIceCandidate?peerid="+peerid, null, null, function(dataJson) { this.onReceiveCandidate(dataJson,name,sessionId,pluginid) }, this.onError, this);
}

// ------------------------------------------
// WebRTC streamer callback for ICE candidate
// ------------------------------------------
JanusVideoRoom.prototype.onReceiveCandidate = function(dataJson,name,sessionId,pluginid) {
	write("onReceiveCandidate answer:" + JSON.stringify(dataJson))

	for (var i=0; i<dataJson.length; i++) {
		var candidate = new RTCIceCandidate(dataJson[i]);

		// send ICE candidate to Janus
		var msg = { "janus": "trickle", "candidate": candidate, "transaction": Math.random().toString()  };
		sendSync(this.janusUrl + "/" + sessionId + "/" + pluginid, null, msg);
	}

	// start long polling
	this.longpoll(null, name, sessionId);
}

// ------------------------------------------
// Janus callback for keepAlive Session
// ------------------------------------------
JanusVideoRoom.prototype.keepAlive = function(sessionId) {
	var msg = { "janus": "keepalive", "session_id": sessionId, "transaction": Math.random().toString()  };
	var answer = sendSync(this.janusUrl + "/" + sessionId, null, msg);
	write("keepAlive :" + JSON.stringify(answer))
}

// ------------------------------------------
// Janus callback for Long Polling
// ------------------------------------------
JanusVideoRoom.prototype.longpoll = function(dataJson, name, sessionId) {
	if (dataJson) {
		write("poll evt:" + JSON.stringify(dataJson))

		if (dataJson.janus == "webrtcup") {
			// notify connection
			this.callback(name, "up");

			// start keep alive
			var bind = this;
			window.setInterval( function() { bind.keepAlive(sessionId); }, 10000);
		}
		else if (dataJson.janus == "hangup") {
			// notify connection
			this.callback(name, "down");
		}
	}

	send(this.janusUrl + "/" + sessionId + "?rid=" + new Date().getTime() + "&maxev=1", null, null, function(dataJson) { this.longpoll(dataJson, name, sessionId) }, function(dataJson) { this.longpoll(dataJson, name, sessionId) }, this);
}

<commit_msg>use only async AJAX for janus connection<commit_after>function write(text) {
	console.log(text);
}

/**
 * Interface with Janus Gateway Video Room and WebRTC-streamer API
 * @constructor
 * @param {string} janusUrl - url of Janus Gateway
 * @param {function} callback - callback to trig when state changes
 * @param {string} srvurl - url of WebRTC-streamer
*/
function JanusVideoRoom (janusUrl, callback, srvurl) {
	this.janusUrl    = janusUrl;
	this.callback    = callback || function() {};
	this.srvurl      = srvurl || location.protocol+"//"+window.location.hostname+":"+window.location.port;
	this.connection  = [];
}

/**
* Ask to publish a stream from WebRTC-streamer in a Janus Video Room user
 * @param {string} janusroomid - id of the Janus Video Room to join
 * @param {string} url - WebRTC stream to publish
 * @param {string} name - name in  Janus Video Room
*/
JanusVideoRoom.prototype.join = function(janusroomid, url, name) {
	// create a session
	var createReq = {janus: "create", transaction: Math.random().toString() }
	send(this.janusUrl, null, createReq, function(dataJson) { this.onCreateSession(dataJson, janusroomid, url, name) }, this.onError, this);
}

/**
* Ask to unpublish a stream from WebRTC-streamer in a Janus Video Room user
 * @param {string} janusroomid - id of the Janus Video Room to join
 * @param {string} url - WebRTC stream to publish
 * @param {string} name - name in  Janus Video Room
*/
JanusVideoRoom.prototype.leave = function(janusroomid, url, name) {
	var connection = this.connection[janusroomid + "_" + url + "_" + name];
	if (connection) {
		var sessionId = connection.sessionId;
		var pluginid  = connection.pluginId;

		var msg = { "janus": "message", "body": {"request": "unpublish"}, "transaction": Math.random().toString() };
		send(this.janusUrl + "/" + sessionId + "/" + pluginid, null, msg,  null, this.onError, this);
	}
}

// ------------------------------------------
// Janus callback for Session Creation
// ------------------------------------------
JanusVideoRoom.prototype.onCreateSession = function(dataJson, janusroomid, url, name) {
	var sessionId = dataJson.data.id;
	write("onCreateSession sessionId:" + sessionId);

	// attach to video room plugin
	var attach = { "janus": "attach", "plugin": "janus.plugin.videoroom", "transaction": Math.random().toString() };
	send(this.janusUrl + "/" + sessionId, null, attach, function(dataJson) { this.onPluginsAttached(dataJson, janusroomid, url, name, sessionId) }, this.onError, this );
}

// ------------------------------------------
// Janus callback for Video Room Plugins Connection
// ------------------------------------------
JanusVideoRoom.prototype.onPluginsAttached = function(dataJson, janusroomid, url, name, sessionId) {
	var pluginid = dataJson.data.id;
	write("onPluginsAttached pluginid:" + pluginid)

	this.callback(name, "joining");

	var join = {"janus":"message","body":{"request":"join","room":janusroomid,"ptype":"publisher","display":name},"transaction":Math.random().toString()}
	send(this.janusUrl + "/" + sessionId + "/" + pluginid, null, join, function(dataJson) { this.onJoinRoom(dataJson,janusroomid,name,url,sessionId,pluginid) }, this.onError, this );
}

// ------------------------------------------
// Janus callback for Video Room Joined
// ------------------------------------------
JanusVideoRoom.prototype.onJoinRoom = function(dataJson,janusroomid,name,url,sessionId,pluginid) {
	write("onJoinRoom:" + JSON.stringify(dataJson))

	send(this.janusUrl + "/" + sessionId + "?rid=" + new Date().getTime() + "&maxev=1", null, null, function(dataJson) { this.onJoinRoomResult(dataJson,janusroomid,name,url,sessionId,pluginid) }, this.onError, this);
}

// ------------------------------------------
// Janus callback for Video Room Joined
// ------------------------------------------
JanusVideoRoom.prototype.onJoinRoomResult = function(dataJson,janusroomid,name,url,sessionId,pluginid) {
	write("onJoinRoomResult:" + JSON.stringify(dataJson))

	if (dataJson.plugindata.data.videoroom === "joined") {
		// register connection
		this.connection[janusroomid + "_" + url + "_" + name] = {"sessionId":sessionId, "pluginId": pluginid };

		// notify new state
		this.callback(name, "joined");

		var peerid = Math.random().toString();
		send(this.srvurl + "/createOffer?peerid="+ peerid+"&url="+encodeURIComponent(url), null, null, function(dataJson) { this.onCreateOffer(dataJson,name,peerid,sessionId,pluginid) }, this.onError, this);
	} else {
		this.callback(name, "joining room failed");
	}
}

// ------------------------------------------
// WebRTC streamer callback for Offer
// ------------------------------------------
JanusVideoRoom.prototype.onCreateOffer = function(dataJson,name,peerid,sessionId,pluginid) {
	write("onCreateOffer:" + JSON.stringify(dataJson))

	this.callback(name, "publishing");

	var msg = { "janus": "message", "body": {"request": "publish", "video": true, "audio": false}, "jsep": dataJson, "transaction": Math.random().toString() };
	send(this.janusUrl + "/" + sessionId + "/" + pluginid, null, msg,  function(dataJson) { this.onPublishStream(dataJson,name,peerid,sessionId,pluginid) }, this.onError, this);
}

// ------------------------------------------
// Janus callback for WebRTC stream is published
// ------------------------------------------
JanusVideoRoom.prototype.onPublishStream = function(dataJson,name,peerid,sessionId,pluginid) {
	write("onPublishStream:" + JSON.stringify(dataJson))

	send(this.janusUrl + "/" + sessionId + "?rid=" + new Date().getTime() + "&maxev=1", null, null, function(dataJson) { this.onPublishStreamResult(dataJson,name,peerid,sessionId,pluginid); }, this.onError, this  );
}

// ------------------------------------------
// Janus callback for WebRTC stream is published
// ------------------------------------------
JanusVideoRoom.prototype.onPublishStreamResult = function(dataJson,name,peerid,sessionId,pluginid) {
	write("onPublishStreamResult:" + JSON.stringify(dataJson))

	if (dataJson.jsep) {
		send(this.srvurl + "/setAnswer?peerid="+ peerid, null, dataJson.jsep, function(dataJson) { this.onSetAnswer(dataJson,name,peerid,sessionId,pluginid) }, this.onError, this);
	} else {
		this.callback(name, "publishing failed (no SDP)");
	}
}

// ------------------------------------------
// WebRTC streamer callback for Answer
// ------------------------------------------
JanusVideoRoom.prototype.onSetAnswer = function(dataJson,name,peerid,sessionId,pluginid) {
	write("onSetAnswer:" + JSON.stringify(dataJson))

	send(this.srvurl + "/getIceCandidate?peerid="+peerid, null, null, function(dataJson) { this.onReceiveCandidate(dataJson,name,sessionId,pluginid) }, this.onError, this);
}

// ------------------------------------------
// WebRTC streamer callback for ICE candidate
// ------------------------------------------
JanusVideoRoom.prototype.onReceiveCandidate = function(dataJson,name,sessionId,pluginid) {
	write("onReceiveCandidate answer:" + JSON.stringify(dataJson))

	for (var i=0; i<dataJson.length; i++) {
		// send ICE candidate to Janus
		var msg = { "janus": "trickle", "candidate": dataJson[i], "transaction": Math.random().toString()  };
		send(this.janusUrl + "/" + sessionId + "/" + pluginid, null, msg);
	}

	// start long polling
	this.longpoll(null, name, sessionId);
}

// ------------------------------------------
// Janus callback for keepAlive Session
// ------------------------------------------
JanusVideoRoom.prototype.keepAlive = function(sessionId) {
	var msg = { "janus": "keepalive", "session_id": sessionId, "transaction": Math.random().toString()  };
	send(this.janusUrl + "/" + sessionId, null, msg, function(dataJson) { write("keepAlive :" + JSON.stringify(dataJson)); }, this.onError, this);
}

// ------------------------------------------
// Janus callback for Long Polling
// ------------------------------------------
JanusVideoRoom.prototype.longpoll = function(dataJson, name, sessionId) {
	if (dataJson) {
		write("poll evt:" + JSON.stringify(dataJson))

		if (dataJson.janus == "webrtcup") {
			// notify connection
			this.callback(name, "up");

			// start keep alive
			var bind = this;
			setInterval( function() { bind.keepAlive(sessionId); }, 10000);
		}
		else if (dataJson.janus == "hangup") {
			// notify connection
			this.callback(name, "down");
		}
	}

	send(this.janusUrl + "/" + sessionId + "?rid=" + new Date().getTime() + "&maxev=1", null, null, function(dataJson) { this.longpoll(dataJson, name, sessionId) }, function(dataJson) { this.longpoll(dataJson, name, sessionId) }, this);
}<|endoftext|>