<commit_before>"use strict";

const { Translate }= require('@google-cloud/translate').v2;
const farmhash = require('farmhash');
const log = require('../utils/logger');

module.exports = (sequelize, DataTypes) => {
  let AcTranslationCache = sequelize.define("AcTranslationCache", {
    index_key: { type: DataTypes.STRING, allowNull: false },
    content: { type: DataTypes.TEXT, allowNull: false },
  }, {

    indexes: [
      {
        name: 'main_index',
        fields: ['index_key']
      }
    ],

    underscored: true,

    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at',

    tableName: 'translation_cache'
  });

  AcTranslationCache.allowedTextTypesForSettingLanguage = [
    "pointContent",
    "postName",
    "postContent",
    "groupName",
    "groupContent",
    "communityName",
    "communityContent",
    "domainName",
    "domainContent",
    "statusChangeContent"
  ]

  AcTranslationCache.getContentToTranslate = (req, modelInstance) => {
    switch(req.query.textType) {
      case 'postName':
      case 'domainName':
      case 'communityName':
      case 'groupName':
        return modelInstance.name;
      case 'postContent':
      case 'domainContent':
      case 'communityContent':
        return modelInstance.description;
      case 'pointContent':
        return modelInstance.PointRevisions[modelInstance.PointRevisions.length-1].content;
      case 'statusChangeContent':
        return modelInstance.content;
      case 'groupContent':
        return modelInstance.objectives;
      case 'pointAdminCommentContent':
        if (modelInstance.public_data &&
            modelInstance.public_data.admin_comment &&
            modelInstance.public_data.admin_comment.text) {
          return modelInstance.public_data.admin_comment.text;
        } else {
          return "Translation error";
        }
      case 'customRatingName':
        if (modelInstance.Group.configuration.customRatings &&
          modelInstance.Group.configuration.customRatings[modelInstance.custom_rating_index]) {
          return modelInstance.Group.configuration.customRatings[modelInstance.custom_rating_index].name
        } else {
          return "Translation error";
        }
      case 'alternativeTextForNewIdeaButton':
        return modelInstance.configuration.alternativeTextForNewIdeaButton;
      case 'alternativeTextForNewIdeaButtonClosed':
        return modelInstance.configuration.alternativeTextForNewIdeaButtonClosed;
      case 'alternativeTextForNewIdeaButtonHeader':
        return modelInstance.configuration.alternativeTextForNewIdeaButtonHeader;
      case 'customThankYouTextNewPosts':
        return modelInstance.configuration.customThankYouTextNewPosts;
      case 'customTitleQuestionText':
        return modelInstance.configuration.customTitleQuestionText;
      case 'customAdminCommentsTitle':
        return modelInstance.configuration.customAdminCommentsTitle;
      case 'alternativePointForHeader':
        return modelInstance.configuration.alternativePointForHeader;
      case 'alternativePointAgainstHeader':
        return modelInstance.configuration.alternativePointAgainstHeader;
      case 'alternativePointForLabel':
        return modelInstance.configuration.alternativePointForLabel;
      case 'alternativePointAgainstLabel':
        return modelInstance.configuration.alternativePointAgainstLabel;
      case 'categoryName':
        return modelInstance.name;
      case 'postTranscriptContent':
        return (modelInstance.public_data && modelInstance.public_data.transcript) ?
          modelInstance.public_data.transcript.text : null;
      default:
        console.error("No valid textType for translation");
        return null;
    }
  };

  // Post Edit
  // When AutoTranslate event ask for all the strings from the StructuredQuestions
  // Replace the StructuredQuestions with translates, store original value and redraw
  // When AutoTranslate stops reinstate the original structured questions

  // In Post
  // When AutoTranslate ask for all the strings for StructuredAnswers & Questions
  // Recreate structure and redraw
  // When AutoTranslate stops
  // Same in XLS and DOCX exports
  AcTranslationCache.getSurveyAnswerTranslations = async (postId, targetLanguage, done) => {
    targetLanguage = AcTranslationCache.fixUpLanguage(targetLanguage);
    sequelize.models.Post.findOne({
      where: {
        id: postId
      },
      attributes: ['id','public_data']
    }).then(async (post) => {
      if (post.public_data &&
          post.public_data.structuredAnswersJson &&
          post.public_data.structuredAnswersJson.length>0) {
        const textStrings = [];
        let combinedText = "";
        for (const answer of post.public_data.structuredAnswersJson) {
          if (answer.value) {
            textStrings.push(answer.value);
            combinedText+=answer.value;
          } else {
            textStrings.push("");
          }
        }
        const contentHash = farmhash.hash32(combinedText).toString();
        let indexKey = `PostAnswer-${post.id}-${targetLanguage}-${contentHash}`;
        AcTranslationCache.getSurveyTranslations(indexKey, textStrings, targetLanguage, done);
      } else {
        done(null, []);
      }
    }).catch( error => {
      done(error);
    })
  }

  AcTranslationCache.getSurveyQuestionTranslations = async (groupId, targetLanguage, done) => {
    targetLanguage = AcTranslationCache.fixUpLanguage(targetLanguage);

    sequelize.models.Group.findOne({
      where: {
        id: groupId
      },
      attributes: ['id','configuration']
    }).then(async (group) => {
      if (group.configuration &&
          group.configuration.structuredQuestionsJson &&
          group.configuration.structuredQuestionsJson.length>0) {

        const textStrings = [];
        let combinedText = "";
        for (const question of group.configuration.structuredQuestionsJson) {
          if (question.text) {
            textStrings.push(question.text);
            combinedText+=question.text;
          } else {
            textStrings.push("");
          }
        }
        const contentHash = farmhash.hash32(combinedText).toString();
        let indexKey = `GroupQuestions-${group.id}-${targetLanguage}-${contentHash}`;
        AcTranslationCache.getSurveyTranslations(indexKey, textStrings, targetLanguage, done);
      } else {
        done(null, []);
      }
    }).catch( error => {
      done(error);
    })
  }

  AcTranslationCache.getSurveyTranslations = (indexKey, textStrings, targetLanguage, done) => {
    sequelize.models.AcTranslationCache.findOne({
      where: {
        index_key: indexKey
      }
    }).then(async translationModel => {
      if (false && translationModel) {
        done(null, JSON.parse(translationModel.content));
      } else {
        try {
          const results = await AcTranslationCache.getSurveyTranslationsFromGoogle(textStrings, targetLanguage);
          const translatedStrings = results[0];
          if (translatedStrings && translatedStrings.length>0) {
            sequelize.models.AcTranslationCache.create({
              index_key: indexKey,
              content: JSON.stringify(translatedStrings)
            }).then(() => {
              done(null, translatedStrings);
            }).catch( error => {
              done(error);
            })
          } else {
            done(null, []);
          }
        } catch (error) {
          done(error);
        }
      }
    }).catch( error => {
      done(error);
    });

  }

  AcTranslationCache.getSurveyTranslationsFromGoogle = async (textsToTranslate, targetLanguage) => {
    //TODO: Implement a pagination for the max 128 strings limit of google translate
    return await new Promise(async (resolve, reject) => {
      const translateAPI = new Translate({
        credentials: JSON.parse(process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON)
      });

      try {
        resolve(await translateAPI.translate(textsToTranslate, targetLanguage));
      } catch (error) {
        reject(error);
      }
    });
  };

  AcTranslationCache.getTranslationFromGoogle = (textType, indexKey, contentToTranslate, targetLanguage, modelInstance, callback) => {

    const translateAPI = new Translate({
      credentials: JSON.parse(process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON)
    });

    translateAPI.translate(contentToTranslate, targetLanguage)
      .then((results) => {
        const translationResults = results[1];
        if (translationResults && translationResults.data
          && translationResults.data.translations &&
          translationResults.data.translations.length>0) {
          const translation = translationResults.data.translations[0];
          sequelize.models.AcTranslationCache.create({
            index_key: indexKey,
            content: translation.translatedText
          }).then(() => {
            if (textType==='postTranscriptContent' || textType==='pointAdminCommentContent') {
              if (textType==='postTranscriptContent') {
                modelInstance.set('public_data.transcript.language', translation.detectedSourceLanguage);
              } else {
                modelInstance.set('public_data.admin_comment.language', translation.detectedSourceLanguage);
              }
              modelInstance.save().then( () => {
                callback(null, { content: translation.translatedText });
              }).catch( error => {
                callback(error);
              });
            } else {
              if (AcTranslationCache.allowedTextTypesForSettingLanguage.indexOf(textType)>-1) {
                modelInstance.update({
                  language: translation.detectedSourceLanguage
                }).then(() => {
                  callback(null, { content: translation.translatedText });
                });
              } else {
                callback(null, { content: translation.translatedText });
              }
            }
          }).catch((error) => {
            callback(error);
          });
        } else {
          callback("No translations");
        }
      }).catch((error) => {
      callback(error);
    });
  };

  AcTranslationCache.fixUpLanguage = (targetLanguage) => {
    targetLanguage = targetLanguage.replace('_','-');

    if (targetLanguage!=='sr-latin' && targetLanguage!=='zh-CN' && targetLanguage!=='zh-TW') {
      targetLanguage = targetLanguage.split("-")[0];
    }

    if (targetLanguage==='sr-latin') {
      targetLanguage = 'sr-Latn';
    }

    return targetLanguage;
  }

  AcTranslationCache.getTranslation = (req, modelInstance, callback) => {

    const contentToTranslate = sequelize.models.AcTranslationCache.getContentToTranslate(req, modelInstance);
    if (contentToTranslate && contentToTranslate!=='' &&
      contentToTranslate.length>1 && isNaN(contentToTranslate)) {

      const contentHash = farmhash.hash32(contentToTranslate).toString();

      const textType = req.query.textType;

      let targetLanguage = req.query.targetLanguage;

      targetLanguage = AcTranslationCache.fixUpLanguage(targetLanguage);

      let indexKey = `${textType}-${modelInstance.id}-${targetLanguage}-${contentHash}`;

      sequelize.models.AcTranslationCache.findOne({
        where: {
          index_key: indexKey
        }
      }).then((translationModel) => {
        if (translationModel) {
          callback(null, { content: translationModel.content });
        } else {
          sequelize.models.AcTranslationCache.getTranslationFromGoogle(textType, indexKey, contentToTranslate, targetLanguage, modelInstance, callback);
        }
      }).catch((error) => {
        callback(error);
      });
    } else {
      log.warn("Empty or short string for translation", {
        textType: req.query.textType,
        targetLanguage: req.query.targetLanguage
      });
      if (!modelInstance.language) {
        modelInstance.update({
          language: '??'
        }).then(() => {
          callback(null, { content: contentToTranslate });
        }).catch( error => {
          callback(error);
        });
      } else {
        callback();
      }
    }
  };

  return AcTranslationCache;
};
<commit_msg>Work on auto translate for surveys<commit_after>"use strict";

const { Translate }= require('@google-cloud/translate').v2;
const farmhash = require('farmhash');
const log = require('../utils/logger');

module.exports = (sequelize, DataTypes) => {
  let AcTranslationCache = sequelize.define("AcTranslationCache", {
    index_key: { type: DataTypes.STRING, allowNull: false },
    content: { type: DataTypes.TEXT, allowNull: false },
  }, {

    indexes: [
      {
        name: 'main_index',
        fields: ['index_key']
      }
    ],

    underscored: true,

    timestamps: true,
    createdAt: 'created_at',
    updatedAt: 'updated_at',

    tableName: 'translation_cache'
  });

  AcTranslationCache.allowedTextTypesForSettingLanguage = [
    "pointContent",
    "postName",
    "postContent",
    "groupName",
    "groupContent",
    "communityName",
    "communityContent",
    "domainName",
    "domainContent",
    "statusChangeContent"
  ]

  AcTranslationCache.getContentToTranslate = (req, modelInstance) => {
    switch(req.query.textType) {
      case 'postName':
      case 'domainName':
      case 'communityName':
      case 'groupName':
        return modelInstance.name;
      case 'postContent':
      case 'domainContent':
      case 'communityContent':
        return modelInstance.description;
      case 'pointContent':
        return modelInstance.PointRevisions[modelInstance.PointRevisions.length-1].content;
      case 'statusChangeContent':
        return modelInstance.content;
      case 'groupContent':
        return modelInstance.objectives;
      case 'pointAdminCommentContent':
        if (modelInstance.public_data &&
            modelInstance.public_data.admin_comment &&
            modelInstance.public_data.admin_comment.text) {
          return modelInstance.public_data.admin_comment.text;
        } else {
          return "Translation error";
        }
      case 'customRatingName':
        if (modelInstance.Group.configuration.customRatings &&
          modelInstance.Group.configuration.customRatings[modelInstance.custom_rating_index]) {
          return modelInstance.Group.configuration.customRatings[modelInstance.custom_rating_index].name
        } else {
          return "Translation error";
        }
      case 'alternativeTextForNewIdeaButton':
        return modelInstance.configuration.alternativeTextForNewIdeaButton;
      case 'alternativeTextForNewIdeaButtonClosed':
        return modelInstance.configuration.alternativeTextForNewIdeaButtonClosed;
      case 'alternativeTextForNewIdeaButtonHeader':
        return modelInstance.configuration.alternativeTextForNewIdeaButtonHeader;
      case 'customThankYouTextNewPosts':
        return modelInstance.configuration.customThankYouTextNewPosts;
      case 'customTitleQuestionText':
        return modelInstance.configuration.customTitleQuestionText;
      case 'customAdminCommentsTitle':
        return modelInstance.configuration.customAdminCommentsTitle;
      case 'alternativePointForHeader':
        return modelInstance.configuration.alternativePointForHeader;
      case 'alternativePointAgainstHeader':
        return modelInstance.configuration.alternativePointAgainstHeader;
      case 'alternativePointForLabel':
        return modelInstance.configuration.alternativePointForLabel;
      case 'alternativePointAgainstLabel':
        return modelInstance.configuration.alternativePointAgainstLabel;
      case 'categoryName':
        return modelInstance.name;
      case 'postTranscriptContent':
        return (modelInstance.public_data && modelInstance.public_data.transcript) ?
          modelInstance.public_data.transcript.text : null;
      default:
        console.error("No valid textType for translation");
        return null;
    }
  };

  // Post Edit
  // When AutoTranslate event ask for all the strings from the StructuredQuestions
  // Replace the StructuredQuestions with translates, store original value and redraw
  // When AutoTranslate stops reinstate the original structured questions

  // In Post
  // When AutoTranslate ask for all the strings for StructuredAnswers & Questions
  // Recreate structure and redraw
  // When AutoTranslate stops
  // Same in XLS and DOCX exports
  AcTranslationCache.getSurveyAnswerTranslations = async (postId, targetLanguage, done) => {
    targetLanguage = AcTranslationCache.fixUpLanguage(targetLanguage);
    sequelize.models.Post.findOne({
      where: {
        id: postId
      },
      attributes: ['id','public_data','language']
    }).then(async (post) => {
      if (post.public_data &&
          post.public_data.structuredAnswersJson &&
          post.public_data.structuredAnswersJson.length>0) {
        const textStrings = [];
        let combinedText = "";
        for (const answer of post.public_data.structuredAnswersJson) {
          if (answer.value) {
            textStrings.push(answer.value);
            combinedText+=answer.value;
          } else {
            textStrings.push("");
          }
        }
        const contentHash = farmhash.hash32(combinedText).toString();
        let indexKey = `PostAnswer-${post.id}-${targetLanguage}-${contentHash}`;
        AcTranslationCache.getSurveyTranslations(indexKey, textStrings, targetLanguage, post, done);
      } else {
        done(null, []);
      }
    }).catch( error => {
      done(error);
    })
  }

  AcTranslationCache.getSurveyQuestionTranslations = async (groupId, targetLanguage, done) => {
    targetLanguage = AcTranslationCache.fixUpLanguage(targetLanguage);

    sequelize.models.Group.findOne({
      where: {
        id: groupId
      },
      attributes: ['id','configuration']
    }).then(async (group) => {
      if (group.configuration &&
          group.configuration.structuredQuestionsJson &&
          group.configuration.structuredQuestionsJson.length>0) {

        const textStrings = [];
        let combinedText = "";
        for (const question of group.configuration.structuredQuestionsJson) {
          if (question.text) {
            textStrings.push(question.text);
            combinedText+=question.text;
          } else {
            textStrings.push("");
          }
        }
        const contentHash = farmhash.hash32(combinedText).toString();
        let indexKey = `GroupQuestions-${group.id}-${targetLanguage}-${contentHash}`;
        AcTranslationCache.getSurveyTranslations(indexKey, textStrings, targetLanguage, null, done);
      } else {
        done(null, []);
      }
    }).catch( error => {
      done(error);
    })
  }

  AcTranslationCache.getSurveyTranslations = (indexKey, textStrings, targetLanguage, saveLanguageToModel, done) => {
    sequelize.models.AcTranslationCache.findOne({
      where: {
        index_key: indexKey
      }
    }).then(async translationModel => {
      if (translationModel) {
        done(null, JSON.parse(translationModel.content));
      } else {
        try {
          const results = await AcTranslationCache.getSurveyTranslationsFromGoogle(textStrings, targetLanguage);
          const translatedStrings = results[0];
          const languageInfo = results[1];
          if (translatedStrings && translatedStrings.length>0) {
            sequelize.models.AcTranslationCache.create({
              index_key: indexKey,
              content: JSON.stringify(translatedStrings)
            }).then(() => {
              if (saveLanguageToModel && languageInfo.data && languageInfo.data.translations && languageInfo.data.translations.length>0) {
                saveLanguageToModel.update({
                  language: languageInfo.data.translations[0].detectedSourceLanguage
                }).then(() => {
                  done(null, translatedStrings);
                }).catch( error => {
                  done(error);
                });
              } else {
                done(null, translatedStrings);
              }
            }).catch( error => {
              done(error);
            })
          } else {
            done(null, []);
          }
        } catch (error) {
          done(error);
        }
      }
    }).catch( error => {
      done(error);
    });

  }

  AcTranslationCache.getSurveyTranslationsFromGoogle = async (textsToTranslate, targetLanguage) => {
    //TODO: Implement a pagination for the max 128 strings limit of google translate
    return await new Promise(async (resolve, reject) => {
      const translateAPI = new Translate({
        credentials: JSON.parse(process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON)
      });

      try {
        resolve(await translateAPI.translate(textsToTranslate, targetLanguage));
      } catch (error) {
        reject(error);
      }
    });
  };

  AcTranslationCache.getTranslationFromGoogle = (textType, indexKey, contentToTranslate, targetLanguage, modelInstance, callback) => {

    const translateAPI = new Translate({
      credentials: JSON.parse(process.env.GOOGLE_APPLICATION_CREDENTIALS_JSON)
    });

    translateAPI.translate(contentToTranslate, targetLanguage)
      .then((results) => {
        const translationResults = results[1];
        if (translationResults && translationResults.data
          && translationResults.data.translations &&
          translationResults.data.translations.length>0) {
          const translation = translationResults.data.translations[0];
          sequelize.models.AcTranslationCache.create({
            index_key: indexKey,
            content: translation.translatedText
          }).then(() => {
            if (textType==='postTranscriptContent' || textType==='pointAdminCommentContent') {
              if (textType==='postTranscriptContent') {
                modelInstance.set('public_data.transcript.language', translation.detectedSourceLanguage);
              } else {
                modelInstance.set('public_data.admin_comment.language', translation.detectedSourceLanguage);
              }
              modelInstance.save().then( () => {
                callback(null, { content: translation.translatedText });
              }).catch( error => {
                callback(error);
              });
            } else {
              if (AcTranslationCache.allowedTextTypesForSettingLanguage.indexOf(textType)>-1) {
                modelInstance.update({
                  language: translation.detectedSourceLanguage
                }).then(() => {
                  callback(null, { content: translation.translatedText });
                }).catch( error => {
                  callback(error);
                });
              } else {
                callback(null, { content: translation.translatedText });
              }
            }
          }).catch((error) => {
            callback(error);
          });
        } else {
          callback("No translations");
        }
      }).catch((error) => {
      callback(error);
    });
  };

  AcTranslationCache.fixUpLanguage = (targetLanguage) => {
    targetLanguage = targetLanguage.replace('_','-');

    if (targetLanguage!=='sr-latin' && targetLanguage!=='zh-CN' && targetLanguage!=='zh-TW') {
      targetLanguage = targetLanguage.split("-")[0];
    }

    if (targetLanguage==='sr-latin') {
      targetLanguage = 'sr-Latn';
    }

    return targetLanguage;
  }

  AcTranslationCache.getTranslation = (req, modelInstance, callback) => {

    const contentToTranslate = sequelize.models.AcTranslationCache.getContentToTranslate(req, modelInstance);
    if (contentToTranslate && contentToTranslate!=='' &&
      contentToTranslate.length>1 && isNaN(contentToTranslate)) {

      const contentHash = farmhash.hash32(contentToTranslate).toString();

      const textType = req.query.textType;

      let targetLanguage = req.query.targetLanguage;

      targetLanguage = AcTranslationCache.fixUpLanguage(targetLanguage);

      let indexKey = `${textType}-${modelInstance.id}-${targetLanguage}-${contentHash}`;

      sequelize.models.AcTranslationCache.findOne({
        where: {
          index_key: indexKey
        }
      }).then((translationModel) => {
        if (translationModel) {
          callback(null, { content: translationModel.content });
        } else {
          sequelize.models.AcTranslationCache.getTranslationFromGoogle(textType, indexKey, contentToTranslate, targetLanguage, modelInstance, callback);
        }
      }).catch((error) => {
        callback(error);
      });
    } else {
      log.warn("Empty or short string for translation", {
        textType: req.query.textType,
        targetLanguage: req.query.targetLanguage
      });
      if (!modelInstance.language) {
        modelInstance.update({
          language: '??'
        }).then(() => {
          callback(null, { content: contentToTranslate });
        }).catch( error => {
          callback(error);
        });
      } else {
        callback();
      }
    }
  };

  return AcTranslationCache;
};
<|endoftext|>


<commit_before>var Vow = require('vow'),
    fs = require('fs'),
    vm = require('vm');

function DepsTech() {}

DepsTech.prototype = {
    getName: function() {
        return 'deps';
    },

    init: function(node) {
        this.node = node;
    },

    getTargets: function() {
        return [this.node.getTargetName('deps.js')];
    },

    build: function() {
        var depsTarget, depsTargetPath, promise,
            _this = this;
        promise = Vow.promise();
        depsTarget = this.node.getTargetName('deps.js');
        depsTargetPath = this.node.resolvePath(depsTarget);
        this.node.requireSources([this.node.getTargetName('bemdecl.js'), this.node.getTargetName('levels')]).spread((function(bemdecl, levels) {
            try {
                var bemdecl = require(_this.node.resolvePath(_this.node.getTargetName('bemdecl.js'))),
                    dep = new Dep(levels);
                bemdecl.blocks.forEach(function(block) {
                    dep.addBlock(block.name);
                    if (block.mods) {
                        block.mods.forEach(function(mod) {
                            if (mod.vals) {
                                mod.vals.forEach(function(val) {
                                    dep.addBlock(block.name, mod.name, val.name);
                                });
                            }
                        });
                    }
                    if (block.elems) {
                        block.elems.forEach(function(elem){
                            dep.addElem(block.name, elem.name);
                        });
                    }
                });
                var resolvedDeps = dep.resolve();
                fs.writeFileSync(depsTargetPath, 'exports.deps = ' + JSON.stringify(resolvedDeps) + ';');
                _this.node.resolveTarget(depsTarget, resolvedDeps);
                return promise.fulfill();
            } catch (err) {
                return promise.reject(err);
            }
        }), function(err) {
            return promise.reject(err);
        });
        return promise;
    },

    clean: function() {
        return this.cleanTarget(this.node.getTargetName('deps.js'));
    },

    cleanTarget: function(target) {
        var targetPath = this.node.resolvePath(target);
        if (fs.existsSync(targetPath)) {
            fs.unlinkSync(this.node.resolvePath(target));
            this.node.getLogger().logClean(target);
        }
    }
};

function declKey(decl) {
   return decl.name + (decl.elem ? '__' + decl.elem : '') + (decl.modName ? '_' + decl.modName + '_' + decl.modVal : '');
}

function Dep(levels) {
    this.levels = levels;
    this.declarations = [];
    this.resolved = {};
    this.declarationIndex = {};
}

Dep.prototype.normalizeDep = function(dep, blockName) {
    if (typeof dep === 'string') {
        return [{ name: dep }];
    } else {
        var res = [];
        if (dep.elem) {
            if (dep.mods) {
                Object.keys(dep.mods).forEach(function(modName) {
                    var modVals = dep.mods[modName];
                    if (!Array.isArray(modVals)) {
                        modVals = [modVals];
                    }
                    res = res.concat(modVals.map(function(modVal) {
                        return { name: dep.block || blockName, elem: dep.elem, modName: modName, modVal: modVal };
                    }));
                });
            } else {
                res.push({ name: dep.block || blockName, elem: dep.elem });
            }
        } else if (dep.mods || dep.elems) {
            Object.keys(dep.mods || {}).forEach(function(modName) {
                var modVals = dep.mods[modName];
                if (!Array.isArray(modVals)) {
                    modVals = [modVals];
                }
                res = res.concat(modVals.map(function(modVal) {
                    return { name: dep.block || blockName, modName: modName, modVal: modVal };
                }));
            });
            var elems = dep.elems || [];
            if (!Array.isArray(elems)) {
                elems = [elems];
            }
            res = res.concat(elems.map(function(elem) {
                return { name: dep.block || blockName, elem: elem };
            }));
        } else {
            res = [{ name: dep.block || blockName }];
        }
        return res;
    }
};

Dep.prototype.normalizeDeps = function(deps, blockName) {
    var dep, result, _i, _len;
    if (Array.isArray(deps)) {
        result = [];
        for (_i = 0, _len = deps.length; _i < _len; _i++) {
            dep = deps[_i];
            result = result.concat(this.normalizeDep(dep, blockName));
        }
        return result;
    } else {
        return this.normalizeDep(deps, blockName);
    }
};

Dep.prototype.getDeps = function(decl) {
    var dep, file, files, key, mustDecl, mustDepIndex, mustDeps, nd, shouldDepIndex, shouldDeps, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
    if (decl.elem) {
        files = this.levels.getElemFiles(decl.name, decl.elem, decl.modName, decl.modVal);
    } else {
        files = this.levels.getBlockFiles(decl.name, decl.modName, decl.modVal);
    }
    files = files.filter(function(file) {
        return file.suffix == 'deps.js';
    });
    mustDepIndex = {};
    shouldDepIndex = {};
    mustDeps = [];
    if (decl.modName) {
        if (decl.elem) {
            mustDecl = { name: decl.name, elem: decl.elem };
        } else {
            mustDecl = { name: decl.name };
        }
        mustDecl.key = declKey(mustDecl);
        mustDepIndex[mustDecl.key] = true;
        mustDeps.push(mustDecl);
    }
    shouldDeps = [];
    for (_i = 0, _len = files.length; _i < _len; _i++) {
        file = files[_i];
        dep = vm.runInThisContext(fs.readFileSync(file.fullname, "utf8"));
        if (dep.mustDeps) {
            _ref = this.normalizeDeps(dep.mustDeps, decl.name);
            for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
                nd = _ref[_j];
                key = declKey(nd);
                if (!mustDepIndex[key]) {
                    mustDepIndex[key] = true;
                    nd.key = key;
                    mustDeps.push(nd);
                }
            }
        }
        if (dep.shouldDeps) {
            _ref1 = this.normalizeDeps(dep.shouldDeps, decl.name);
            for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
                nd = _ref1[_k];
                key = declKey(nd);
                if (!shouldDepIndex[key]) {
                    shouldDepIndex[key] = true;
                    shouldDeps.push(nd);
                }
            }
        }
    }
    return [mustDeps, shouldDeps];
};

Dep.prototype.addBlock = function(blockName, modName, modVal) {
    if (modName) {
        this.addDecl({
            name: blockName,
            modName: modName,
            modVal: modVal
        });
    } else {
        this.addDecl({
            name: blockName
        });
    }
};

Dep.prototype.addElem = function(blockName, elemName, modName, modVal) {
    if (modName) {
        this.addDecl({
            name: blockName,
            elem: elemName,
            modName: modName,
            modVal: modVal
        });
    } else {
        this.addDecl({
            name: blockName,
            elem: elemName
        });
    }
};

Dep.prototype.addDecl = function(decl) {
    var dep, deps, key, _i, _j, _len, _len1, _ref, _ref1;
    key = declKey(decl);
    if (this.declarationIndex[key]) {
        return;
    }
    this.declarations.push(decl);
    this.declarationIndex[key] = decl;
    deps = this.getDeps(decl);
    decl.key = key;
    decl.deps = {};
    decl.depCount = 0;
    _ref = deps[0];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        dep = _ref[_i];
        decl.deps[dep.key] = true;
        decl.depCount++;
        this.addDecl(dep);
    }
    _ref1 = deps[1];
    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
        dep = _ref1[_j];
        this.addDecl(dep);
    }
};

Dep.prototype.resolve = function() {
    var decl, hasChanges, item, items, newItems, result, subDecl, _i, _j, _len, _len1;
    items = this.declarations.slice(0);
    result = [];
    hasChanges = true;
    while (hasChanges) {
        newItems = [];
        hasChanges = false;
        for (_i = 0, _len = items.length; _i < _len; _i++) {
            decl = items[_i];
            if (decl.depCount === 0) {
                hasChanges = true;
                for (_j = 0, _len1 = items.length; _j < _len1; _j++) {
                    subDecl = items[_j];
                    if (subDecl.deps[decl.key]) {
                        delete subDecl.deps[decl.key];
                        subDecl.depCount--;
                    }
                }
                item = {
                    block: decl.name
                };
                if (decl.elem) {
                    item.elem = decl.elem;
                }
                if (decl.modName) {
                    item.mod = decl.modName;
                    item.val = decl.modVal;
                }
                result.push(item);
            } else {
                newItems.push(decl);
            }
        }
        items = newItems;
    }
    if (items.length) {
        var errorMessage = items.map(function(item) {
            return item.key + ' <- ' + Object.keys(item.deps).join(', ');
        });
        throw Error('Unresolved deps: \n' + errorMessage.join('\n'));
    }
    return result;
};

module.exports = DepsTech;
<commit_msg>noDeps<commit_after>var Vow = require('vow'),
    fs = require('fs'),
    vm = require('vm');

function DepsTech() {}

DepsTech.prototype = {
    getName: function() {
        return 'deps';
    },

    init: function(node) {
        this.node = node;
    },

    getTargets: function() {
        return [this.node.getTargetName('deps.js')];
    },

    build: function() {
        var depsTarget, depsTargetPath, promise,
            _this = this;
        promise = Vow.promise();
        depsTarget = this.node.getTargetName('deps.js');
        depsTargetPath = this.node.resolvePath(depsTarget);
        this.node.requireSources([this.node.getTargetName('bemdecl.js'), this.node.getTargetName('levels')]).spread((function(bemdecl, levels) {
            try {
                var bemdecl = require(_this.node.resolvePath(_this.node.getTargetName('bemdecl.js'))),
                    dep = new Dep(levels);
                bemdecl.blocks.forEach(function(block) {
                    dep.addBlock(block.name);
                    if (block.mods) {
                        block.mods.forEach(function(mod) {
                            if (mod.vals) {
                                mod.vals.forEach(function(val) {
                                    dep.addBlock(block.name, mod.name, val.name);
                                });
                            }
                        });
                    }
                    if (block.elems) {
                        block.elems.forEach(function(elem){
                            dep.addElem(block.name, elem.name);
                        });
                    }
                });
                var resolvedDeps = dep.resolve();
                fs.writeFileSync(depsTargetPath, 'exports.deps = ' + JSON.stringify(resolvedDeps) + ';');
                _this.node.resolveTarget(depsTarget, resolvedDeps);
                return promise.fulfill();
            } catch (err) {
                return promise.reject(err);
            }
        }), function(err) {
            return promise.reject(err);
        });
        return promise;
    },

    clean: function() {
        return this.cleanTarget(this.node.getTargetName('deps.js'));
    },

    cleanTarget: function(target) {
        var targetPath = this.node.resolvePath(target);
        if (fs.existsSync(targetPath)) {
            fs.unlinkSync(this.node.resolvePath(target));
            this.node.getLogger().logClean(target);
        }
    }
};

function declKey(decl) {
   return decl.name + (decl.elem ? '__' + decl.elem : '') + (decl.modName ? '_' + decl.modName + '_' + decl.modVal : '');
}

function Dep(levels) {
    this.levels = levels;
    this.declarations = [];
    this.resolved = {};
    this.declarationIndex = {};
}

Dep.prototype.normalizeDep = function(dep, blockName) {
    if (typeof dep === 'string') {
        return [{ name: dep }];
    } else {
        if (!dep) {
            console.log(blockName, dep);
        }
        var res = [];
        if (dep.elem) {
            if (dep.mods) {
                Object.keys(dep.mods).forEach(function(modName) {
                    var modVals = dep.mods[modName];
                    if (!Array.isArray(modVals)) {
                        modVals = [modVals];
                    }
                    res = res.concat(modVals.map(function(modVal) {
                        return { name: dep.block || blockName, elem: dep.elem, modName: modName, modVal: modVal };
                    }));
                });
            } else {
                res.push({ name: dep.block || blockName, elem: dep.elem });
            }
        } else if (dep.mods || dep.elems) {
            Object.keys(dep.mods || {}).forEach(function(modName) {
                var modVals = dep.mods[modName];
                if (!Array.isArray(modVals)) {
                    modVals = [modVals];
                }
                res = res.concat(modVals.map(function(modVal) {
                    return { name: dep.block || blockName, modName: modName, modVal: modVal };
                }));
            });
            var elems = dep.elems || [];
            if (!Array.isArray(elems)) {
                elems = [elems];
            }
            res = res.concat(elems.map(function(elem) {
                return { name: dep.block || blockName, elem: elem };
            }));
        } else {
            res = [{ name: dep.block || blockName }];
        }
        return res;
    }
};

Dep.prototype.normalizeDeps = function(deps, blockName) {
    var dep, result, _i, _len;
    if (Array.isArray(deps)) {
        result = [];
        for (_i = 0, _len = deps.length; _i < _len; _i++) {
            dep = deps[_i];
            result = result.concat(this.normalizeDep(dep, blockName));
        }
        return result;
    } else {
        return this.normalizeDep(deps, blockName);
    }
};

Dep.prototype.getDeps = function(decl) {
    var dep, _this = this, files, key, mustDecl, mustDepIndex, mustDeps, shouldDepIndex, shouldDeps;
    if (decl.elem) {
        files = this.levels.getElemFiles(decl.name, decl.elem, decl.modName, decl.modVal);
    } else {
        files = this.levels.getBlockFiles(decl.name, decl.modName, decl.modVal);
    }
    files = files.filter(function(file) {
        return file.suffix == 'deps.js';
    });
    mustDepIndex = {};
    shouldDepIndex = {};
    mustDeps = [];
    if (decl.modName) {
        if (decl.elem) {
            mustDecl = { name: decl.name, elem: decl.elem };
        } else {
            mustDecl = { name: decl.name };
        }
        mustDecl.key = declKey(mustDecl);
        mustDepIndex[mustDecl.key] = true;
        mustDeps.push(mustDecl);
    }
    shouldDeps = [];
    files.forEach(function(file) {
        dep = vm.runInThisContext(fs.readFileSync(file.fullname, "utf8"));
        if (dep.mustDeps) {
            _this.normalizeDeps(dep.mustDeps, decl.name).forEach(function(nd) {
                key = declKey(nd);
                if (!mustDepIndex[key]) {
                    mustDepIndex[key] = true;
                    nd.key = key;
                    mustDeps.push(nd);
                }
            });
        }
        if (dep.shouldDeps) {
            _this.normalizeDeps(dep.shouldDeps, decl.name).forEach(function(nd) {
                key = declKey(nd);
                if (!shouldDepIndex[key]) {
                    shouldDepIndex[key] = true;
                    nd.key = key;
                    shouldDeps.push(nd);
                }
            });
        }
        if (dep.noDeps) {
            _this.normalizeDeps(dep.noDeps, decl.name).forEach(function(nd) {
                key = declKey(nd);
                nd.key = key;
                removeFromDeps(nd, mustDepIndex, mustDeps);
                removeFromDeps(nd, shouldDepIndex, shouldDeps);
            });
        }
    });
    function removeFromDeps(decl, index, list) {
        if (index[decl.key]) {
            for (var i = 0, l = list.length; i < l; i++) {
                if (list[i].key == decl.key) {
                    return list.splice(i, 1);
                }
            }
        } else {
            index[decl.key] = true;
        }
        return null;
    }
    return [mustDeps, shouldDeps];
};

Dep.prototype.addBlock = function(blockName, modName, modVal) {
    if (modName) {
        this.addDecl({
            name: blockName,
            modName: modName,
            modVal: modVal
        });
    } else {
        this.addDecl({
            name: blockName
        });
    }
};

Dep.prototype.addElem = function(blockName, elemName, modName, modVal) {
    if (modName) {
        this.addDecl({
            name: blockName,
            elem: elemName,
            modName: modName,
            modVal: modVal
        });
    } else {
        this.addDecl({
            name: blockName,
            elem: elemName
        });
    }
};

Dep.prototype.addDecl = function(decl) {
    var dep, deps, key, _i, _j, _len, _len1, _ref, _ref1;
    key = declKey(decl);
    if (this.declarationIndex[key]) {
        return;
    }
    this.declarations.push(decl);
    this.declarationIndex[key] = decl;
    deps = this.getDeps(decl);
    decl.key = key;
    decl.deps = {};
    decl.depCount = 0;
    _ref = deps[0];
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        dep = _ref[_i];
        decl.deps[dep.key] = true;
        decl.depCount++;
        this.addDecl(dep);
    }
    _ref1 = deps[1];
    for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
        dep = _ref1[_j];
        this.addDecl(dep);
    }
};

Dep.prototype.resolve = function() {
    var decl, hasChanges, item, items, newItems, result, subDecl, _i, _j, _len, _len1;
    items = this.declarations.slice(0);
    result = [];
    hasChanges = true;
    while (hasChanges) {
        newItems = [];
        hasChanges = false;
        for (_i = 0, _len = items.length; _i < _len; _i++) {
            decl = items[_i];
            if (decl.depCount === 0) {
                hasChanges = true;
                for (_j = 0, _len1 = items.length; _j < _len1; _j++) {
                    subDecl = items[_j];
                    if (subDecl.deps[decl.key]) {
                        delete subDecl.deps[decl.key];
                        subDecl.depCount--;
                    }
                }
                item = {
                    block: decl.name
                };
                if (decl.elem) {
                    item.elem = decl.elem;
                }
                if (decl.modName) {
                    item.mod = decl.modName;
                    item.val = decl.modVal;
                }
                result.push(item);
            } else {
                newItems.push(decl);
            }
        }
        items = newItems;
    }
    if (items.length) {
        var errorMessage = items.map(function(item) {
            return item.key + ' <- ' + Object.keys(item.deps).join(', ');
        });
        throw Error('Unresolved deps: \n' + errorMessage.join('\n'));
    }
    return result;
};

module.exports = DepsTech;
<|endoftext|>


<commit_before>'use strict';

const Color = require('./color');
const distributionGenerator = require('./distribution-generator');
const schemeDefinitions = require('./scheme-definitions');

function Scheme(options){
  options = options || {};
  this.name = options.name || '';
  this.colors = options.colors || [{base: new Color()}];
}

Scheme.prototype.toJSON = function toJSON(){
  return JSON.stringify({
    name: this.name,
    colors: this.colors
  });
};

Scheme.prototype.setName = function setName(name){
  this.name = name;
  return this;
};

Scheme.prototype.getName = function getName(){
  return this.name;
};

Scheme.prototype.rotate = function rotate(angle){
  function rotateColors(color){
    color.rotateHueWheel(angle);
  }
  this.traverse(rotateColors);
  return this;
};

Scheme.prototype.setSaturation = function setSaturation(saturation){
  saturation = saturation || this.colors[0].base.getHSV().s;
  function saturateColors(color){
    color.setHSV(null, saturation);
  }
  this.traverse(saturateColors);
  return this;
};

Scheme.prototype.flatten = function flatten(value){
  value = value || this.colors[0].base.getHSV().v;
  function flattenColors(color){
    color.setHSV(null, null, value);
  }

  this.traverse(flattenColors);
  return this;
};

Scheme.prototype.reset = function reset(){
  this.name = '';
  this.colors = [{base: new Color()}];
  return this;
};

Scheme.prototype.homogenize = function homogenize(saturation, value){
  this.setSaturation(saturation);
  this.flatten(value);
  return this;
};

Scheme.prototype.configure = function configure(options){
  if(!options){
    throw new Error('configure method was call without configuration options.');
  }
  if(typeof options === 'string'){
    options = schemeDefinitions[options];
    if(!options){
      throw new Error(`Type ${options} is not defined.`);
    }
  }

  this.config = options;
};

Scheme.prototype.generate = function generate(){
  let angles;

  angles = distributionGenerator(this.config);
  angles.forEach((angle)=>{
    // Fist color in the array is the main color to calculate other scheme colors
    var auxColor = this.colors[0].base.clone();
    this.colors({base: auxColor.rotateHueWheel(angle)});
  });
};

Scheme.prototype.traverse = function traverse(fn){
  this.colors.forEach(function(colorSet){
    fn(colorSet.base);
    colorSet.shades.forEach(fn);
    colorSet.tints.forEach(fn);
    colorSet.tones.forEach(fn);
  });
};

module.exports = Scheme;
<commit_msg>Change default value forr name from '' to undefined<commit_after>'use strict';

const Color = require('./color');
const distributionGenerator = require('./distribution-generator');
const schemeDefinitions = require('./scheme-definitions');

function Scheme(options){
  options = options || {};
  this.name = options.name || undefined;
  this.colors = options.colors || [{base: new Color()}];
}

Scheme.prototype.toJSON = function toJSON(){
  return JSON.stringify({
    name: this.name,
    colors: this.colors
  });
};

Scheme.prototype.setName = function setName(name){
  this.name = name;
  return this;
};

Scheme.prototype.getName = function getName(){
  return this.name;
};

Scheme.prototype.rotate = function rotate(angle){
  function rotateColors(color){
    color.rotateHueWheel(angle);
  }
  this.traverse(rotateColors);
  return this;
};

Scheme.prototype.setSaturation = function setSaturation(saturation){
  saturation = saturation || this.colors[0].base.getHSV().s;
  function saturateColors(color){
    color.setHSV(null, saturation);
  }
  this.traverse(saturateColors);
  return this;
};

Scheme.prototype.flatten = function flatten(value){
  value = value || this.colors[0].base.getHSV().v;
  function flattenColors(color){
    color.setHSV(null, null, value);
  }

  this.traverse(flattenColors);
  return this;
};

Scheme.prototype.reset = function reset(){
  this.name = undefined;
  this.colors = [{base: new Color()}];
  return this;
};

Scheme.prototype.homogenize = function homogenize(saturation, value){
  this.setSaturation(saturation);
  this.flatten(value);
  return this;
};

Scheme.prototype.configure = function configure(options){
  if(!options){
    throw new Error('configure method was call without configuration options.');
  }
  if(typeof options === 'string'){
    options = schemeDefinitions[options];
    if(!options){
      throw new Error(`Type ${options} is not defined.`);
    }
  }

  this.config = options;
};

Scheme.prototype.generate = function generate(){
  let angles;

  angles = distributionGenerator(this.config);
  angles.forEach((angle, index)=>{
    if(index === 0){ // first iteration is the main color which is already in the array
      return;
    }
    // Fist color in the array is the main color to calculate other scheme colors
    var auxColor = this.colors[0].base.clone();
    this.colors.push({base: auxColor.rotateHueWheel(angle)});
  });
};

Scheme.prototype.traverse = function traverse(fn){
  this.colors.forEach(function(colorSet){
    fn(colorSet.base);
    colorSet.shades.forEach(fn);
    colorSet.tints.forEach(fn);
    colorSet.tones.forEach(fn);
  });
};

module.exports = Scheme;
<|endoftext|>


<commit_before>import _ from 'lodash';
import autobind from 'autobind-decorator';
import {
  observable,
  action,
  computed,
} from 'mobx';
import { Pokeio } from 'pokemon-go-node-api';
import POKEMON_META from '../api/pokemons';
import Sort from '../api/sort';

class Auth {
  @observable provider = 'google';
  @observable username;
  @observable password;
  @observable authed = false;
  @observable location;
  @observable _pokemon = [];
  @observable sort = 'recent';
  @observable locationString = 'San Francisco';

  constructor() {
    this.api = new Pokeio();

    this.getLocation();
  }

  @action
  getLocation() {
    return new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition((loc) => {
        this.location = loc.coords;
        resolve(loc);
      }, (err) => {
        console.error('Error getting location', err);
      }, {
        enableHighAccuracy: true,
      });

    });
  }

  @computed
  get pokemon() {
    const sorter = Sort[this.sort];
    return _.sortBy(this._pokemon.slice(), sorter);
  }

  @action
  setProvider(value) {
    this.provider = value;
  }

  @action
  login() {
    if (this.username && this.password && this.provider) {
      if (!this.location && !this.locationString) {
        this.getLocation();
      } else {
        let location;

        if (this.location) {
          location = {
            type: 'coords',
            coords: this.location,
          };
        } else if (this.locationString) {
          location = {
            type: 'name',
            name: this.locationString,
          };
        }

        this.api.init(this.username, this.password, location, this.provider, (err) => {
          if (!err) {
            this.authed = true;
            this.getPokemon();
          } else {
            console.error(err);
          }
        });
      }
    } else {
      console.error('Cant login, missing authentication details.');
    }
  }

  @action getPokemon() {
    this.api.GetInventory((err, res) => {
      if (!err) {
        if (res && res.inventory_delta && res.inventory_delta.inventory_items) {
          const filtered = res.inventory_delta.inventory_items.filter((item) => {
            return item.inventory_item_data.pokemon && item.inventory_item_data.pokemon.pokemon_id;
          }).map((item) => item.inventory_item_data.pokemon)
            .map((pokemon) => {
              console.log(pokemon.pokemon_id);
              const meta = POKEMON_META[pokemon.pokemon_id - 1];
              return {
                ...pokemon,
                name: meta.name,
                img: meta.img,
                type: meta.type,
              };
            })

          const fs = require('fs');
          fs.writeFileSync('response.json', JSON.stringify(filtered, null, 2));
          this._pokemon = filtered;
        }
      } else {
        console.error(err);
      }
    });
  }
}

const authStore = new Auth();

export default authStore;
export { Auth };
<commit_msg>Reverse sort order<commit_after>import _ from 'lodash';
import autobind from 'autobind-decorator';
import {
  observable,
  action,
  computed,
} from 'mobx';
import { Pokeio } from 'pokemon-go-node-api';
import POKEMON_META from '../api/pokemons';
import Sort from '../api/sort';

class Auth {
  @observable provider = 'google';
  @observable username;
  @observable password;
  @observable authed = false;
  @observable location;
  @observable _pokemon = [];
  @observable sort = 'recent';
  @observable locationString = 'San Francisco';

  constructor() {
    this.api = new Pokeio();

    this.getLocation();
  }

  @action
  getLocation() {
    return new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition((loc) => {
        this.location = loc.coords;
        resolve(loc);
      }, (err) => {
        console.error('Error getting location', err);
      }, {
        enableHighAccuracy: true,
      });

    });
  }

  @computed
  get pokemon() {
    const sorter = Sort[this.sort];
    return _.reverse(
      _.sortBy(this._pokemon.slice(), sorter)
    );
  }

  @action
  setProvider(value) {
    this.provider = value;
  }

  @action
  login() {
    if (this.username && this.password && this.provider) {
      if (!this.location && !this.locationString) {
        this.getLocation();
      } else {
        let location;

        if (this.location) {
          location = {
            type: 'coords',
            coords: this.location,
          };
        } else if (this.locationString) {
          location = {
            type: 'name',
            name: this.locationString,
          };
        }

        this.api.init(this.username, this.password, location, this.provider, (err) => {
          if (!err) {
            this.authed = true;
            this.getPokemon();
          } else {
            console.error(err);
          }
        });
      }
    } else {
      console.error('Cant login, missing authentication details.');
    }
  }

  @action getPokemon() {
    this.api.GetInventory((err, res) => {
      if (!err) {
        if (res && res.inventory_delta && res.inventory_delta.inventory_items) {
          const filtered = res.inventory_delta.inventory_items.filter((item) => {
            return item.inventory_item_data.pokemon && item.inventory_item_data.pokemon.pokemon_id;
          }).map((item) => item.inventory_item_data.pokemon)
            .map((pokemon) => {
              console.log(pokemon.pokemon_id);
              const meta = POKEMON_META[pokemon.pokemon_id - 1];
              return {
                ...pokemon,
                name: meta.name,
                img: meta.img,
                type: meta.type,
              };
            })

          const fs = require('fs');
          fs.writeFileSync('response.json', JSON.stringify(filtered, null, 2));
          this._pokemon = filtered;
        }
      } else {
        console.error(err);
      }
    });
  }
}

const authStore = new Auth();

export default authStore;
export { Auth };
<|endoftext|>


<commit_before>"use strict";
var React = require('react');
var _ = require('underscore');
var globals = require('./globals');
var curator = require('./curator');
var RestMixin = require('./rest').RestMixin;
var form = require('../libs/bootstrap/form');
var panel = require('../libs/bootstrap/panel');

var RecordHeader = curator.RecordHeader;
var PmidSummary = curator.PmidSummary;
var queryKeyValue = globals.queryKeyValue;
var Form = form.Form;
var FormMixin = form.FormMixin;
var Input = form.Input;
var Panel = panel.Panel;

var FamilySubmit = module.exports.FamilySubmit = React.createClass({
    mixins: [FormMixin, RestMixin],

    // Keeps track of values from the query string
    queryValues: {},

    getInitialState: function() {
        return {
            gdm: null, // GDM object given in query string
            family: null, // Group object given in query string
            annotation: null, // Annotation object given in query string
            haveIndividual: '' // Setting of have-individual switch
        };
    },

    // Handle value changes in the form
    handleChange: function(ref, e) {
        if (ref === 'haveindividual') {
            this.setState({haveIndividual: this.refs[ref].getValue()});
        }
    },

    // Load objects from query string into the state variables. Must have already parsed the query string
    // and set the queryValues property of this React class.
    loadData: function() {
        var gdmUuid = this.queryValues.gdmUuid;
        var familyUuid = this.queryValues.familyUuid;
        var annotationUuid = this.queryValues.annotationUuid;

        // Make an array of URIs to query the database. Don't include any that didn't include a query string.
        var uris = _.compact([
            gdmUuid ? '/gdm/' + gdmUuid : '',
            familyUuid ? '/family/' + familyUuid : '',
            annotationUuid ? '/evidence/' + annotationUuid : ''
        ]);

        // With all given query string variables, get the corresponding objects from the DB.
        this.getRestDatas(
            uris
        ).then(datas => {
            // See what we got back so we can build an object to copy in this React object's state to rerender the page.
            var stateObj = {};
            datas.forEach(function(data) {
                switch(data['@type'][0]) {
                    case 'gdm':
                        stateObj.gdm = data;
                        break;

                    case 'family':
                        stateObj.family = data;
                        break;

                    case 'annotation':
                        stateObj.annotation = data;
                        break;

                    default:
                        break;
                }
            });

            // Set all the state variables we've collected
            this.setState(stateObj);

            // Not passing data to anyone; just resolve with an empty promise.
            return Promise.resolve();
        }).catch(function(e) {
            console.log('OBJECT LOAD ERROR: %s — %s', e.statusText, e.url);
        });
    },

    // After the Family Curation page component mounts, grab the GDM, group, family, and annotation UUIDs (as many as given)
    // from the query string and retrieve the corresponding objects from the DB, if they exist. Note, we have to do this after
    // the component mounts because AJAX DB queries can't be done from unmounted components.
    componentDidMount: function() {
        // Get the 'evidence', 'gdm', and 'group' UUIDs from the query string and save them locally.
        this.loadData();
    },

    render: function() {
        var gdm = this.state.gdm;
        var family = this.state.family;
        var group = (family && family.associatedGroups.length) ? family.associatedGroups[0] : null;
        var annotation = this.state.annotation;
        var hasVariants = !!(family && family.segregation && family.segregation.variants && family.segregation.variants.length);

        // Get the given family's proband individual if it has one; null if it doesn't.
        var probandIndividual = family && _(family.individualIncluded).find(function(individual) {
            return individual.proband;
        });

        // Get the query strings. Have to do this now so we know whether to render the form or not. The form
        // uses React controlled inputs, so we can only render them the first time if we already have the
        // family object read in.
        this.queryValues.gdmUuid = queryKeyValue('gdm', this.props.href);
        this.queryValues.familyUuid = queryKeyValue('family', this.props.href);
        this.queryValues.annotationUuid = queryKeyValue('annotation', this.props.href);
        this.queryValues.initialVariants = queryKeyValue('initvar', this.props.href) === ""; // True if variants in family for the first time
        this.queryValues.hadVariants = queryKeyValue('hadvar', this.props.href) === ""; // True if family had variants even if it doesn't now

        var hadVariants = (gdm && family) ? this.queryValues.hadVariants : false;
        console.log('hadVariants: ' + hadVariants);

        // Build the link to go back and edit the newly created group page
        var editFamilyLink = (gdm && family && annotation) ? '/family-curation/?gdm=' + gdm.uuid + '&evidence=' + annotation.uuid + '&family=' + family.uuid : '';

        return (

                <RecordHeader gdm={gdm} omimId={gdm && gdm.omimId} />

                    {family ?

Family Information: {family.label} View Edit

                            {group ?

{'Group association: ' + group.label}

                            : null}

                    : null}
                    {annotation && annotation.article ?

                            <PmidSummary article={annotation.article} displayJournal />

                    : null}

                            {hasVariants || this.queryValues.hadVariants ?
                                <Panel panelClassName="submit-results-panel" panelBodyClassName="bg-info">

                                                Edit proband Individual

                                                Add non-proband Individual

                                                Return to Record Curation page

                                </Panel>
                            :

                                    <Panel panelClassName="submit-results-panel" panelBodyClassName="bg-info">
                                        <Form formClassName="form-horizontal form-std">
                                            <Input type="select" ref="haveindividual" defaultValue={this.state.haveIndividual}
                                                label="No segregating variant information has been associated with the proband in this Family. Would you like to do this?"
                                                handleChange={this.handleChange} labelClassName="family-submit-results-label" wrapperClassName="family-submit-results-switch" groupClassName="submit-results-wrapper">
                                                <option value="" disabled="disabled">No Selection</option>
                                                <option disabled="disabled"></option>
                                                <option value="y">Yes</option>
                                                <option value="n">No</option>
                                            </Input>
                                        </Form>

                                            Note: If you want to associate variant(s) with the proband, you must edit the family and add variant(s) there. This creates an individual who is the proband for the family.

                                    </Panel>
                                    {this.state.haveIndividual === 'y' || this.state.haveIndividual === 'n' ?
                                        <Panel panelClassName="submit-results-panel submit-results-response">
                                            {(this.state.haveIndividual === 'y' && gdm && annotation && family) ?

                                                        Edit this family

                                            : ((this.state.haveIndividual === 'n' && gdm && annotation) ?

                                                            You can add information about non-proband individuals in this family, including variant information by creating an Individual entry for them.

                                                            Note: Individual information includes associated variant(s), phenotypes, sex, etc.

                                                            Add non-proband Individual

                                                            Return to Record Curation page

                                            : null)}
                                        </Panel>
                                    : null}

                            }

        );
    }
});

globals.curator_page.register(FamilySubmit, 'curator_page', 'family-submit');
<commit_msg>Change Display Family Submit contents conditions<commit_after>"use strict";
var React = require('react');
var _ = require('underscore');
var globals = require('./globals');
var curator = require('./curator');
var RestMixin = require('./rest').RestMixin;
var form = require('../libs/bootstrap/form');
var panel = require('../libs/bootstrap/panel');

var RecordHeader = curator.RecordHeader;
var PmidSummary = curator.PmidSummary;
var queryKeyValue = globals.queryKeyValue;
var Form = form.Form;
var FormMixin = form.FormMixin;
var Input = form.Input;
var Panel = panel.Panel;

var FamilySubmit = module.exports.FamilySubmit = React.createClass({
    mixins: [FormMixin, RestMixin],

    // Keeps track of values from the query string
    queryValues: {},

    getInitialState: function() {
        return {
            gdm: null, // GDM object given in query string
            family: null, // Group object given in query string
            annotation: null, // Annotation object given in query string
            haveIndividual: '' // Setting of have-individual switch
        };
    },

    // Handle value changes in the form
    handleChange: function(ref, e) {
        if (ref === 'haveindividual') {
            this.setState({haveIndividual: this.refs[ref].getValue()});
        }
    },

    // Load objects from query string into the state variables. Must have already parsed the query string
    // and set the queryValues property of this React class.
    loadData: function() {
        var gdmUuid = this.queryValues.gdmUuid;
        var familyUuid = this.queryValues.familyUuid;
        var annotationUuid = this.queryValues.annotationUuid;

        // Make an array of URIs to query the database. Don't include any that didn't include a query string.
        var uris = _.compact([
            gdmUuid ? '/gdm/' + gdmUuid : '',
            familyUuid ? '/family/' + familyUuid : '',
            annotationUuid ? '/evidence/' + annotationUuid : ''
        ]);

        // With all given query string variables, get the corresponding objects from the DB.
        this.getRestDatas(
            uris
        ).then(datas => {
            // See what we got back so we can build an object to copy in this React object's state to rerender the page.
            var stateObj = {};
            datas.forEach(function(data) {
                switch(data['@type'][0]) {
                    case 'gdm':
                        stateObj.gdm = data;
                        break;

                    case 'family':
                        stateObj.family = data;
                        break;

                    case 'annotation':
                        stateObj.annotation = data;
                        break;

                    default:
                        break;
                }
            });

            // Set all the state variables we've collected
            this.setState(stateObj);

            // Not passing data to anyone; just resolve with an empty promise.
            return Promise.resolve();
        }).catch(function(e) {
            console.log('OBJECT LOAD ERROR: %s — %s', e.statusText, e.url);
        });
    },

    // After the Family Curation page component mounts, grab the GDM, group, family, and annotation UUIDs (as many as given)
    // from the query string and retrieve the corresponding objects from the DB, if they exist. Note, we have to do this after
    // the component mounts because AJAX DB queries can't be done from unmounted components.
    componentDidMount: function() {
        // Get the 'evidence', 'gdm', and 'group' UUIDs from the query string and save them locally.
        this.loadData();
    },

    render: function() {
        var gdm = this.state.gdm;
        var family = this.state.family;
        var group = (family && family.associatedGroups.length) ? family.associatedGroups[0] : null;
        var annotation = this.state.annotation;
        var hasVariants = !!(family && family.segregation && family.segregation.variants && family.segregation.variants.length);

        // Get the given family's proband individual if it has one; null if it doesn't.
        var probandIndividual = family && _(family.individualIncluded).find(function(individual) {
            return individual.proband;
        });

        // Get the query strings. Have to do this now so we know whether to render the form or not. The form
        // uses React controlled inputs, so we can only render them the first time if we already have the
        // family object read in.
        this.queryValues.gdmUuid = queryKeyValue('gdm', this.props.href);
        this.queryValues.familyUuid = queryKeyValue('family', this.props.href);
        this.queryValues.annotationUuid = queryKeyValue('annotation', this.props.href);
        this.queryValues.initialVariants = queryKeyValue('initvar', this.props.href) === ""; // True if variants in family for the first time
        this.queryValues.hadVariants = queryKeyValue('hadvar', this.props.href) === ""; // True if family had variants even if it doesn't now

        var hadVariants = (gdm && family) ? this.queryValues.hadVariants : false;
        console.log('hadVariants: ' + hadVariants);

        // Build the link to go back and edit the newly created group page
        var editFamilyLink = (gdm && family && annotation) ? '/family-curation/?gdm=' + gdm.uuid + '&evidence=' + annotation.uuid + '&family=' + family.uuid : '';

        return (

                <RecordHeader gdm={gdm} omimId={gdm && gdm.omimId} />

                    {family ?

Family Information: {family.label} View Edit

                            {group ?

{'Group association: ' + group.label}

                            : null}

                    : null}
                    {annotation && annotation.article ?

                            <PmidSummary article={annotation.article} displayJournal />

                    : null}

                            {hasVariants || hadVariants ?
                                <Panel panelClassName="submit-results-panel" panelBodyClassName="bg-info">

                                                Edit proband Individual

                                                Add non-proband Individual

                                                Return to Record Curation page

                                </Panel>
                            :

                                    <Panel panelClassName="submit-results-panel" panelBodyClassName="bg-info">
                                        <Form formClassName="form-horizontal form-std">
                                            <Input type="select" ref="haveindividual" defaultValue={this.state.haveIndividual}
                                                label="No segregating variant information has been associated with the proband in this Family. Would you like to do this?"
                                                handleChange={this.handleChange} labelClassName="family-submit-results-label" wrapperClassName="family-submit-results-switch" groupClassName="submit-results-wrapper">
                                                <option value="" disabled="disabled">No Selection</option>
                                                <option disabled="disabled"></option>
                                                <option value="y">Yes</option>
                                                <option value="n">No</option>
                                            </Input>
                                        </Form>

                                            Note: If you want to associate variant(s) with the proband, you must edit the family and add variant(s) there. This creates an individual who is the proband for the family.

                                    </Panel>
                                    {this.state.haveIndividual === 'y' || this.state.haveIndividual === 'n' ?
                                        <Panel panelClassName="submit-results-panel submit-results-response">
                                            {(this.state.haveIndividual === 'y' && gdm && annotation && family) ?

                                                        Edit this family

                                            : ((this.state.haveIndividual === 'n' && gdm && annotation) ?

                                                            You can add information about non-proband individuals in this family, including variant information by creating an Individual entry for them.

                                                            Note: Individual information includes associated variant(s), phenotypes, sex, etc.

                                                            Add non-proband Individual

                                                            Return to Record Curation page

                                            : null)}
                                        </Panel>
                                    : null}

                            }

        );
    }
});

globals.curator_page.register(FamilySubmit, 'curator_page', 'family-submit');
<|endoftext|>


<commit_before>import test from 'tape'
import { Vector, Polygon, Rectangle, Circle, ShapeEventEmitter } from '..'

test('Polygon#contains', t => {
  t.plan(5)
  //Disable warning about missing 'new'. That's what we are testing
  /*jshint -W064 */
  /*eslint-disable new-cap */
  t.throws(()=> Polygon(), TypeError)
  t.throws(()=> Rectangle(), TypeError)
  t.throws(()=> Vector(), TypeError)
  t.throws(()=> Circle(), TypeError)
  t.throws(()=> ShapeEventEmitter(), TypeError)
  /*eslint-enable new-cap */

})

<commit_msg>Fix name for the classtest<commit_after>import test from 'tape'
import { Vector, Polygon, Rectangle, Circle, ShapeEventEmitter } from '..'

test('Classtest', t => {
  t.plan(5)
  //Disable warning about missing 'new'. That's what we are testing
  /*jshint -W064 */
  /*eslint-disable new-cap */
  t.throws(()=> Polygon(), TypeError)
  t.throws(()=> Rectangle(), TypeError)
  t.throws(()=> Vector(), TypeError)
  t.throws(()=> Circle(), TypeError)
  t.throws(()=> ShapeEventEmitter(), TypeError)
  /*eslint-enable new-cap */

})

<|endoftext|>


<commit_before>import values from 'lodash/values';
import { ContentNodeKinds, LearningActivities } from 'kolibri.coreVue.vuex.constants';
import every from 'lodash/every';
import keys from 'lodash/keys';

/**
 * Validation for vue router "location descriptor objects".
 * See e.g. https://router.vuejs.org/en/api/router-link.html
 */
export function validateLinkObject(object) {
  const validKeys = ['name', 'path', 'params', 'query'];
  return every(keys(object), key => validKeys.includes(key));
}

export function validateUsername(username) {
  const hasPuncRe = /[\s`~!@#$%^&*()\-+={}\[\]\|\\\/:;"'<>,\.\?]/; // eslint-disable-line
  return !hasPuncRe.test(username);
}

export function validateContentNodeKind(value, others = []) {
  return [...values(ContentNodeKinds), ...others].includes(value);
}

export function validateLearningActivity(arr) {
  const isValidLearningActivity = v => Object.values(LearningActivities).includes(v);
  return arr.length > 0 && arr.every(isValidLearningActivity);
}

export function objectPropValidator( options ){
	var args = arguments || [];
    var _getType = function(variable) {
        var match = false;
        var rawType = "";
        try {
            match = variable && variable.toString().match(/^\s*function (\w+)/);
        } catch {}
        try {
            rawType = Object.prototype.toString.call(variable).slice(8, -1);
        } catch {}
        return match ? match[1] : (rawType.length > 0 ? rawType : ((typeof variable == "function" || typeof variable.name != "undefined") ? variable.name : ''));
    };
    var _isUndefined = function(variable) {
        return (typeof variable === "undefined");
    };
    var _isSet = function(variable) {
        return (typeof variable !== "undefined");
    };
    var _isString = function(variable) {
        return (typeof variable === "string");
    };
    var _isNumber = function(variable) {
        return (typeof variable === "number");
    };
    var _isFinite = function(variable) {
        return isFinite(variable);
    };
    var _isInfinity = function(variable) {
        return (typeof variable === "number" && !isFinite(variable));
    };
    var _isBoolean = function(variable) {
        return (typeof variable === "boolean");
    };
    var _isBigInt = function(variable) {
        return (typeof variable === "bigint");
    };
    var _isFlatten = function(variable) {
        return (typeof variable === "string" || typeof variable === "number" || typeof variable === "boolean");
    };
    var _isEmpty = function(variable) {
        if (typeof variable === 'undefined' || variable === "" || variable === 0 || variable === [] || variable === {} || variable === false || variable === null || isNaN(variable) || variable === function() {}) {
            return true;
        }
        return false;
    };
    var _isArray = function(variable) {
        if (typeof Array != "undefined" && typeof Array.isArray != "undefined") {
            return Array.isArray(variable);
        }
        if (variable.constructor && variable.constructor.name && variable.constructor.name == "Array") {
            return true;
        }
        if (typeof Object != "undefined" && Object.prototype && Object.prototype.toString && Object.prototype.toString.call && Object.prototype.toString.call(variable) == "[object Array]"); {
            return true;
        }
        return false;
    };
    var _inArray = function(needle, haystack) {
        if (typeof haystack.indexOf != "undefined") {
            return haystack.indexOf(needle) > -1;
        }
        return false;
    };
    var _isFunction = function(variable) {
        return (typeof variable === "function");
    };
    var _isObject = function(variable) {
        return (typeof variable === "object");
    };
    var _isPureObject = function(variable) {
        return (typeof variable === "object" && typeof Object != "undefined" && variable === Object(variable));
    };
    var _isSymbol = function(variable) {
        return (typeof variable === "undefined");
    };
    var _isRegularType = function(variable) {
        var regularTypes = [String, Number, Boolean, Function, BigInt, Object, Array, Symbol];
        var regularTypesStr = ['String', 'Number', 'Boolean', 'Function', 'BigInt', 'Object', 'Array', 'Symbol'];
        if (regularTypes.indexOf(variable) > -1) {
            return true;
        }
        if (regularTypesStr.indexOf(variable) > -1) {
            return true;
        }
        return false;
    };
    var validatorLogger = function(msg, dataType, option, config, dataKey) {
        var dataMsg = "CURRENT DATA TYPE: " + dataType;
        var optMsg = "NEED DATA TYPE";
        switch (true) {
            case _isUndefined(option.type): {
                optMsg += ": Undefined";
            }
            break;
			case _isArray(option.type): {
				if (option.type.length <= 1) {
					optMsg += ": " + (_isSet(option.type[0]) ? _getType(option.type[0]) : "Undefined");
				} else {
					optMsg += "(in): [";
					for (var i = 0; i < option.type.length; i++) {
						optMsg += _getType(option.type[i]).toLowerCase();
					}
					optMsg.slice(0, -1);
					optMsg += "]";
				}
			}
        	break;
			default: {
				optMsg += _getType(option.type).toLowerCase();
			}
			break;
        }
        var finalMessage = "[Error](objectPropValidator): " + msg;
        if ("Required type mismatch" === msg) {
            finalMessage += ". Correction need: " + dataMsg + ", " + optMsg;
        }
        finalMessage += ". Key name: " + dataKey + ".";

        // Logger function check, ensure and call
        if (!(_isSet(config.logLevel) && config.logLevel === null)) {

            if (_isSet(config.logLevel) && config.logLevel == "throw") {
                if (_isSet(Error)) {
                    throw new Error(finalMessage);
                } else {
                    throw finalMessage;
                }
            } else if (_isUndefined(config.logLevel) || (_isSet(config.logLevel) && !console.hasOwnProperty(config.logLevel))) {
                config.logLevel = "error";
            }
            try {
                console[config.logLevel](finalMessage);
            } catch (err) {
                console.error(finalMessage);
            }

        }
    };
    var validator = function(data, option, config, dataKey) {
        var dataType = typeof data;
        dataType = dataType.toLowerCase();
        // If data is not available but need to required
        if (_isUndefined(data) && (_isSet(option.required) && option.required && _isSet(option.type) && !_isEmpty(option.type))) {
            validatorLogger("Required but undefined data", dataType, option, config, dataKey);
            return false;
        }
        if (_isSet(data) && (_isSet(option.validator) && _isFunction(option.validator) && !option.validator(data))) {
            validatorLogger("Validator function isn't valid", dataType, option, config, dataKey);
            return false;
        }
        if (_isSet(data) && (_isSet(option.validator) && !option.validator)) {
            validatorLogger("Validator isn't valid", dataType, option, config, dataKey);
            return false;
        }
        if (_isSet(option.type)) {
            if (!_isArray(option.type)) {
                option.type = [option.type];
            }
            var optionType = [];
            for (var i = 0; i < option.type.length; i++) {
                optionType = optionType.concat(_getType(option.type).toLowerCase());
            }
            if (!_inArray(dataType, optionType)) {
                validatorLogger("Required type mismatch", dataType, option, config, dataKey);
                return false;
            }
        }
        if (_isUndefined(option.required) || (_isSet(option.required) && option.required === false)) {
            return true;
        }
        return true;
    };
	var config = ( _isSet(args[1]) && _isObject(args[1]) ? args[1] : {
		enabled: true,
		logLevel: 'error'	} );

	return function(values) {
		if (!config.enabled) return true; // skip validations if disabled
		//if (!_isObject(values)) return false; // Check is object or return false
		for (var key in options) {
			var data = values[key];
			var option = options[key];
			if (option == null) continue;
			if (_isObject(option)) {
				objectPropValidator(option, config)(data);
				validator(data, option, config, key);
			}
		}
		return true;
	};
}
<commit_msg>prettier<commit_after>import values from 'lodash/values';
import { ContentNodeKinds, LearningActivities } from 'kolibri.coreVue.vuex.constants';
import every from 'lodash/every';
import keys from 'lodash/keys';

/**
 * Validation for vue router "location descriptor objects".
 * See e.g. https://router.vuejs.org/en/api/router-link.html
 */
export function validateLinkObject(object) {
  const validKeys = ['name', 'path', 'params', 'query'];
  return every(keys(object), key => validKeys.includes(key));
}

export function validateUsername(username) {
  const hasPuncRe = /[\s`~!@#$%^&*()\-+={}\[\]\|\\\/:;"'<>,\.\?]/; // eslint-disable-line
  return !hasPuncRe.test(username);
}

export function validateContentNodeKind(value, others = []) {
  return [...values(ContentNodeKinds), ...others].includes(value);
}

export function validateLearningActivity(arr) {
  const isValidLearningActivity = v => Object.values(LearningActivities).includes(v);
  return arr.length > 0 && arr.every(isValidLearningActivity);
}

export function objectValidator(spec) {
  console.log('VALIDATE');
  console.log(spec);
  return () => true;
}

export function objectPropValidator(options) {
  var args = arguments || [];
  var _getType = function(variable) {
    var match = false;
    var rawType = '';
    try {
      match = variable && variable.toString().match(/^\s*function (\w+)/);
    } catch {}
    try {
      rawType = Object.prototype.toString.call(variable).slice(8, -1);
    } catch {}
    return match
      ? match[1]
      : rawType.length > 0
      ? rawType
      : typeof variable == 'function' || typeof variable.name != 'undefined'
      ? variable.name
      : '';
  };
  var _isUndefined = function(variable) {
    return typeof variable === 'undefined';
  };
  var _isSet = function(variable) {
    return typeof variable !== 'undefined';
  };
  var _isString = function(variable) {
    return typeof variable === 'string';
  };
  var _isNumber = function(variable) {
    return typeof variable === 'number';
  };
  var _isFinite = function(variable) {
    return isFinite(variable);
  };
  var _isInfinity = function(variable) {
    return typeof variable === 'number' && !isFinite(variable);
  };
  var _isBoolean = function(variable) {
    return typeof variable === 'boolean';
  };
  var _isBigInt = function(variable) {
    return typeof variable === 'bigint';
  };
  var _isFlatten = function(variable) {
    return (
      typeof variable === 'string' || typeof variable === 'number' || typeof variable === 'boolean'
    );
  };
  var _isEmpty = function(variable) {
    if (
      typeof variable === 'undefined' ||
      variable === '' ||
      variable === 0 ||
      variable === [] ||
      variable === {} ||
      variable === false ||
      variable === null ||
      isNaN(variable) ||
      variable === function() {}
    ) {
      return true;
    }
    return false;
  };
  var _isArray = function(variable) {
    if (typeof Array != 'undefined' && typeof Array.isArray != 'undefined') {
      return Array.isArray(variable);
    }
    if (variable.constructor && variable.constructor.name && variable.constructor.name == 'Array') {
      return true;
    }
    if (
      typeof Object != 'undefined' &&
      Object.prototype &&
      Object.prototype.toString &&
      Object.prototype.toString.call &&
      Object.prototype.toString.call(variable) == '[object Array]'
    );
    {
      return true;
    }
    return false;
  };
  var _inArray = function(needle, haystack) {
    if (typeof haystack.indexOf != 'undefined') {
      return haystack.indexOf(needle) > -1;
    }
    return false;
  };
  var _isFunction = function(variable) {
    return typeof variable === 'function';
  };
  var _isObject = function(variable) {
    return typeof variable === 'object';
  };
  var _isPureObject = function(variable) {
    return (
      typeof variable === 'object' && typeof Object != 'undefined' && variable === Object(variable)
    );
  };
  var _isSymbol = function(variable) {
    return typeof variable === 'undefined';
  };
  var _isRegularType = function(variable) {
    var regularTypes = [String, Number, Boolean, Function, BigInt, Object, Array, Symbol];
    var regularTypesStr = [
      'String',
      'Number',
      'Boolean',
      'Function',
      'BigInt',
      'Object',
      'Array',
      'Symbol',
    ];
    if (regularTypes.indexOf(variable) > -1) {
      return true;
    }
    if (regularTypesStr.indexOf(variable) > -1) {
      return true;
    }
    return false;
  };
  var validatorLogger = function(msg, dataType, option, config, dataKey) {
    var dataMsg = 'CURRENT DATA TYPE: ' + dataType;
    var optMsg = 'NEED DATA TYPE';
    switch (true) {
      case _isUndefined(option.type):
        {
          optMsg += ': Undefined';
        }
        break;
      case _isArray(option.type):
        {
          if (option.type.length <= 1) {
            optMsg += ': ' + (_isSet(option.type[0]) ? _getType(option.type[0]) : 'Undefined');
          } else {
            optMsg += '(in): [';
            for (var i = 0; i < option.type.length; i++) {
              optMsg += _getType(option.type[i]).toLowerCase();
            }
            optMsg.slice(0, -1);
            optMsg += ']';
          }
        }
        break;
      default:
        {
          optMsg += _getType(option.type).toLowerCase();
        }
        break;
    }
    var finalMessage = '[Error](objectPropValidator): ' + msg;
    if ('Required type mismatch' === msg) {
      finalMessage += '. Correction need: ' + dataMsg + ', ' + optMsg;
    }
    finalMessage += '. Key name: ' + dataKey + '.';

    // Logger function check, ensure and call
    if (!(_isSet(config.logLevel) && config.logLevel === null)) {
      if (_isSet(config.logLevel) && config.logLevel == 'throw') {
        if (_isSet(Error)) {
          throw new Error(finalMessage);
        } else {
          throw finalMessage;
        }
      } else if (
        _isUndefined(config.logLevel) ||
        (_isSet(config.logLevel) && !console.hasOwnProperty(config.logLevel))
      ) {
        config.logLevel = 'error';
      }
      try {
        console[config.logLevel](finalMessage);
      } catch (err) {
        console.error(finalMessage);
      }
    }
  };
  var validator = function(data, option, config, dataKey) {
    var dataType = typeof data;
    dataType = dataType.toLowerCase();
    // If data is not available but need to required
    if (
      _isUndefined(data) &&
      _isSet(option.required) &&
      option.required &&
      _isSet(option.type) &&
      !_isEmpty(option.type)
    ) {
      validatorLogger('Required but undefined data', dataType, option, config, dataKey);
      return false;
    }
    if (
      _isSet(data) &&
      _isSet(option.validator) &&
      _isFunction(option.validator) &&
      !option.validator(data)
    ) {
      validatorLogger("Validator function isn't valid", dataType, option, config, dataKey);
      return false;
    }
    if (_isSet(data) && _isSet(option.validator) && !option.validator) {
      validatorLogger("Validator isn't valid", dataType, option, config, dataKey);
      return false;
    }
    if (_isSet(option.type)) {
      if (!_isArray(option.type)) {
        option.type = [option.type];
      }
      var optionType = [];
      for (var i = 0; i < option.type.length; i++) {
        optionType = optionType.concat(_getType(option.type).toLowerCase());
      }
      if (!_inArray(dataType, optionType)) {
        validatorLogger('Required type mismatch', dataType, option, config, dataKey);
        return false;
      }
    }
    if (_isUndefined(option.required) || (_isSet(option.required) && option.required === false)) {
      return true;
    }
    return true;
  };
  var config =
    _isSet(args[1]) && _isObject(args[1])
      ? args[1]
      : {
          enabled: true,
          logLevel: 'error',
        };

  return function(values) {
    if (!config.enabled) return true; // skip validations if disabled
    //if (!_isObject(values)) return false; // Check is object or return false
    for (var key in options) {
      var data = values[key];
      var option = options[key];
      if (option == null) continue;
      if (_isObject(option)) {
        objectPropValidator(option, config)(data);
        validator(data, option, config, key);
      }
    }
    return true;
  };
}
<|endoftext|>


<commit_before>import EmberObject from '@ember/object';
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import {
  render,
  click,
  findAll,
  find,
  triggerEvent,
} from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Component | class field description', function (hooks) {
  setupRenderingTest(hooks);

  test('it renders', async function (assert) {
    this.set('type', 'method');
    this.set(
      'field',
      EmberObject.create({
        access: 'public',
        deprecated: true,
        name: 'concat',
        description: 'concatenates',
        params: [{ name: 'param1' }, { name: 'param2' }, { name: 'param3' }],
      })
    );

    await render(hbs`{{class-field-description type=type field=field}}`);

    assert.dom('.method-name').hasText('concat');
    assert.dom(findAll('.access')[0]).hasText('public');
    assert.dom(findAll('.access')[1]).hasText('deprecated');
    assert.dom(findAll('.args')[0]).hasText('(param1, param2, param3)');
  });

  test('On hover -- the link icon shows up', async function (assert) {
    this.set('type', 'method');
    this.set(
      'field',
      EmberObject.create({
        access: 'public',
        deprecated: true,
        name: 'concat',
        description: 'concatenates',
        params: [{ name: 'param1' }, { name: 'param2' }, { name: 'param3' }],
      })
    );

    await render(hbs`{{class-field-description type=type field=field}}`);

    await triggerEvent('.class-field-description--link', 'mouseenter');
    assert
      .dom('.class-field-description--link-hover')
      .exists('The link icon appears when hovering on the method text');
  });

  test('it calls the provided action on link-click with the field name as an arg', async function (assert) {
    this.set('updateAnchor', (name) => {
      assert.equal(
        name,
        'field-name',
        'expected the field name to be passed into the action'
      );
      assert.step('updateAnchorAction');
    });

    this.set(
      'field',
      EmberObject.create({
        name: 'field-name',
      })
    );

    await render(
      hbs`{{class-field-description field=field updateAnchor=updateAnchor}}`
    );

    await click('.class-field-description--link');

    assert.verifySteps(['updateAnchorAction']);
  });

  test('parameter props are displayed', async function (assert) {
    this.set('type', 'method');
    this.set(
      'field',
      EmberObject.create({
        access: 'public',
        deprecated: true,
        name: 'concat',
        description: 'concatenates',
        params: [
          { name: 'param1' },
          { name: 'param2' },
          { name: 'options', props: [{ name: 'prop1' }, { name: 'prop2' }] },
        ],
      })
    );

    await render(hbs`{{class-field-description type=type field=field}}`);

    assert.dom(find('.prop:nth-child(1) dt')).hasText('prop1');
    assert.dom(find('.prop:nth-child(2) dt')).hasText('prop2');
  });
});
<commit_msg>tests: class-field-desc: prefer angle syntax<commit_after>import EmberObject from '@ember/object';
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import {
  render,
  click,
  findAll,
  find,
  triggerEvent,
} from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';

module('Integration | Component | class field description', function (hooks) {
  setupRenderingTest(hooks);

  test('it renders', async function (assert) {
    this.set('type', 'method');
    this.set(
      'field',
      EmberObject.create({
        access: 'public',
        deprecated: true,
        name: 'concat',
        description: 'concatenates',
        params: [{ name: 'param1' }, { name: 'param2' }, { name: 'param3' }],
      })
    );

    await render(
      hbs`<ClassFieldDescription @type={{this.type}} @field={{this.field}}/>`
    );

    assert.dom('.method-name').hasText('concat');
    assert.dom(findAll('.access')[0]).hasText('public');
    assert.dom(findAll('.access')[1]).hasText('deprecated');
    assert.dom(findAll('.args')[0]).hasText('(param1, param2, param3)');
  });

  test('On hover -- the link icon shows up', async function (assert) {
    this.set('type', 'method');
    this.set(
      'field',
      EmberObject.create({
        access: 'public',
        deprecated: true,
        name: 'concat',
        description: 'concatenates',
        params: [{ name: 'param1' }, { name: 'param2' }, { name: 'param3' }],
      })
    );

    await render(
      hbs`<ClassFieldDescription @type={{this.type}} @field={{this.field}}/>`
    );

    await triggerEvent('.class-field-description--link', 'mouseenter');
    assert
      .dom('.class-field-description--link-hover')
      .exists('The link icon appears when hovering on the method text');
  });

  test('it calls the provided action on link-click with the field name as an arg', async function (assert) {
    this.set('updateAnchor', (name) => {
      assert.equal(
        name,
        'field-name',
        'expected the field name to be passed into the action'
      );
      assert.step('updateAnchorAction');
    });

    this.set(
      'field',
      EmberObject.create({
        name: 'field-name',
      })
    );

    await render(
      hbs`<ClassFieldDescription @field={{this.field}} @updateAnchor={{this.updateAnchor}}/>`
    );

    await click('.class-field-description--link');

    assert.verifySteps(['updateAnchorAction']);
  });

  test('parameter props are displayed', async function (assert) {
    this.set('type', 'method');
    this.set(
      'field',
      EmberObject.create({
        access: 'public',
        deprecated: true,
        name: 'concat',
        description: 'concatenates',
        params: [
          { name: 'param1' },
          { name: 'param2' },
          { name: 'options', props: [{ name: 'prop1' }, { name: 'prop2' }] },
        ],
      })
    );

    await render(
      hbs`<ClassFieldDescription @type={{this.type}} @field={{this.field}}/>`
    );

    assert.dom(find('.prop:nth-child(1) dt')).hasText('prop1');
    assert.dom(find('.prop:nth-child(2) dt')).hasText('prop2');
  });
});
<|endoftext|>