axyseo 2.1.24 → 2.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/build/cjs/const/analysis.js +40 -3
  2. package/build/cjs/const/analysis.js.map +1 -1
  3. package/build/cjs/languageProcessing/AbstractResearcher.js +3 -1
  4. package/build/cjs/languageProcessing/AbstractResearcher.js.map +1 -1
  5. package/build/cjs/languageProcessing/languages/ja/helpers/countCharacters.js +5 -1
  6. package/build/cjs/languageProcessing/languages/ja/helpers/countCharacters.js.map +1 -1
  7. package/build/cjs/languageProcessing/researches/charactersInUrl.js +26 -0
  8. package/build/cjs/languageProcessing/researches/charactersInUrl.js.map +1 -0
  9. package/build/cjs/languageProcessing/researches/checkRelatedKeywords.js +0 -1
  10. package/build/cjs/languageProcessing/researches/checkRelatedKeywords.js.map +1 -1
  11. package/build/cjs/languageProcessing/researches/getKeywordDensity.js.map +1 -1
  12. package/build/cjs/scoring/assessments/assessment.js +5 -6
  13. package/build/cjs/scoring/assessments/assessment.js.map +1 -1
  14. package/build/cjs/scoring/assessments/index.js +12 -6
  15. package/build/cjs/scoring/assessments/index.js.map +1 -1
  16. package/build/cjs/scoring/assessments/readability/ParagraphTooLongAssessment.js +18 -17
  17. package/build/cjs/scoring/assessments/readability/ParagraphTooLongAssessment.js.map +1 -1
  18. package/build/cjs/scoring/assessments/readability/RelatedKeywordsAssessment.js +11 -25
  19. package/build/cjs/scoring/assessments/readability/RelatedKeywordsAssessment.js.map +1 -1
  20. package/build/cjs/scoring/assessments/readability/SentenceBeginningsAssessment.js +3 -1
  21. package/build/cjs/scoring/assessments/readability/SentenceBeginningsAssessment.js.map +1 -1
  22. package/build/cjs/scoring/assessments/readability/SentenceLengthInTextAssessment.js +11 -11
  23. package/build/cjs/scoring/assessments/readability/SentenceLengthInTextAssessment.js.map +1 -1
  24. package/build/cjs/scoring/assessments/readability/TransitionWordsAssessment.js +1 -1
  25. package/build/cjs/scoring/assessments/readability/TransitionWordsAssessment.js.map +1 -1
  26. package/build/cjs/scoring/assessments/seo/FAQsAssessment.js +7 -52
  27. package/build/cjs/scoring/assessments/seo/FAQsAssessment.js.map +1 -1
  28. package/build/cjs/scoring/assessments/seo/FAQsStructureDataAssessment.js +83 -0
  29. package/build/cjs/scoring/assessments/seo/FAQsStructureDataAssessment.js.map +1 -0
  30. package/build/cjs/scoring/assessments/seo/ImageCountAssessment.js +2 -2
  31. package/build/cjs/scoring/assessments/seo/ImageCountAssessment.js.map +1 -1
  32. package/build/cjs/scoring/assessments/seo/InternalLinksAssessment.js +5 -5
  33. package/build/cjs/scoring/assessments/seo/InternalLinksAssessment.js.map +1 -1
  34. package/build/cjs/scoring/assessments/seo/IntroductionKeywordAssessment.js +4 -5
  35. package/build/cjs/scoring/assessments/seo/IntroductionKeywordAssessment.js.map +1 -1
  36. package/build/cjs/scoring/assessments/seo/InvalidCharactersInUrl.js +93 -0
  37. package/build/cjs/scoring/assessments/seo/InvalidCharactersInUrl.js.map +1 -0
  38. package/build/cjs/scoring/assessments/seo/KeyphraseAssessment.js +4 -4
  39. package/build/cjs/scoring/assessments/seo/KeyphraseAssessment.js.map +1 -1
  40. package/build/cjs/scoring/assessments/seo/KeyphraseLengthAssessment.js +5 -6
  41. package/build/cjs/scoring/assessments/seo/KeyphraseLengthAssessment.js.map +1 -1
  42. package/build/cjs/scoring/assessments/seo/KeywordDensityAssessment.js +3 -5
  43. package/build/cjs/scoring/assessments/seo/KeywordDensityAssessment.js.map +1 -1
  44. package/build/cjs/scoring/assessments/seo/KeywordFAQsAssessment.js +4 -5
  45. package/build/cjs/scoring/assessments/seo/KeywordFAQsAssessment.js.map +1 -1
  46. package/build/cjs/scoring/assessments/seo/MetaDescriptionKeywordAssessment.js +6 -6
  47. package/build/cjs/scoring/assessments/seo/MetaDescriptionKeywordAssessment.js.map +1 -1
  48. package/build/cjs/scoring/assessments/seo/MetaDescriptionLengthAssessment.js +3 -6
  49. package/build/cjs/scoring/assessments/seo/MetaDescriptionLengthAssessment.js.map +1 -1
  50. package/build/cjs/scoring/assessments/seo/MetaTitleKeywordAssessment.js +2 -2
  51. package/build/cjs/scoring/assessments/seo/MetaTitleKeywordAssessment.js.map +1 -1
  52. package/build/cjs/scoring/assessments/seo/NumberInMetaTitleAssessment.js +2 -2
  53. package/build/cjs/scoring/assessments/seo/NumberInMetaTitleAssessment.js.map +1 -1
  54. package/build/cjs/scoring/assessments/seo/OutboundLinksAssessment.js +5 -6
  55. package/build/cjs/scoring/assessments/seo/OutboundLinksAssessment.js.map +1 -1
  56. package/build/cjs/scoring/assessments/seo/PageTitleWidthAssessment.js +3 -5
  57. package/build/cjs/scoring/assessments/seo/PageTitleWidthAssessment.js.map +1 -1
  58. package/build/cjs/scoring/assessments/seo/RelatedKeywordsDensityAssessment.js +103 -0
  59. package/build/cjs/scoring/assessments/seo/RelatedKeywordsDensityAssessment.js.map +1 -0
  60. package/build/cjs/scoring/assessments/seo/SchemaAssessment.js +16 -2
  61. package/build/cjs/scoring/assessments/seo/SchemaAssessment.js.map +1 -1
  62. package/build/cjs/scoring/assessments/seo/SingleH1Assessment.js +3 -3
  63. package/build/cjs/scoring/assessments/seo/SingleH1Assessment.js.map +1 -1
  64. package/build/cjs/scoring/assessments/seo/SingleTitleAssessment.js +3 -5
  65. package/build/cjs/scoring/assessments/seo/SingleTitleAssessment.js.map +1 -1
  66. package/build/cjs/scoring/assessments/seo/SubHeadingsKeywordAssessment.js +3 -5
  67. package/build/cjs/scoring/assessments/seo/SubHeadingsKeywordAssessment.js.map +1 -1
  68. package/build/cjs/scoring/assessments/seo/TextImagesAssessment.js +5 -4
  69. package/build/cjs/scoring/assessments/seo/TextImagesAssessment.js.map +1 -1
  70. package/build/cjs/scoring/assessments/seo/TextLengthAssessment.js +52 -18
  71. package/build/cjs/scoring/assessments/seo/TextLengthAssessment.js.map +1 -1
  72. package/build/cjs/scoring/assessments/seo/UrlKeywordAssessment.js +3 -3
  73. package/build/cjs/scoring/assessments/seo/UrlKeywordAssessment.js.map +1 -1
  74. package/build/cjs/scoring/assessments/seo/UrlLengthAssessment.js +2 -4
  75. package/build/cjs/scoring/assessments/seo/UrlLengthAssessment.js.map +1 -1
  76. package/build/cjs/scoring/assessors/assessor.js +0 -1
  77. package/build/cjs/scoring/assessors/assessor.js.map +1 -1
  78. package/build/cjs/scoring/assessors/avadaAssessor.js +2 -16
  79. package/build/cjs/scoring/assessors/avadaAssessor.js.map +1 -1
  80. package/build/cjs/scoring/assessors/contentAssessor.js +2 -2
  81. package/build/cjs/scoring/assessors/contentAssessor.js.map +1 -1
  82. package/build/cjs/scoring/assessors/index.js +0 -14
  83. package/build/cjs/scoring/assessors/index.js.map +1 -1
  84. package/build/cjs/scoring/assessors/seoAssessor.js +6 -4
  85. package/build/cjs/scoring/assessors/seoAssessor.js.map +1 -1
  86. package/build/cjs/values/Paper.js +10 -2
  87. package/build/cjs/values/Paper.js.map +1 -1
  88. package/build/esm/const/analysis.js +39 -2
  89. package/build/esm/const/analysis.js.map +1 -1
  90. package/build/esm/languageProcessing/AbstractResearcher.js +3 -1
  91. package/build/esm/languageProcessing/AbstractResearcher.js.map +1 -1
  92. package/build/esm/languageProcessing/languages/ja/helpers/countCharacters.js +5 -1
  93. package/build/esm/languageProcessing/languages/ja/helpers/countCharacters.js.map +1 -1
  94. package/build/esm/languageProcessing/researches/charactersInUrl.js +21 -0
  95. package/build/esm/languageProcessing/researches/charactersInUrl.js.map +1 -0
  96. package/build/esm/languageProcessing/researches/checkRelatedKeywords.js +0 -1
  97. package/build/esm/languageProcessing/researches/checkRelatedKeywords.js.map +1 -1
  98. package/build/esm/languageProcessing/researches/getKeywordDensity.js.map +1 -1
  99. package/build/esm/scoring/assessments/assessment.js +6 -7
  100. package/build/esm/scoring/assessments/assessment.js.map +1 -1
  101. package/build/esm/scoring/assessments/index.js +12 -6
  102. package/build/esm/scoring/assessments/index.js.map +1 -1
  103. package/build/esm/scoring/assessments/readability/ParagraphTooLongAssessment.js +19 -18
  104. package/build/esm/scoring/assessments/readability/ParagraphTooLongAssessment.js.map +1 -1
  105. package/build/esm/scoring/assessments/readability/RelatedKeywordsAssessment.js +12 -26
  106. package/build/esm/scoring/assessments/readability/RelatedKeywordsAssessment.js.map +1 -1
  107. package/build/esm/scoring/assessments/readability/SentenceBeginningsAssessment.js +4 -2
  108. package/build/esm/scoring/assessments/readability/SentenceBeginningsAssessment.js.map +1 -1
  109. package/build/esm/scoring/assessments/readability/SentenceLengthInTextAssessment.js +12 -12
  110. package/build/esm/scoring/assessments/readability/SentenceLengthInTextAssessment.js.map +1 -1
  111. package/build/esm/scoring/assessments/readability/TransitionWordsAssessment.js +2 -2
  112. package/build/esm/scoring/assessments/readability/TransitionWordsAssessment.js.map +1 -1
  113. package/build/esm/scoring/assessments/seo/FAQsAssessment.js +8 -53
  114. package/build/esm/scoring/assessments/seo/FAQsAssessment.js.map +1 -1
  115. package/build/esm/scoring/assessments/seo/FAQsStructureDataAssessment.js +76 -0
  116. package/build/esm/scoring/assessments/seo/FAQsStructureDataAssessment.js.map +1 -0
  117. package/build/esm/scoring/assessments/seo/ImageCountAssessment.js +3 -3
  118. package/build/esm/scoring/assessments/seo/ImageCountAssessment.js.map +1 -1
  119. package/build/esm/scoring/assessments/seo/InternalLinksAssessment.js +6 -6
  120. package/build/esm/scoring/assessments/seo/InternalLinksAssessment.js.map +1 -1
  121. package/build/esm/scoring/assessments/seo/IntroductionKeywordAssessment.js +5 -6
  122. package/build/esm/scoring/assessments/seo/IntroductionKeywordAssessment.js.map +1 -1
  123. package/build/esm/scoring/assessments/seo/InvalidCharactersInUrl.js +87 -0
  124. package/build/esm/scoring/assessments/seo/InvalidCharactersInUrl.js.map +1 -0
  125. package/build/esm/scoring/assessments/seo/KeyphraseAssessment.js +5 -5
  126. package/build/esm/scoring/assessments/seo/KeyphraseAssessment.js.map +1 -1
  127. package/build/esm/scoring/assessments/seo/KeyphraseLengthAssessment.js +6 -7
  128. package/build/esm/scoring/assessments/seo/KeyphraseLengthAssessment.js.map +1 -1
  129. package/build/esm/scoring/assessments/seo/KeywordDensityAssessment.js +4 -6
  130. package/build/esm/scoring/assessments/seo/KeywordDensityAssessment.js.map +1 -1
  131. package/build/esm/scoring/assessments/seo/KeywordFAQsAssessment.js +5 -6
  132. package/build/esm/scoring/assessments/seo/KeywordFAQsAssessment.js.map +1 -1
  133. package/build/esm/scoring/assessments/seo/MetaDescriptionKeywordAssessment.js +8 -8
  134. package/build/esm/scoring/assessments/seo/MetaDescriptionKeywordAssessment.js.map +1 -1
  135. package/build/esm/scoring/assessments/seo/MetaDescriptionLengthAssessment.js +4 -7
  136. package/build/esm/scoring/assessments/seo/MetaDescriptionLengthAssessment.js.map +1 -1
  137. package/build/esm/scoring/assessments/seo/MetaTitleKeywordAssessment.js +3 -3
  138. package/build/esm/scoring/assessments/seo/MetaTitleKeywordAssessment.js.map +1 -1
  139. package/build/esm/scoring/assessments/seo/NumberInMetaTitleAssessment.js +3 -3
  140. package/build/esm/scoring/assessments/seo/NumberInMetaTitleAssessment.js.map +1 -1
  141. package/build/esm/scoring/assessments/seo/OutboundLinksAssessment.js +6 -7
  142. package/build/esm/scoring/assessments/seo/OutboundLinksAssessment.js.map +1 -1
  143. package/build/esm/scoring/assessments/seo/PageTitleWidthAssessment.js +4 -6
  144. package/build/esm/scoring/assessments/seo/PageTitleWidthAssessment.js.map +1 -1
  145. package/build/esm/scoring/assessments/seo/RelatedKeywordsDensityAssessment.js +96 -0
  146. package/build/esm/scoring/assessments/seo/RelatedKeywordsDensityAssessment.js.map +1 -0
  147. package/build/esm/scoring/assessments/seo/SchemaAssessment.js +17 -3
  148. package/build/esm/scoring/assessments/seo/SchemaAssessment.js.map +1 -1
  149. package/build/esm/scoring/assessments/seo/SingleH1Assessment.js +4 -4
  150. package/build/esm/scoring/assessments/seo/SingleH1Assessment.js.map +1 -1
  151. package/build/esm/scoring/assessments/seo/SingleTitleAssessment.js +4 -6
  152. package/build/esm/scoring/assessments/seo/SingleTitleAssessment.js.map +1 -1
  153. package/build/esm/scoring/assessments/seo/SubHeadingsKeywordAssessment.js +4 -6
  154. package/build/esm/scoring/assessments/seo/SubHeadingsKeywordAssessment.js.map +1 -1
  155. package/build/esm/scoring/assessments/seo/TextImagesAssessment.js +6 -5
  156. package/build/esm/scoring/assessments/seo/TextImagesAssessment.js.map +1 -1
  157. package/build/esm/scoring/assessments/seo/TextLengthAssessment.js +54 -19
  158. package/build/esm/scoring/assessments/seo/TextLengthAssessment.js.map +1 -1
  159. package/build/esm/scoring/assessments/seo/UrlKeywordAssessment.js +4 -4
  160. package/build/esm/scoring/assessments/seo/UrlKeywordAssessment.js.map +1 -1
  161. package/build/esm/scoring/assessments/seo/UrlLengthAssessment.js +3 -5
  162. package/build/esm/scoring/assessments/seo/UrlLengthAssessment.js.map +1 -1
  163. package/build/esm/scoring/assessors/assessor.js +0 -1
  164. package/build/esm/scoring/assessors/assessor.js.map +1 -1
  165. package/build/esm/scoring/assessors/avadaAssessor.js +3 -17
  166. package/build/esm/scoring/assessors/avadaAssessor.js.map +1 -1
  167. package/build/esm/scoring/assessors/contentAssessor.js +2 -2
  168. package/build/esm/scoring/assessors/contentAssessor.js.map +1 -1
  169. package/build/esm/scoring/assessors/index.js +0 -2
  170. package/build/esm/scoring/assessors/index.js.map +1 -1
  171. package/build/esm/scoring/assessors/seoAssessor.js +6 -4
  172. package/build/esm/scoring/assessors/seoAssessor.js.map +1 -1
  173. package/build/esm/values/Paper.js +10 -2
  174. package/build/esm/values/Paper.js.map +1 -1
  175. package/package.json +4 -2
@@ -1,7 +1,8 @@
1
1
  import { merge, partition, sortBy } from 'lodash';
2
2
  import AssessmentResult from "../../../values/AssessmentResult";
3
3
  import Assessment from "../assessment";
4
- import { SENTENCE_BEGINNINGS_ID } from "../../../const/analysis";
4
+ import { TextBlockIcon } from '@shopify/polaris-icons';
5
+ import { MAIN_CONTENT_POINTS, SENTENCE_BEGINNINGS_ID } from "../../../const/analysis";
5
6
  const maximumConsecutiveDuplicates = 2;
6
7
 
7
8
  /**
@@ -23,6 +24,7 @@ export default class SentenceBeginningsAssessment extends Assessment {
23
24
  ctaType: 'fix',
24
25
  docUrl: 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#sentence-beginnings',
25
26
  fixPosition: 'description',
27
+ icon: TextBlockIcon,
26
28
  title: 'Sentence beginnings',
27
29
  content: {
28
30
  improve: '',
@@ -71,7 +73,7 @@ export default class SentenceBeginningsAssessment extends Assessment {
71
73
  } else {
72
74
  status = 'good';
73
75
  }
74
- const score = this.getScore(this._config.priority, status);
76
+ const score = this.getScore(MAIN_CONTENT_POINTS, status);
75
77
  return {
76
78
  score,
77
79
  status
@@ -1 +1 @@
1
- {"version":3,"file":"SentenceBeginningsAssessment.js","names":["merge","partition","sortBy","AssessmentResult","Assessment","SENTENCE_BEGINNINGS_ID","maximumConsecutiveDuplicates","SentenceBeginningsAssessment","constructor","config","defaultConfig","id","priority","ctaType","docUrl","fixPosition","title","content","improve","bad","good","identifier","_config","groupSentenceBeginnings","sentenceBeginnings","tooOften","word","count","length","total","sortedCounts","lowestCount","calculateSentenceBeginningsResult","groupedSentenceBeginnings","status","score","getScore","getResult","paper","researcher","getResearch","sentenceBeginningsErrors","filter","sentenceBeginning","calculatedResult","assessmentResult","setData","setScore","setStatus","isApplicable","hasEnoughContentForAssessment","hasResearch"],"sources":["../../../../../src/scoring/assessments/readability/SentenceBeginningsAssessment.js"],"sourcesContent":["import {merge, partition, sortBy} from 'lodash';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport Assessment from '../assessment';\n\nimport {SENTENCE_BEGINNINGS_ID} from '@axyseo/const/analysis';\n\nconst maximumConsecutiveDuplicates = 2;\n\n/**\n * Represents the assessment that checks whether there are three or more consecutive sentences beginning with the same word.\n */\nexport default class SentenceBeginningsAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {object} config The configuration to use.\n *\n * @returns {void}\n */\n constructor(config = {}) {\n super();\n\n const defaultConfig = {\n id: SENTENCE_BEGINNINGS_ID,\n priority: 'medium',\n ctaType: 'fix',\n docUrl:\n 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#sentence-beginnings',\n fixPosition: 'description',\n title: 'Sentence beginnings',\n content: {\n improve: '',\n bad:\n 'Found sentences with repetitive beginnings. Change the wording for more engaging content.',\n good: 'No sentences with repetitive beginnings found.'\n }\n };\n\n this.identifier = SENTENCE_BEGINNINGS_ID;\n this._config = merge(defaultConfig, config);\n }\n\n /**\n * Counts and groups the number too often used sentence beginnings and determines the lowest count within that group.\n *\n * @param {array} sentenceBeginnings The array containing the objects containing the beginning words and counts.\n *\n * @returns {object} The object containing the total number of too often used beginnings and the lowest count within those.\n */\n groupSentenceBeginnings(sentenceBeginnings) {\n const tooOften = partition(sentenceBeginnings, function(word) {\n return word.count > maximumConsecutiveDuplicates;\n });\n\n if (tooOften[0].length === 0) {\n return {total: 0};\n }\n\n const sortedCounts = sortBy(tooOften[0], function(word) {\n return word.count;\n });\n\n return {total: tooOften[0].length, lowestCount: sortedCounts[0].count};\n }\n\n /**\n *\n * @param groupedSentenceBeginnings\n * @returns {{score: number, status: string}}\n */\n calculateSentenceBeginningsResult(groupedSentenceBeginnings) {\n let status = '';\n if (groupedSentenceBeginnings.total > 0) {\n status = 'bad';\n } else {\n status = 'good';\n }\n\n const score = this.getScore(this._config.priority, status);\n\n return {\n score,\n status\n };\n }\n\n /**\n *\n * @param paper\n * @param researcher\n * @returns {AssessmentResult}\n */\n getResult({paper, researcher}) {\n const sentenceBeginnings = researcher.getResearch('getSentenceBeginnings');\n const sentenceBeginningsErrors = sentenceBeginnings.filter(\n sentenceBeginning => sentenceBeginning.count > maximumConsecutiveDuplicates\n );\n\n const groupedSentenceBeginnings = this.groupSentenceBeginnings(sentenceBeginnings);\n const calculatedResult = this.calculateSentenceBeginningsResult(groupedSentenceBeginnings);\n const assessmentResult = new AssessmentResult({config: this._config});\n\n assessmentResult.setData(sentenceBeginningsErrors);\n assessmentResult.setScore(calculatedResult.score);\n assessmentResult.setStatus(calculatedResult.status);\n\n return assessmentResult;\n }\n\n /**\n * Checks if the sentence beginnings assessment is applicable to the paper.\n *\n * @param {Object} paper The paper to check.\n * @param {Researcher} researcher The researcher object.\n *\n * @returns {boolean} Returns true if the language is available and the paper is not empty.\n */\n isApplicable(paper, researcher) {\n return (\n this.hasEnoughContentForAssessment(paper) && researcher.hasResearch('getSentenceBeginnings')\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"SentenceBeginningsAssessment.js","names":["merge","partition","sortBy","AssessmentResult","Assessment","TextBlockIcon","MAIN_CONTENT_POINTS","SENTENCE_BEGINNINGS_ID","maximumConsecutiveDuplicates","SentenceBeginningsAssessment","constructor","config","defaultConfig","id","priority","ctaType","docUrl","fixPosition","icon","title","content","improve","bad","good","identifier","_config","groupSentenceBeginnings","sentenceBeginnings","tooOften","word","count","length","total","sortedCounts","lowestCount","calculateSentenceBeginningsResult","groupedSentenceBeginnings","status","score","getScore","getResult","paper","researcher","getResearch","sentenceBeginningsErrors","filter","sentenceBeginning","calculatedResult","assessmentResult","setData","setScore","setStatus","isApplicable","hasEnoughContentForAssessment","hasResearch"],"sources":["../../../../../src/scoring/assessments/readability/SentenceBeginningsAssessment.js"],"sourcesContent":["import {merge, partition, sortBy} from 'lodash';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport Assessment from '../assessment';\nimport {TextBlockIcon} from '@shopify/polaris-icons';\nimport {MAIN_CONTENT_POINTS, SENTENCE_BEGINNINGS_ID} from '@axyseo/const/analysis';\n\nconst maximumConsecutiveDuplicates = 2;\n\n/**\n * Represents the assessment that checks whether there are three or more consecutive sentences beginning with the same word.\n */\nexport default class SentenceBeginningsAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {object} config The configuration to use.\n *\n * @returns {void}\n */\n constructor(config = {}) {\n super();\n\n const defaultConfig = {\n id: SENTENCE_BEGINNINGS_ID,\n priority: 'medium',\n ctaType: 'fix',\n docUrl:\n 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#sentence-beginnings',\n fixPosition: 'description',\n icon: TextBlockIcon,\n title: 'Sentence beginnings',\n content: {\n improve: '',\n bad:\n 'Found sentences with repetitive beginnings. Change the wording for more engaging content.',\n good: 'No sentences with repetitive beginnings found.'\n }\n };\n\n this.identifier = SENTENCE_BEGINNINGS_ID;\n this._config = merge(defaultConfig, config);\n }\n\n /**\n * Counts and groups the number too often used sentence beginnings and determines the lowest count within that group.\n *\n * @param {array} sentenceBeginnings The array containing the objects containing the beginning words and counts.\n *\n * @returns {object} The object containing the total number of too often used beginnings and the lowest count within those.\n */\n groupSentenceBeginnings(sentenceBeginnings) {\n const tooOften = partition(sentenceBeginnings, function(word) {\n return word.count > maximumConsecutiveDuplicates;\n });\n\n if (tooOften[0].length === 0) {\n return {total: 0};\n }\n\n const sortedCounts = sortBy(tooOften[0], function(word) {\n return word.count;\n });\n\n return {total: tooOften[0].length, lowestCount: sortedCounts[0].count};\n }\n\n /**\n *\n * @param groupedSentenceBeginnings\n * @returns {{score: number, status: string}}\n */\n calculateSentenceBeginningsResult(groupedSentenceBeginnings) {\n let status = '';\n if (groupedSentenceBeginnings.total > 0) {\n status = 'bad';\n } else {\n status = 'good';\n }\n\n const score = this.getScore(MAIN_CONTENT_POINTS, status);\n\n return {\n score,\n status\n };\n }\n\n /**\n *\n * @param paper\n * @param researcher\n * @returns {AssessmentResult}\n */\n getResult({paper, researcher}) {\n const sentenceBeginnings = researcher.getResearch('getSentenceBeginnings');\n const sentenceBeginningsErrors = sentenceBeginnings.filter(\n sentenceBeginning => sentenceBeginning.count > maximumConsecutiveDuplicates\n );\n\n const groupedSentenceBeginnings = this.groupSentenceBeginnings(sentenceBeginnings);\n const calculatedResult = this.calculateSentenceBeginningsResult(groupedSentenceBeginnings);\n const assessmentResult = new AssessmentResult({config: this._config});\n\n assessmentResult.setData(sentenceBeginningsErrors);\n assessmentResult.setScore(calculatedResult.score);\n assessmentResult.setStatus(calculatedResult.status);\n\n return assessmentResult;\n }\n\n /**\n * Checks if the sentence beginnings assessment is applicable to the paper.\n *\n * @param {Object} paper The paper to check.\n * @param {Researcher} researcher The researcher object.\n *\n * @returns {boolean} Returns true if the language is available and the paper is not empty.\n */\n isApplicable(paper, researcher) {\n return (\n this.hasEnoughContentForAssessment(paper) && researcher.hasResearch('getSentenceBeginnings')\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -3,7 +3,8 @@ import Assessment from "../assessment";
3
3
  import getTooLongSentences from "../../helpers/assessments/checkForTooLongSentences";
4
4
  import formatNumber from "../../../helpers/formatNumber";
5
5
  import AssessmentResult from "../../../values/AssessmentResult";
6
- import { TEXT_SENTENCE_LENGTH_ID } from "../../../const/analysis";
6
+ import { TextBlockIcon } from '@shopify/polaris-icons';
7
+ import { MAIN_CONTENT_POINTS, TEXT_SENTENCE_LENGTH_ID } from "../../../const/analysis";
7
8
 
8
9
  /**
9
10
  * Represents the assessment that will calculate the length of sentences in the text.
@@ -25,7 +26,7 @@ class SentenceLengthInTextAssessment extends Assessment {
25
26
  docUrl: 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#sentence-length',
26
27
  ctaType: 'fix',
27
28
  fixPosition: 'sentenceLength',
28
- icon: '',
29
+ icon: TextBlockIcon,
29
30
  recommendedLength: 20,
30
31
  slightlyTooMany: 25,
31
32
  farTooMany: 30,
@@ -53,11 +54,12 @@ class SentenceLengthInTextAssessment extends Assessment {
53
54
  researcher
54
55
  }) {
55
56
  const sentences = researcher.getResearch('countSentencesFromText');
57
+ const hasDescription = paper.hasDescription();
56
58
  if (researcher.getConfig('sentenceLength')) {
57
59
  this._config = this.getLanguageSpecificConfig(researcher);
58
60
  }
59
61
  const percentage = this.calculatePercentage(sentences);
60
- const result = this.calculateResult(percentage);
62
+ const result = this.calculateResult(percentage, hasDescription);
61
63
  const assessmentResult = new AssessmentResult({
62
64
  config: this._config
63
65
  });
@@ -74,7 +76,7 @@ class SentenceLengthInTextAssessment extends Assessment {
74
76
  * @returns {boolean} True when there is text.
75
77
  */
76
78
  isApplicable(paper) {
77
- return this.hasEnoughContentForAssessment(paper);
79
+ return true;
78
80
  }
79
81
 
80
82
  /**
@@ -111,21 +113,19 @@ class SentenceLengthInTextAssessment extends Assessment {
111
113
  /**
112
114
  *
113
115
  * @param percentage
116
+ * @param hasDescription
114
117
  * @returns {{score: number, status: string}}
115
118
  */
116
- calculateResult(percentage) {
117
- let status = '';
118
- if (percentage <= this._config.recommendedLength) {
119
+ calculateResult(percentage, hasDescription) {
120
+ let status = 'bad';
121
+ if (percentage <= 0 && hasDescription && percentage <= this._config.recommendedLength) {
119
122
  status = 'good';
120
123
  }
121
- if (percentage > this._config.recommendedLength) {
122
- status = 'bad';
123
- }
124
- const score = this.getScore(this._config.priority, status);
124
+ const score = this.getScore(MAIN_CONTENT_POINTS, status);
125
125
  this._config.content = {
126
126
  improve: '',
127
127
  bad: `Sentence too long. Keep sentence length less than ${this._config.recommendedLength} words to improve readability and flow.`,
128
- good: `Sentence length is optimized for readability, less than ${this._config.recommendedLength} words.`
128
+ good: `Sentences optimized`
129
129
  };
130
130
  return {
131
131
  score,
@@ -1 +1 @@
1
- {"version":3,"file":"SentenceLengthInTextAssessment.js","names":["merge","Assessment","getTooLongSentences","formatNumber","AssessmentResult","TEXT_SENTENCE_LENGTH_ID","SentenceLengthInTextAssessment","constructor","config","isCornerstone","isProduct","defaultConfig","id","priority","docUrl","ctaType","fixPosition","icon","recommendedLength","slightlyTooMany","farTooMany","title","content","improve","bad","good","_config","identifier","getResult","paper","researcher","sentences","getResearch","getConfig","getLanguageSpecificConfig","percentage","calculatePercentage","result","calculateResult","assessmentResult","setScore","score","setStatus","status","isApplicable","hasEnoughContentForAssessment","currentConfig","languageSpecificConfig","hasOwnProperty","length","tooLongTotal","countTooLongSentences","getScore"],"sources":["../../../../../src/scoring/assessments/readability/SentenceLengthInTextAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport Assessment from '../assessment';\nimport getTooLongSentences from '../../helpers/assessments/checkForTooLongSentences';\nimport formatNumber from '../../../helpers/formatNumber';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport {TEXT_SENTENCE_LENGTH_ID} from '@axyseo/const/analysis';\n\n/**\n * Represents the assessment that will calculate the length of sentences in the text.\n */\nclass SentenceLengthInTextAssessment extends Assessment {\n /**\n\t * Sets the identifier and the config.\n\t *\n\t * @param {object} config\t\t\tThe scoring configuration that should be used.\n\t * @param {boolean} isCornerstone\tWhether cornerstone configuration should be used.\n\t * @param {boolean} isProduct\t\tWhether product configuration should be used.\n\n\t * @returns {void}\n\t */\n constructor(config = {}, isCornerstone = false, isProduct = false) {\n super();\n\n const defaultConfig = {\n id: TEXT_SENTENCE_LENGTH_ID,\n priority: 'high',\n docUrl:\n 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#sentence-length',\n ctaType: 'fix',\n fixPosition: 'sentenceLength',\n icon: '',\n recommendedLength: 20,\n slightlyTooMany: 25,\n farTooMany: 30,\n title: 'Text Sentence Length',\n content: {\n improve: '',\n bad:\n 'Sentence too long. Keep sentence length less than 20 words to improve readability and flow.',\n good: 'Sentence length is optimized for readability, less than 20 words.'\n }\n };\n\n this._config = merge(defaultConfig, config);\n this.identifier = TEXT_SENTENCE_LENGTH_ID;\n }\n\n /**\n * Scores the percentage of sentences including more than the recommended number of words.\n *\n * @param {Paper} paper The paper to use for the assessment.\n * @param {Researcher} researcher The researcher used for calling research.\n *\n * @returns {AssessmentResult} The Assessment result.\n */\n getResult({paper, researcher}) {\n const sentences = researcher.getResearch('countSentencesFromText');\n if (researcher.getConfig('sentenceLength')) {\n this._config = this.getLanguageSpecificConfig(researcher);\n }\n\n const percentage = this.calculatePercentage(sentences);\n const result = this.calculateResult(percentage);\n\n const assessmentResult = new AssessmentResult({config: this._config});\n\n assessmentResult.setScore(result.score);\n assessmentResult.setStatus(result.status);\n\n return assessmentResult;\n }\n\n /**\n * Checks whether the paper has text.\n *\n * @param {Paper} paper The paper to use for the assessment.\n *\n * @returns {boolean} True when there is text.\n */\n isApplicable(paper) {\n return this.hasEnoughContentForAssessment(paper);\n }\n\n /**\n * Check if there is language-specific config, and if so, overwrite the current config with it.\n *\n * @param {Researcher} researcher The researcher to use.\n *\n * @returns {Object} The config that should be used.\n */\n getLanguageSpecificConfig(researcher) {\n const currentConfig = this._config;\n const languageSpecificConfig = researcher.getConfig('sentenceLength');\n\n if (languageSpecificConfig.hasOwnProperty('recommendedLength')) {\n currentConfig.recommendedLength = languageSpecificConfig.recommendedLength;\n }\n\n return currentConfig;\n }\n\n /**\n * Calculates the percentage of sentences that are too long.\n *\n * @param {Array} sentences The sentences to calculate the percentage for.\n * @returns {number} The calculates percentage of too long sentences.\n */\n calculatePercentage(sentences) {\n let percentage = 0;\n\n if (sentences.length !== 0) {\n const tooLongTotal = this.countTooLongSentences(sentences);\n\n percentage = formatNumber((tooLongTotal / sentences.length) * 100);\n }\n\n return percentage;\n }\n\n /**\n *\n * @param percentage\n * @returns {{score: number, status: string}}\n */\n calculateResult(percentage) {\n let status = '';\n if (percentage <= this._config.recommendedLength) {\n status = 'good';\n }\n\n if (percentage > this._config.recommendedLength) {\n status = 'bad';\n }\n\n const score = this.getScore(this._config.priority, status);\n\n this._config.content = {\n improve: '',\n bad: `Sentence too long. Keep sentence length less than ${this._config.recommendedLength} words to improve readability and flow.`,\n good: `Sentence length is optimized for readability, less than ${this._config.recommendedLength} words.`\n };\n\n return {\n score,\n status\n };\n }\n\n /**\n * Gets the sentences that are qualified as being too long.\n *\n * @param {array} sentences The sentences to filter through.\n * @returns {array} Array with all the sentences considered to be too long.\n */\n getTooLongSentences(sentences) {\n return getTooLongSentences(sentences, this._config.recommendedLength);\n }\n\n /**\n * Get the total amount of sentences that are qualified as being too long.\n *\n * @param {Array} sentences The sentences to filter through.\n * @returns {Number} The amount of sentences that are considered too long.\n */\n countTooLongSentences(sentences) {\n return this.getTooLongSentences(sentences).length;\n }\n}\n\nexport default SentenceLengthInTextAssessment;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"SentenceLengthInTextAssessment.js","names":["merge","Assessment","getTooLongSentences","formatNumber","AssessmentResult","TextBlockIcon","MAIN_CONTENT_POINTS","TEXT_SENTENCE_LENGTH_ID","SentenceLengthInTextAssessment","constructor","config","isCornerstone","isProduct","defaultConfig","id","priority","docUrl","ctaType","fixPosition","icon","recommendedLength","slightlyTooMany","farTooMany","title","content","improve","bad","good","_config","identifier","getResult","paper","researcher","sentences","getResearch","hasDescription","getConfig","getLanguageSpecificConfig","percentage","calculatePercentage","result","calculateResult","assessmentResult","setScore","score","setStatus","status","isApplicable","currentConfig","languageSpecificConfig","hasOwnProperty","length","tooLongTotal","countTooLongSentences","getScore"],"sources":["../../../../../src/scoring/assessments/readability/SentenceLengthInTextAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport Assessment from '../assessment';\nimport getTooLongSentences from '../../helpers/assessments/checkForTooLongSentences';\nimport formatNumber from '../../../helpers/formatNumber';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport {TextBlockIcon} from '@shopify/polaris-icons';\nimport {MAIN_CONTENT_POINTS, TEXT_SENTENCE_LENGTH_ID} from '@axyseo/const/analysis';\n\n/**\n * Represents the assessment that will calculate the length of sentences in the text.\n */\nclass SentenceLengthInTextAssessment extends Assessment {\n /**\n\t * Sets the identifier and the config.\n\t *\n\t * @param {object} config\t\t\tThe scoring configuration that should be used.\n\t * @param {boolean} isCornerstone\tWhether cornerstone configuration should be used.\n\t * @param {boolean} isProduct\t\tWhether product configuration should be used.\n\n\t * @returns {void}\n\t */\n constructor(config = {}, isCornerstone = false, isProduct = false) {\n super();\n\n const defaultConfig = {\n id: TEXT_SENTENCE_LENGTH_ID,\n priority: 'high',\n docUrl:\n 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#sentence-length',\n ctaType: 'fix',\n fixPosition: 'sentenceLength',\n icon: TextBlockIcon,\n recommendedLength: 20,\n slightlyTooMany: 25,\n farTooMany: 30,\n title: 'Text Sentence Length',\n content: {\n improve: '',\n bad:\n 'Sentence too long. Keep sentence length less than 20 words to improve readability and flow.',\n good: 'Sentence length is optimized for readability, less than 20 words.'\n }\n };\n\n this._config = merge(defaultConfig, config);\n this.identifier = TEXT_SENTENCE_LENGTH_ID;\n }\n\n /**\n * Scores the percentage of sentences including more than the recommended number of words.\n *\n * @param {Paper} paper The paper to use for the assessment.\n * @param {Researcher} researcher The researcher used for calling research.\n *\n * @returns {AssessmentResult} The Assessment result.\n */\n getResult({paper, researcher}) {\n const sentences = researcher.getResearch('countSentencesFromText');\n const hasDescription = paper.hasDescription();\n if (researcher.getConfig('sentenceLength')) {\n this._config = this.getLanguageSpecificConfig(researcher);\n }\n const percentage = this.calculatePercentage(sentences);\n const result = this.calculateResult(percentage, hasDescription);\n\n const assessmentResult = new AssessmentResult({config: this._config});\n\n assessmentResult.setScore(result.score);\n assessmentResult.setStatus(result.status);\n\n return assessmentResult;\n }\n\n /**\n * Checks whether the paper has text.\n *\n * @param {Paper} paper The paper to use for the assessment.\n *\n * @returns {boolean} True when there is text.\n */\n isApplicable(paper) {\n return true;\n }\n\n /**\n * Check if there is language-specific config, and if so, overwrite the current config with it.\n *\n * @param {Researcher} researcher The researcher to use.\n *\n * @returns {Object} The config that should be used.\n */\n getLanguageSpecificConfig(researcher) {\n const currentConfig = this._config;\n const languageSpecificConfig = researcher.getConfig('sentenceLength');\n\n if (languageSpecificConfig.hasOwnProperty('recommendedLength')) {\n currentConfig.recommendedLength = languageSpecificConfig.recommendedLength;\n }\n\n return currentConfig;\n }\n\n /**\n * Calculates the percentage of sentences that are too long.\n *\n * @param {Array} sentences The sentences to calculate the percentage for.\n * @returns {number} The calculates percentage of too long sentences.\n */\n calculatePercentage(sentences) {\n let percentage = 0;\n\n if (sentences.length !== 0) {\n const tooLongTotal = this.countTooLongSentences(sentences);\n percentage = formatNumber((tooLongTotal / sentences.length) * 100);\n }\n\n return percentage;\n }\n\n /**\n *\n * @param percentage\n * @param hasDescription\n * @returns {{score: number, status: string}}\n */\n calculateResult(percentage, hasDescription) {\n let status = 'bad';\n if (percentage <= 0 && hasDescription && percentage <= this._config.recommendedLength) {\n status = 'good';\n }\n const score = this.getScore(MAIN_CONTENT_POINTS, status);\n\n this._config.content = {\n improve: '',\n bad: `Sentence too long. Keep sentence length less than ${this._config.recommendedLength} words to improve readability and flow.`,\n good: `Sentences optimized`\n };\n\n return {\n score,\n status\n };\n }\n\n /**\n * Gets the sentences that are qualified as being too long.\n *\n * @param {array} sentences The sentences to filter through.\n * @returns {array} Array with all the sentences considered to be too long.\n */\n getTooLongSentences(sentences) {\n return getTooLongSentences(sentences, this._config.recommendedLength);\n }\n\n /**\n * Get the total amount of sentences that are qualified as being too long.\n *\n * @param {Array} sentences The sentences to filter through.\n * @returns {Number} The amount of sentences that are considered too long.\n */\n countTooLongSentences(sentences) {\n return this.getTooLongSentences(sentences).length;\n }\n}\n\nexport default SentenceLengthInTextAssessment;\n"],"mappings":"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","ignoreList":[]}
@@ -6,7 +6,7 @@ import Assessment from "../assessment";
6
6
  import removeHtmlBlocks from "../../../languageProcessing/helpers/html/htmlParser";
7
7
  import getWords from "../../../languageProcessing/helpers/word/getWords";
8
8
  import { filterShortcodesFromHTML } from "../../../languageProcessing/helpers";
9
- import { TEXT_TRANSITION_WORDS_ID } from "../../../const/analysis";
9
+ import { MAIN_CONTENT_POINTS, TEXT_TRANSITION_WORDS_ID } from "../../../const/analysis";
10
10
 
11
11
  /**
12
12
  * Represents the assessment that checks whether there are enough transition words in the text.
@@ -87,7 +87,7 @@ export default class TransitionWordsAssessment extends Assessment {
87
87
  if (score < 6 || percentage === 0) {
88
88
  status = 'bad';
89
89
  }
90
- const customScore = this.getScore(this._config.priority, status);
90
+ const customScore = this.getScore(MAIN_CONTENT_POINTS, status);
91
91
  return {
92
92
  score: customScore,
93
93
  status
@@ -1 +1 @@
1
- {"version":3,"file":"TransitionWordsAssessment.js","names":["merge","formatNumber","inRangeStartInclusive","inRange","AssessmentResult","Assessment","removeHtmlBlocks","getWords","filterShortcodesFromHTML","TEXT_TRANSITION_WORDS_ID","TransitionWordsAssessment","constructor","config","defaultConfig","id","fixPosition","ctaType","docUrl","priority","applicableIfTextLongerThan","title","content","good","bad","improve","identifier","_config","calculateTransitionWordPercentage","sentences","transitionWordSentences","totalSentences","calculateScoreFromPercentage","percentage","calculateTransitionWordResult","score","status","customScore","getScore","getResult","paper","researcher","getResearch","transitionWordResult","assessmentResult","setScore","setStatus","isApplicable","customCountLength","getHelper","customApplicabilityConfig","getConfig","transitionWords","text","getText","_attributes","shortcodes","textLength","length","hasResearch"],"sources":["../../../../../src/scoring/assessments/readability/TransitionWordsAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport formatNumber from '../../../helpers/formatNumber';\nimport {inRangeStartInclusive as inRange} from '../../helpers/assessments/inRange';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport Assessment from '../assessment';\nimport removeHtmlBlocks from '@axyseo/languageProcessing/helpers/html/htmlParser';\nimport getWords from '@axyseo/languageProcessing/helpers/word/getWords';\nimport {filterShortcodesFromHTML} from '@axyseo/languageProcessing/helpers';\nimport {TEXT_TRANSITION_WORDS_ID} from '@axyseo/const/analysis';\n\n/**\n * Represents the assessment that checks whether there are enough transition words in the text.\n */\nexport default class TransitionWordsAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {object} config The configuration to use.\n *\n * @returns {void}\n */\n constructor(config = {}) {\n super();\n\n const defaultConfig = {\n id: TEXT_TRANSITION_WORDS_ID,\n fixPosition: 'longestParagraph',\n ctaType: 'fix',\n docUrl:\n 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#use-of-transition-words',\n priority: 'low',\n applicableIfTextLongerThan: 200,\n title: 'Use of transition words',\n content: {\n good: 'Transition words are used effectively.',\n bad:\n 'Lack of transition words. Improve readability and flow by adding words like \"however,\" \"also,\" etc.',\n improve: ''\n }\n };\n\n this.identifier = TEXT_TRANSITION_WORDS_ID;\n this._config = merge(defaultConfig, config);\n }\n\n /**\n * Calculates the actual percentage of transition words in the sentences.\n *\n * @param {object} sentences The object containing the total number of sentences and the number of sentences containing\n * a transition word.\n *\n * @returns {number} The percentage of sentences containing a transition word.\n */\n calculateTransitionWordPercentage(sentences) {\n if (sentences.transitionWordSentences === 0 || sentences.totalSentences === 0) {\n return 0;\n }\n\n return formatNumber((sentences.transitionWordSentences / sentences.totalSentences) * 100);\n }\n\n /**\n * Calculates the score for the assessment based on the percentage of sentences containing transition words.\n *\n * @param {number} percentage The percentage of sentences containing transition words.\n *\n * @returns {number} The score.\n */\n calculateScoreFromPercentage(percentage) {\n if (percentage < 10) {\n // Red indicator.\n return 3;\n }\n\n if (inRange(percentage, 10, 20)) {\n // Orange indicator.\n return 6;\n }\n\n // Green indicator.\n return 9;\n }\n\n /**\n *\n * @param transitionWordSentences\n * @returns {{score: number, status: string}}\n */\n calculateTransitionWordResult(transitionWordSentences) {\n const percentage = this.calculateTransitionWordPercentage(transitionWordSentences);\n const score = this.calculateScoreFromPercentage(percentage);\n\n let status = 'good';\n if (score < 6 || percentage === 0) {\n status = 'bad';\n }\n\n const customScore = this.getScore(this._config.priority, status);\n\n return {\n score: customScore,\n status\n };\n }\n\n /**\n *\n * @param paper\n * @param researcher\n * @returns {AssessmentResult}\n */\n getResult({paper, researcher}) {\n const transitionWordSentences = researcher.getResearch('findTransitionWords');\n const transitionWordResult = this.calculateTransitionWordResult(transitionWordSentences);\n const assessmentResult = new AssessmentResult({config: this._config});\n\n assessmentResult.setScore(transitionWordResult.score);\n assessmentResult.setStatus(transitionWordResult.status);\n\n return assessmentResult;\n }\n\n /**\n * Checks if the transition words assessment is applicable to the paper. Language-specific length requirements and methods of counting text length\n * may apply (e.g. for Japanese, the text should be counted in characters instead of words, which also makes the minimum required length higher).\n *\n * @param {Paper} paper The paper to check.\n * @param {Researcher} researcher The researcher object.\n *\n * @returns {boolean} Returns true if the language is available, the paper is not empty and the text is longer than the minimum required length.\n */\n isApplicable(paper, researcher) {\n const customCountLength = researcher.getHelper('customCountLength');\n const customApplicabilityConfig = researcher.getConfig('assessmentApplicability')\n .transitionWords;\n if (customApplicabilityConfig) {\n this._config.applicableIfTextLongerThan = customApplicabilityConfig;\n }\n let text = paper.getText();\n text = removeHtmlBlocks(text);\n text = filterShortcodesFromHTML(text, paper._attributes && paper._attributes.shortcodes);\n const textLength = customCountLength ? customCountLength(text) : getWords(text).length;\n\n // Do not use hasEnoughContent in this assessment as it is mostly redundant with `textLength >= this._config.applicableIfTextLongerThan`\n return (\n textLength >= this._config.applicableIfTextLongerThan &&\n researcher.hasResearch('findTransitionWords')\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"TransitionWordsAssessment.js","names":["merge","formatNumber","inRangeStartInclusive","inRange","AssessmentResult","Assessment","removeHtmlBlocks","getWords","filterShortcodesFromHTML","MAIN_CONTENT_POINTS","TEXT_TRANSITION_WORDS_ID","TransitionWordsAssessment","constructor","config","defaultConfig","id","fixPosition","ctaType","docUrl","priority","applicableIfTextLongerThan","title","content","good","bad","improve","identifier","_config","calculateTransitionWordPercentage","sentences","transitionWordSentences","totalSentences","calculateScoreFromPercentage","percentage","calculateTransitionWordResult","score","status","customScore","getScore","getResult","paper","researcher","getResearch","transitionWordResult","assessmentResult","setScore","setStatus","isApplicable","customCountLength","getHelper","customApplicabilityConfig","getConfig","transitionWords","text","getText","_attributes","shortcodes","textLength","length","hasResearch"],"sources":["../../../../../src/scoring/assessments/readability/TransitionWordsAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport formatNumber from '../../../helpers/formatNumber';\nimport {inRangeStartInclusive as inRange} from '../../helpers/assessments/inRange';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport Assessment from '../assessment';\nimport removeHtmlBlocks from '@axyseo/languageProcessing/helpers/html/htmlParser';\nimport getWords from '@axyseo/languageProcessing/helpers/word/getWords';\nimport {filterShortcodesFromHTML} from '@axyseo/languageProcessing/helpers';\nimport {MAIN_CONTENT_POINTS, TEXT_TRANSITION_WORDS_ID} from '@axyseo/const/analysis';\n\n/**\n * Represents the assessment that checks whether there are enough transition words in the text.\n */\nexport default class TransitionWordsAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {object} config The configuration to use.\n *\n * @returns {void}\n */\n constructor(config = {}) {\n super();\n\n const defaultConfig = {\n id: TEXT_TRANSITION_WORDS_ID,\n fixPosition: 'longestParagraph',\n ctaType: 'fix',\n docUrl:\n 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#use-of-transition-words',\n priority: 'low',\n applicableIfTextLongerThan: 200,\n title: 'Use of transition words',\n content: {\n good: 'Transition words are used effectively.',\n bad:\n 'Lack of transition words. Improve readability and flow by adding words like \"however,\" \"also,\" etc.',\n improve: ''\n }\n };\n\n this.identifier = TEXT_TRANSITION_WORDS_ID;\n this._config = merge(defaultConfig, config);\n }\n\n /**\n * Calculates the actual percentage of transition words in the sentences.\n *\n * @param {object} sentences The object containing the total number of sentences and the number of sentences containing\n * a transition word.\n *\n * @returns {number} The percentage of sentences containing a transition word.\n */\n calculateTransitionWordPercentage(sentences) {\n if (sentences.transitionWordSentences === 0 || sentences.totalSentences === 0) {\n return 0;\n }\n\n return formatNumber((sentences.transitionWordSentences / sentences.totalSentences) * 100);\n }\n\n /**\n * Calculates the score for the assessment based on the percentage of sentences containing transition words.\n *\n * @param {number} percentage The percentage of sentences containing transition words.\n *\n * @returns {number} The score.\n */\n calculateScoreFromPercentage(percentage) {\n if (percentage < 10) {\n // Red indicator.\n return 3;\n }\n\n if (inRange(percentage, 10, 20)) {\n // Orange indicator.\n return 6;\n }\n\n // Green indicator.\n return 9;\n }\n\n /**\n *\n * @param transitionWordSentences\n * @returns {{score: number, status: string}}\n */\n calculateTransitionWordResult(transitionWordSentences) {\n const percentage = this.calculateTransitionWordPercentage(transitionWordSentences);\n const score = this.calculateScoreFromPercentage(percentage);\n\n let status = 'good';\n if (score < 6 || percentage === 0) {\n status = 'bad';\n }\n\n const customScore = this.getScore(MAIN_CONTENT_POINTS, status);\n\n return {\n score: customScore,\n status\n };\n }\n\n /**\n *\n * @param paper\n * @param researcher\n * @returns {AssessmentResult}\n */\n getResult({paper, researcher}) {\n const transitionWordSentences = researcher.getResearch('findTransitionWords');\n const transitionWordResult = this.calculateTransitionWordResult(transitionWordSentences);\n const assessmentResult = new AssessmentResult({config: this._config});\n\n assessmentResult.setScore(transitionWordResult.score);\n assessmentResult.setStatus(transitionWordResult.status);\n\n return assessmentResult;\n }\n\n /**\n * Checks if the transition words assessment is applicable to the paper. Language-specific length requirements and methods of counting text length\n * may apply (e.g. for Japanese, the text should be counted in characters instead of words, which also makes the minimum required length higher).\n *\n * @param {Paper} paper The paper to check.\n * @param {Researcher} researcher The researcher object.\n *\n * @returns {boolean} Returns true if the language is available, the paper is not empty and the text is longer than the minimum required length.\n */\n isApplicable(paper, researcher) {\n const customCountLength = researcher.getHelper('customCountLength');\n const customApplicabilityConfig = researcher.getConfig('assessmentApplicability')\n .transitionWords;\n if (customApplicabilityConfig) {\n this._config.applicableIfTextLongerThan = customApplicabilityConfig;\n }\n let text = paper.getText();\n text = removeHtmlBlocks(text);\n text = filterShortcodesFromHTML(text, paper._attributes && paper._attributes.shortcodes);\n const textLength = customCountLength ? customCountLength(text) : getWords(text).length;\n\n // Do not use hasEnoughContent in this assessment as it is mostly redundant with `textLength >= this._config.applicableIfTextLongerThan`\n return (\n textLength >= this._config.applicableIfTextLongerThan &&\n researcher.hasResearch('findTransitionWords')\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  import { merge } from 'lodash';
2
2
  import Assessment from "../assessment";
3
3
  import AssessmentResult from "../../../values/AssessmentResult";
4
- import { FAQs_ASSESSMENT_ID } from "../../../const/analysis";
4
+ import { FAQs_ASSESSMENT_ID, FAQS_POINTS } from "../../../const/analysis";
5
5
 
6
6
  /**
7
7
  * Represents an assessment that checks FAQs content and structure for SGE optimization.
@@ -22,14 +22,12 @@ export default class FAQsAssessment extends Assessment {
22
22
  docUrl: 'https://blog.google/products/search/generative-ai-search/',
23
23
  priority: 'high',
24
24
  fixPosition: 'faqs',
25
- factor: 2,
26
25
  title: 'FAQs Optimization',
27
26
  content: {
28
27
  good: 'FAQs are well-structured and optimized for Google SGE.',
29
- improve: 'FAQs could be improved to better match Google SGE requirements.',
28
+ improve: '',
30
29
  bad: 'FAQs need significant improvement to meet Google SGE standards.',
31
30
  details: {
32
- hasSchema: 'Missing FAQ schema markup',
33
31
  hasProperStructure: 'Empty questions or answers',
34
32
  hasMinimumFAQs: 'Less than 3 FAQs'
35
33
  }
@@ -67,7 +65,7 @@ export default class FAQsAssessment extends Assessment {
67
65
  * @returns {{score: number, status: string, data: {hasSchema: ((function(): *)|boolean), hasProperStructure: boolean, hasMinimumFAQs: boolean}}|{score: number, status: string, data: {hasFAQs: boolean}}}
68
66
  */
69
67
  calculateResult(paper) {
70
- const faqs = paper.getFAQs();
68
+ const faqs = paper.getFAQs()?.questions || [];
71
69
  let status = 'bad';
72
70
  let score = 0;
73
71
  if (!faqs || faqs.length === 0) {
@@ -79,58 +77,16 @@ export default class FAQsAssessment extends Assessment {
79
77
  }
80
78
  };
81
79
  }
82
-
83
- // Check FAQ structure and content
84
- const hasSchema = paper.hasFAQsSchema();
85
- const hasProperStructure = this.checkFAQStructure(faqs);
80
+ const isEnableFaqs = paper.getFAQs()?.status;
86
81
  const hasMinimumFAQs = this.checkMinimumFAQs(faqs);
87
-
88
- // Calculate score based on criteria
89
- const criteriaMet = [hasSchema, hasProperStructure, hasMinimumFAQs].filter(Boolean).length;
90
- if (criteriaMet === 3) {
91
- status = 'good';
92
- } else if (criteriaMet === 2) {
93
- status = 'improve';
94
- } else {
95
- status = 'bad';
96
- }
97
- score = this.getScore(this._config.priority, status, this._config.factor);
82
+ status = hasMinimumFAQs && isEnableFaqs ? 'good' : 'bad';
83
+ score = this.getScore(FAQS_POINTS, status);
98
84
  return {
99
85
  score,
100
- status,
101
- data: {
102
- hasSchema,
103
- hasProperStructure,
104
- hasMinimumFAQs
105
- }
86
+ status
106
87
  };
107
88
  }
108
89
 
109
- /**
110
- * Checks if FAQs have proper structure
111
- * @param {Array} faqs
112
- * @returns {boolean}
113
- */
114
- checkFAQStructure(faqs) {
115
- return faqs.every(faq => {
116
- return faq.question && faq.answer && typeof faq.question === 'string' && typeof faq.answer === 'string' && faq.question.length > 0 && faq.answer.length > 0;
117
- });
118
- }
119
-
120
- /**
121
- * Checks if FAQs are relevant to the main content
122
- * @param {Array} faqs
123
- * @param {Array} keywords
124
- * @returns {boolean}
125
- */
126
- checkRelevance(faqs, keywords) {
127
- if (!keywords || keywords.length === 0) return true;
128
- return faqs.some(faq => {
129
- const question = faq.question.toLowerCase();
130
- return keywords.some(keyword => question.includes(keyword.toLowerCase()));
131
- });
132
- }
133
-
134
90
  /**
135
91
  * Checks if there are at least 3 FAQs
136
92
  * @param {Array} faqs
@@ -148,8 +104,7 @@ export default class FAQsAssessment extends Assessment {
148
104
  * @returns {boolean} True when there is text.
149
105
  */
150
106
  isApplicable(paper) {
151
- const data = paper.getData();
152
- return 'faqs' in data;
107
+ return true;
153
108
  }
154
109
  }
155
110
  //# sourceMappingURL=FAQsAssessment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FAQsAssessment.js","names":["merge","Assessment","AssessmentResult","FAQs_ASSESSMENT_ID","FAQsAssessment","constructor","config","defaultConfig","id","ctaType","docUrl","priority","fixPosition","factor","title","content","good","improve","bad","details","hasSchema","hasProperStructure","hasMinimumFAQs","identifier","_config","getResult","paper","researcher","calculatedResult","calculateResult","assessmentResult","setScore","score","setStatus","status","setData","data","faqs","getFAQs","length","hasFAQs","hasFAQsSchema","checkFAQStructure","checkMinimumFAQs","criteriaMet","filter","Boolean","getScore","every","faq","question","answer","checkRelevance","keywords","some","toLowerCase","keyword","includes","isApplicable","getData"],"sources":["../../../../../src/scoring/assessments/seo/FAQsAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport Assessment from '../assessment';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport {FAQs_ASSESSMENT_ID} from '@axyseo/const/analysis';\n\n/**\n * Represents an assessment that checks FAQs content and structure for SGE optimization.\n */\nexport default class FAQsAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {Object} [config] The configuration to use.\n *\n * @returns {void}\n */\n constructor(config = {}) {\n super();\n\n const defaultConfig = {\n id: FAQs_ASSESSMENT_ID,\n ctaType: 'fix',\n docUrl: 'https://blog.google/products/search/generative-ai-search/',\n priority: 'high',\n fixPosition: 'faqs',\n factor: 2,\n title: 'FAQs Optimization',\n content: {\n good: 'FAQs are well-structured and optimized for Google SGE.',\n improve: 'FAQs could be improved to better match Google SGE requirements.',\n bad: 'FAQs need significant improvement to meet Google SGE standards.',\n details: {\n hasSchema: 'Missing FAQ schema markup',\n hasProperStructure: 'Empty questions or answers',\n hasMinimumFAQs: 'Less than 3 FAQs'\n }\n }\n };\n\n this.identifier = FAQs_ASSESSMENT_ID;\n this._config = merge(defaultConfig, config);\n }\n\n /**\n * Executes the Assessment and returns a result.\n *\n * @param {Paper} paper The Paper object to assess.\n * @param {Researcher} researcher The Researcher object containing all available researches.\n *\n * @returns {AssessmentResult} The result of the assessment, containing both a score and a descriptive text.\n */\n getResult({paper, researcher}) {\n const calculatedResult = this.calculateResult(paper);\n\n const assessmentResult = new AssessmentResult({config: this._config});\n assessmentResult.setScore(calculatedResult.score);\n assessmentResult.setStatus(calculatedResult.status);\n assessmentResult.setData(calculatedResult.data);\n\n return assessmentResult;\n }\n\n /**\n *\n * @param paper\n * @returns {{score: number, status: string, data: {hasSchema: ((function(): *)|boolean), hasProperStructure: boolean, hasMinimumFAQs: boolean}}|{score: number, status: string, data: {hasFAQs: boolean}}}\n */\n calculateResult(paper) {\n const faqs = paper.getFAQs();\n let status = 'bad';\n let score = 0;\n\n if (!faqs || faqs.length === 0) {\n return {score: 0, status: 'bad', data: {hasFAQs: false}};\n }\n\n // Check FAQ structure and content\n const hasSchema = paper.hasFAQsSchema();\n const hasProperStructure = this.checkFAQStructure(faqs);\n const hasMinimumFAQs = this.checkMinimumFAQs(faqs);\n\n // Calculate score based on criteria\n const criteriaMet = [hasSchema, hasProperStructure, hasMinimumFAQs].filter(Boolean).length;\n\n if (criteriaMet === 3) {\n status = 'good';\n } else if (criteriaMet === 2) {\n status = 'improve';\n } else {\n status = 'bad';\n }\n\n score = this.getScore(this._config.priority, status, this._config.factor);\n\n return {\n score,\n status,\n data: {\n hasSchema,\n hasProperStructure,\n hasMinimumFAQs\n }\n };\n }\n\n /**\n * Checks if FAQs have proper structure\n * @param {Array} faqs\n * @returns {boolean}\n */\n checkFAQStructure(faqs) {\n return faqs.every(faq => {\n return (\n faq.question &&\n faq.answer &&\n typeof faq.question === 'string' &&\n typeof faq.answer === 'string' &&\n faq.question.length > 0 &&\n faq.answer.length > 0\n );\n });\n }\n\n /**\n * Checks if FAQs are relevant to the main content\n * @param {Array} faqs\n * @param {Array} keywords\n * @returns {boolean}\n */\n checkRelevance(faqs, keywords) {\n if (!keywords || keywords.length === 0) return true;\n\n return faqs.some(faq => {\n const question = faq.question.toLowerCase();\n return keywords.some(keyword => question.includes(keyword.toLowerCase()));\n });\n }\n\n /**\n * Checks if there are at least 3 FAQs\n * @param {Array} faqs\n * @returns {boolean}\n */\n checkMinimumFAQs(faqs) {\n return faqs.length >= 3;\n }\n\n /**\n * Checks whether the paper has text.\n *\n * @param {Paper} paper The paper to use for the assessment.\n *\n * @returns {boolean} True when there is text.\n */\n isApplicable(paper) {\n const data = paper.getData();\n return 'faqs' in data;\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"FAQsAssessment.js","names":["merge","Assessment","AssessmentResult","FAQs_ASSESSMENT_ID","FAQS_POINTS","FAQsAssessment","constructor","config","defaultConfig","id","ctaType","docUrl","priority","fixPosition","title","content","good","improve","bad","details","hasProperStructure","hasMinimumFAQs","identifier","_config","getResult","paper","researcher","calculatedResult","calculateResult","assessmentResult","setScore","score","setStatus","status","setData","data","faqs","getFAQs","questions","length","hasFAQs","isEnableFaqs","checkMinimumFAQs","getScore","isApplicable"],"sources":["../../../../../src/scoring/assessments/seo/FAQsAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport Assessment from '../assessment';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport {FAQs_ASSESSMENT_ID, FAQS_POINTS} from '@axyseo/const/analysis';\n\n/**\n * Represents an assessment that checks FAQs content and structure for SGE optimization.\n */\nexport default class FAQsAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {Object} [config] The configuration to use.\n *\n * @returns {void}\n */\n constructor(config = {}) {\n super();\n\n const defaultConfig = {\n id: FAQs_ASSESSMENT_ID,\n ctaType: 'fix',\n docUrl: 'https://blog.google/products/search/generative-ai-search/',\n priority: 'high',\n fixPosition: 'faqs',\n title: 'FAQs Optimization',\n content: {\n good: 'FAQs are well-structured and optimized for Google SGE.',\n improve: '',\n bad: 'FAQs need significant improvement to meet Google SGE standards.',\n details: {\n hasProperStructure: 'Empty questions or answers',\n hasMinimumFAQs: 'Less than 3 FAQs'\n }\n }\n };\n\n this.identifier = FAQs_ASSESSMENT_ID;\n this._config = merge(defaultConfig, config);\n }\n\n /**\n * Executes the Assessment and returns a result.\n *\n * @param {Paper} paper The Paper object to assess.\n * @param {Researcher} researcher The Researcher object containing all available researches.\n *\n * @returns {AssessmentResult} The result of the assessment, containing both a score and a descriptive text.\n */\n getResult({paper, researcher}) {\n const calculatedResult = this.calculateResult(paper);\n\n const assessmentResult = new AssessmentResult({config: this._config});\n assessmentResult.setScore(calculatedResult.score);\n assessmentResult.setStatus(calculatedResult.status);\n assessmentResult.setData(calculatedResult.data);\n\n return assessmentResult;\n }\n\n /**\n *\n * @param paper\n * @returns {{score: number, status: string, data: {hasSchema: ((function(): *)|boolean), hasProperStructure: boolean, hasMinimumFAQs: boolean}}|{score: number, status: string, data: {hasFAQs: boolean}}}\n */\n calculateResult(paper) {\n const faqs = paper.getFAQs()?.questions || [];\n let status = 'bad';\n let score = 0;\n\n if (!faqs || faqs.length === 0) {\n return {score: 0, status: 'bad', data: {hasFAQs: false}};\n }\n const isEnableFaqs = paper.getFAQs()?.status;\n const hasMinimumFAQs = this.checkMinimumFAQs(faqs);\n status = hasMinimumFAQs && isEnableFaqs ? 'good' : 'bad';\n score = this.getScore(FAQS_POINTS, status);\n\n return {\n score,\n status\n };\n }\n\n\n\n /**\n * Checks if there are at least 3 FAQs\n * @param {Array} faqs\n * @returns {boolean}\n */\n checkMinimumFAQs(faqs) {\n return faqs.length >= 3;\n }\n\n /**\n * Checks whether the paper has text.\n *\n * @param {Paper} paper The paper to use for the assessment.\n *\n * @returns {boolean} True when there is text.\n */\n isApplicable(paper) {\n return true;\n }\n}\n"],"mappings":"AAAA,SAAQA,KAAK,QAAO,QAAQ;AAC5B,OAAOC,UAAU;AACjB,OAAOC,gBAAgB;AACvB,SAAQC,kBAAkB,EAAEC,WAAW;;AAEvC;AACA;AACA;AACA,eAAe,MAAMC,cAAc,SAASJ,UAAU,CAAC;EACrD;AACF;AACA;AACA;AACA;AACA;AACA;EACEK,WAAWA,CAACC,MAAM,GAAG,CAAC,CAAC,EAAE;IACvB,KAAK,CAAC,CAAC;IAEP,MAAMC,aAAa,GAAG;MACpBC,EAAE,EAAEN,kBAAkB;MACtBO,OAAO,EAAE,KAAK;MACdC,MAAM,EAAE,2DAA2D;MACnEC,QAAQ,EAAE,MAAM;MAChBC,WAAW,EAAE,MAAM;MACnBC,KAAK,EAAE,mBAAmB;MAC1BC,OAAO,EAAE;QACPC,IAAI,EAAE,wDAAwD;QAC9DC,OAAO,EAAE,EAAE;QACXC,GAAG,EAAE,iEAAiE;QACtEC,OAAO,EAAE;UACPC,kBAAkB,EAAE,4BAA4B;UAChDC,cAAc,EAAE;QAClB;MACF;IACF,CAAC;IAED,IAAI,CAACC,UAAU,GAAGnB,kBAAkB;IACpC,IAAI,CAACoB,OAAO,GAAGvB,KAAK,CAACQ,aAAa,EAAED,MAAM,CAAC;EAC7C;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEiB,SAASA,CAAC;IAACC,KAAK;IAAEC;EAAU,CAAC,EAAE;IAC7B,MAAMC,gBAAgB,GAAG,IAAI,CAACC,eAAe,CAACH,KAAK,CAAC;IAEpD,MAAMI,gBAAgB,GAAG,IAAI3B,gBAAgB,CAAC;MAACK,MAAM,EAAE,IAAI,CAACgB;IAAO,CAAC,CAAC;IACrEM,gBAAgB,CAACC,QAAQ,CAACH,gBAAgB,CAACI,KAAK,CAAC;IACjDF,gBAAgB,CAACG,SAAS,CAACL,gBAAgB,CAACM,MAAM,CAAC;IACnDJ,gBAAgB,CAACK,OAAO,CAACP,gBAAgB,CAACQ,IAAI,CAAC;IAE/C,OAAON,gBAAgB;EACzB;;EAEA;AACF;AACA;AACA;AACA;EACED,eAAeA,CAACH,KAAK,EAAE;IACrB,MAAMW,IAAI,GAAGX,KAAK,CAACY,OAAO,CAAC,CAAC,EAAEC,SAAS,IAAI,EAAE;IAC7C,IAAIL,MAAM,GAAG,KAAK;IAClB,IAAIF,KAAK,GAAG,CAAC;IAEb,IAAI,CAACK,IAAI,IAAIA,IAAI,CAACG,MAAM,KAAK,CAAC,EAAE;MAC9B,OAAO;QAACR,KAAK,EAAE,CAAC;QAAEE,MAAM,EAAE,KAAK;QAAEE,IAAI,EAAE;UAACK,OAAO,EAAE;QAAK;MAAC,CAAC;IAC1D;IACA,MAAMC,YAAY,GAAGhB,KAAK,CAACY,OAAO,CAAC,CAAC,EAAEJ,MAAM;IAC5C,MAAMZ,cAAc,GAAG,IAAI,CAACqB,gBAAgB,CAACN,IAAI,CAAC;IAClDH,MAAM,GAAGZ,cAAc,IAAIoB,YAAY,GAAG,MAAM,GAAG,KAAK;IACxDV,KAAK,GAAG,IAAI,CAACY,QAAQ,CAACvC,WAAW,EAAE6B,MAAM,CAAC;IAE1C,OAAO;MACLF,KAAK;MACLE;IACF,CAAC;EACH;;EAIA;AACF;AACA;AACA;AACA;EACES,gBAAgBA,CAACN,IAAI,EAAE;IACrB,OAAOA,IAAI,CAACG,MAAM,IAAI,CAAC;EACzB;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEK,YAAYA,CAACnB,KAAK,EAAE;IAClB,OAAO,IAAI;EACb;AACF","ignoreList":[]}
@@ -0,0 +1,76 @@
1
+ import { merge } from 'lodash';
2
+ import Assessment from "../assessment";
3
+ import AssessmentResult from "../../../values/AssessmentResult";
4
+ import { FAQS_POINTS, FAQs_STRUCTURE_DATA_ID } from "../../../const/analysis";
5
+
6
+ /**
7
+ * Represents an assessment that checks FAQs content and structure for SGE optimization.
8
+ */
9
+ export default class FAQsStructureDataAssessment extends Assessment {
10
+ /**
11
+ * Sets the identifier and the config.
12
+ *
13
+ * @param {Object} [config] The configuration to use.
14
+ *
15
+ * @returns {void}
16
+ */
17
+ constructor(config = {}) {
18
+ super();
19
+ const defaultConfig = {
20
+ id: FAQs_STRUCTURE_DATA_ID,
21
+ ctaType: 'fix',
22
+ docUrl: 'https://blog.google/products/search/generative-ai-search/',
23
+ priority: 'high',
24
+ fixPosition: 'faqs',
25
+ title: 'FAQs structured data',
26
+ content: {
27
+ good: 'FAQ structured data added',
28
+ improve: '',
29
+ bad: 'Add FAQs structured data for Google rich results eligibility.'
30
+ }
31
+ };
32
+ this.identifier = FAQs_STRUCTURE_DATA_ID;
33
+ this._config = merge(defaultConfig, config);
34
+ }
35
+
36
+ /**
37
+ * Executes the Assessment and returns a result.
38
+ *
39
+ * @param {Paper} paper The Paper object to assess.
40
+ * @param {Researcher} researcher The Researcher object containing all available researches.
41
+ *
42
+ * @returns {AssessmentResult} The result of the assessment, containing both a score and a descriptive text.
43
+ */
44
+ getResult({
45
+ paper,
46
+ researcher
47
+ }) {
48
+ const calculatedResult = this.calculateResult(paper);
49
+ const assessmentResult = new AssessmentResult({
50
+ config: this._config
51
+ });
52
+ assessmentResult.setScore(calculatedResult.score);
53
+ assessmentResult.setStatus(calculatedResult.status);
54
+ return assessmentResult;
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @param paper
60
+ * @returns {{score: number, status: string, data: {hasSchema: ((function(): *)|boolean), hasProperStructure: boolean, hasMinimumFAQs: boolean}}|{score: number, status: string, data: {hasFAQs: boolean}}}
61
+ */
62
+ calculateResult(paper) {
63
+ // Check FAQ structure and content
64
+ const hasSchema = paper.hasFAQsSchema();
65
+ const status = hasSchema ? 'good' : 'bad';
66
+ const score = this.getScore(FAQS_POINTS, status);
67
+ return {
68
+ score,
69
+ status
70
+ };
71
+ }
72
+ isApplicable(paper) {
73
+ return true;
74
+ }
75
+ }
76
+ //# sourceMappingURL=FAQsStructureDataAssessment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FAQsStructureDataAssessment.js","names":["merge","Assessment","AssessmentResult","FAQS_POINTS","FAQs_STRUCTURE_DATA_ID","FAQsStructureDataAssessment","constructor","config","defaultConfig","id","ctaType","docUrl","priority","fixPosition","title","content","good","improve","bad","identifier","_config","getResult","paper","researcher","calculatedResult","calculateResult","assessmentResult","setScore","score","setStatus","status","hasSchema","hasFAQsSchema","getScore","isApplicable"],"sources":["../../../../../src/scoring/assessments/seo/FAQsStructureDataAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport Assessment from '../assessment';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport {FAQS_POINTS, FAQs_STRUCTURE_DATA_ID} from '@axyseo/const/analysis';\n\n/**\n * Represents an assessment that checks FAQs content and structure for SGE optimization.\n */\nexport default class FAQsStructureDataAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {Object} [config] The configuration to use.\n *\n * @returns {void}\n */\n constructor(config = {}) {\n super();\n\n const defaultConfig = {\n id: FAQs_STRUCTURE_DATA_ID,\n ctaType: 'fix',\n docUrl: 'https://blog.google/products/search/generative-ai-search/',\n priority: 'high',\n fixPosition: 'faqs',\n title: 'FAQs structured data',\n content: {\n good: 'FAQ structured data added',\n improve: '',\n bad: 'Add FAQs structured data for Google rich results eligibility.',\n }\n };\n\n this.identifier = FAQs_STRUCTURE_DATA_ID;\n this._config = merge(defaultConfig, config);\n }\n\n /**\n * Executes the Assessment and returns a result.\n *\n * @param {Paper} paper The Paper object to assess.\n * @param {Researcher} researcher The Researcher object containing all available researches.\n *\n * @returns {AssessmentResult} The result of the assessment, containing both a score and a descriptive text.\n */\n getResult({paper, researcher}) {\n const calculatedResult = this.calculateResult(paper);\n const assessmentResult = new AssessmentResult({config: this._config});\n assessmentResult.setScore(calculatedResult.score);\n assessmentResult.setStatus(calculatedResult.status);\n return assessmentResult;\n }\n\n /**\n *\n * @param paper\n * @returns {{score: number, status: string, data: {hasSchema: ((function(): *)|boolean), hasProperStructure: boolean, hasMinimumFAQs: boolean}}|{score: number, status: string, data: {hasFAQs: boolean}}}\n */\n calculateResult(paper) {\n // Check FAQ structure and content\n const hasSchema = paper.hasFAQsSchema();\n const status = hasSchema ? 'good' : 'bad';\n const score = this.getScore(FAQS_POINTS, status);\n return {\n score,\n status\n };\n }\n\n\n\n\n isApplicable(paper) {\n return true;\n }\n}\n"],"mappings":"AAAA,SAAQA,KAAK,QAAO,QAAQ;AAC5B,OAAOC,UAAU;AACjB,OAAOC,gBAAgB;AACvB,SAAQC,WAAW,EAAEC,sBAAsB;;AAE3C;AACA;AACA;AACA,eAAe,MAAMC,2BAA2B,SAASJ,UAAU,CAAC;EAClE;AACF;AACA;AACA;AACA;AACA;AACA;EACEK,WAAWA,CAACC,MAAM,GAAG,CAAC,CAAC,EAAE;IACvB,KAAK,CAAC,CAAC;IAEP,MAAMC,aAAa,GAAG;MACpBC,EAAE,EAAEL,sBAAsB;MAC1BM,OAAO,EAAE,KAAK;MACdC,MAAM,EAAE,2DAA2D;MACnEC,QAAQ,EAAE,MAAM;MAChBC,WAAW,EAAE,MAAM;MACnBC,KAAK,EAAE,sBAAsB;MAC7BC,OAAO,EAAE;QACPC,IAAI,EAAE,2BAA2B;QACjCC,OAAO,EAAE,EAAE;QACXC,GAAG,EAAE;MACP;IACF,CAAC;IAED,IAAI,CAACC,UAAU,GAAGf,sBAAsB;IACxC,IAAI,CAACgB,OAAO,GAAGpB,KAAK,CAACQ,aAAa,EAAED,MAAM,CAAC;EAC7C;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEc,SAASA,CAAC;IAACC,KAAK;IAAEC;EAAU,CAAC,EAAE;IAC7B,MAAMC,gBAAgB,GAAG,IAAI,CAACC,eAAe,CAACH,KAAK,CAAC;IACpD,MAAMI,gBAAgB,GAAG,IAAIxB,gBAAgB,CAAC;MAACK,MAAM,EAAE,IAAI,CAACa;IAAO,CAAC,CAAC;IACrEM,gBAAgB,CAACC,QAAQ,CAACH,gBAAgB,CAACI,KAAK,CAAC;IACjDF,gBAAgB,CAACG,SAAS,CAACL,gBAAgB,CAACM,MAAM,CAAC;IACnD,OAAOJ,gBAAgB;EACzB;;EAEA;AACF;AACA;AACA;AACA;EACED,eAAeA,CAACH,KAAK,EAAE;IACrB;IACA,MAAMS,SAAS,GAAGT,KAAK,CAACU,aAAa,CAAC,CAAC;IACvC,MAAMF,MAAM,GAAGC,SAAS,GAAG,MAAM,GAAG,KAAK;IAC1C,MAAMH,KAAK,GAAG,IAAI,CAACK,QAAQ,CAAC9B,WAAW,EAAE2B,MAAM,CAAC;IAC/C,OAAO;MACLF,KAAK;MACLE;IACF,CAAC;EACH;EAKAI,YAAYA,CAACZ,KAAK,EAAE;IAClB,OAAO,IAAI;EACb;AACF","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  import { merge } from 'lodash';
2
2
  import Assessment from "../assessment";
3
3
  import AssessmentResult from "../../../values/AssessmentResult";
4
- import { MEDIA_ID } from "../../../const/analysis";
4
+ import { FAQS_POINTS, MEDIA_ID } from "../../../const/analysis";
5
5
 
6
6
  /**
7
7
  * Represents the assessment that checks if the text has any images present, including videos in product pages.
@@ -64,7 +64,7 @@ export default class TextImagesAssessment extends Assessment {
64
64
  * @returns {boolean} True when there is text.
65
65
  */
66
66
  isApplicable(paper) {
67
- return paper.hasText();
67
+ return true;
68
68
  }
69
69
 
70
70
  /**
@@ -81,7 +81,7 @@ export default class TextImagesAssessment extends Assessment {
81
81
  } else {
82
82
  status = 'good';
83
83
  }
84
- const score = this.getScore(this._config.priority, status);
84
+ const score = this.getScore(FAQS_POINTS, status);
85
85
  return {
86
86
  score,
87
87
  status
@@ -1 +1 @@
1
- {"version":3,"file":"ImageCountAssessment.js","names":["merge","Assessment","AssessmentResult","MEDIA_ID","TextImagesAssessment","constructor","config","countVideos","defaultConfig","id","docUrl","priority","fixPosition","title","content","good","improve","bad","identifier","_config","_countVideos","getResult","paper","researcher","imageCount","getResearch","videoCount","assessmentResult","calculatedResult","calculateResult","setScore","score","setStatus","status","isApplicable","hasText","mediaCount","getScore"],"sources":["../../../../../src/scoring/assessments/seo/ImageCountAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport Assessment from '../assessment';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport {MEDIA_ID} from '@axyseo/const/analysis';\n\n/**\n * Represents the assessment that checks if the text has any images present, including videos in product pages.\n */\nexport default class TextImagesAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {object} config The configuration to use.\n * @param {boolean} countVideos Whether videos are also included in the assessment or not.\n *\n * @returns {void}\n */\n constructor(config = {}, countVideos = true) {\n super();\n\n const defaultConfig = {\n id: MEDIA_ID,\n docUrl:\n 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#images-and-videos',\n priority: 'high',\n fixPosition: 'description',\n title: 'Media',\n content: {\n good: 'Media are used effectively.',\n improve: '',\n bad: 'No media found. Add visual content to enhance engagement.'\n }\n };\n\n this.identifier = MEDIA_ID;\n this._config = merge(defaultConfig, config);\n this._countVideos = countVideos;\n }\n\n /**\n * Execute the Assessment and return a result.\n *\n * @param {Paper} paper The Paper object to assess.\n * @param {Researcher} researcher The Researcher object containing all available researches.\n * @returns {AssessmentResult} The result of the assessment, containing both a score and a descriptive text.\n */\n getResult({paper, researcher}) {\n this.imageCount = researcher.getResearch('imageCount');\n this.videoCount = researcher.getResearch('videoCount');\n\n const assessmentResult = new AssessmentResult({config: this._config});\n\n const calculatedResult = this.calculateResult();\n\n assessmentResult.setScore(calculatedResult.score);\n assessmentResult.setStatus(calculatedResult.status);\n\n return assessmentResult;\n }\n\n /**\n * Checks whether the paper has text.\n *\n * @param {Paper} paper The paper to use for the assessment.\n *\n * @returns {boolean} True when there is text.\n */\n isApplicable(paper) {\n return paper.hasText();\n }\n\n /**\n *\n * @returns {{score: number, status: string}}\n */\n calculateResult() {\n // If \"countVideos\" is on, we include videos in the assessment\n const mediaCount = this._countVideos ? this.imageCount + this.videoCount : this.imageCount;\n\n let status = '';\n // No images.\n if (mediaCount === 0) {\n status = 'bad';\n } else {\n status = 'good';\n }\n\n const score = this.getScore(this._config.priority, status);\n\n return {\n score,\n status\n };\n }\n}\n"],"mappings":"AAAA,SAAQA,KAAK,QAAO,QAAQ;AAC5B,OAAOC,UAAU;AACjB,OAAOC,gBAAgB;AACvB,SAAQC,QAAQ;;AAEhB;AACA;AACA;AACA,eAAe,MAAMC,oBAAoB,SAASH,UAAU,CAAC;EAC3D;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEI,WAAWA,CAACC,MAAM,GAAG,CAAC,CAAC,EAAEC,WAAW,GAAG,IAAI,EAAE;IAC3C,KAAK,CAAC,CAAC;IAEP,MAAMC,aAAa,GAAG;MACpBC,EAAE,EAAEN,QAAQ;MACZO,MAAM,EACJ,+FAA+F;MACjGC,QAAQ,EAAE,MAAM;MAChBC,WAAW,EAAE,aAAa;MAC1BC,KAAK,EAAE,OAAO;MACdC,OAAO,EAAE;QACPC,IAAI,EAAE,6BAA6B;QACnCC,OAAO,EAAE,EAAE;QACXC,GAAG,EAAE;MACP;IACF,CAAC;IAED,IAAI,CAACC,UAAU,GAAGf,QAAQ;IAC1B,IAAI,CAACgB,OAAO,GAAGnB,KAAK,CAACQ,aAAa,EAAEF,MAAM,CAAC;IAC3C,IAAI,CAACc,YAAY,GAAGb,WAAW;EACjC;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEc,SAASA,CAAC;IAACC,KAAK;IAAEC;EAAU,CAAC,EAAE;IAC7B,IAAI,CAACC,UAAU,GAAGD,UAAU,CAACE,WAAW,CAAC,YAAY,CAAC;IACtD,IAAI,CAACC,UAAU,GAAGH,UAAU,CAACE,WAAW,CAAC,YAAY,CAAC;IAEtD,MAAME,gBAAgB,GAAG,IAAIzB,gBAAgB,CAAC;MAACI,MAAM,EAAE,IAAI,CAACa;IAAO,CAAC,CAAC;IAErE,MAAMS,gBAAgB,GAAG,IAAI,CAACC,eAAe,CAAC,CAAC;IAE/CF,gBAAgB,CAACG,QAAQ,CAACF,gBAAgB,CAACG,KAAK,CAAC;IACjDJ,gBAAgB,CAACK,SAAS,CAACJ,gBAAgB,CAACK,MAAM,CAAC;IAEnD,OAAON,gBAAgB;EACzB;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEO,YAAYA,CAACZ,KAAK,EAAE;IAClB,OAAOA,KAAK,CAACa,OAAO,CAAC,CAAC;EACxB;;EAEA;AACF;AACA;AACA;EACEN,eAAeA,CAAA,EAAG;IAChB;IACA,MAAMO,UAAU,GAAG,IAAI,CAAChB,YAAY,GAAG,IAAI,CAACI,UAAU,GAAG,IAAI,CAACE,UAAU,GAAG,IAAI,CAACF,UAAU;IAE1F,IAAIS,MAAM,GAAG,EAAE;IACf;IACA,IAAIG,UAAU,KAAK,CAAC,EAAE;MACpBH,MAAM,GAAG,KAAK;IAChB,CAAC,MAAM;MACLA,MAAM,GAAG,MAAM;IACjB;IAEA,MAAMF,KAAK,GAAG,IAAI,CAACM,QAAQ,CAAC,IAAI,CAAClB,OAAO,CAACR,QAAQ,EAAEsB,MAAM,CAAC;IAE1D,OAAO;MACLF,KAAK;MACLE;IACF,CAAC;EACH;AACF","ignoreList":[]}
1
+ {"version":3,"file":"ImageCountAssessment.js","names":["merge","Assessment","AssessmentResult","FAQS_POINTS","MEDIA_ID","TextImagesAssessment","constructor","config","countVideos","defaultConfig","id","docUrl","priority","fixPosition","title","content","good","improve","bad","identifier","_config","_countVideos","getResult","paper","researcher","imageCount","getResearch","videoCount","assessmentResult","calculatedResult","calculateResult","setScore","score","setStatus","status","isApplicable","mediaCount","getScore"],"sources":["../../../../../src/scoring/assessments/seo/ImageCountAssessment.js"],"sourcesContent":["import {merge} from 'lodash';\nimport Assessment from '../assessment';\nimport AssessmentResult from '../../../values/AssessmentResult';\nimport {FAQS_POINTS, MEDIA_ID} from '@axyseo/const/analysis';\n\n/**\n * Represents the assessment that checks if the text has any images present, including videos in product pages.\n */\nexport default class TextImagesAssessment extends Assessment {\n /**\n * Sets the identifier and the config.\n *\n * @param {object} config The configuration to use.\n * @param {boolean} countVideos Whether videos are also included in the assessment or not.\n *\n * @returns {void}\n */\n constructor(config = {}, countVideos = true) {\n super();\n\n const defaultConfig = {\n id: MEDIA_ID,\n docUrl:\n 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#images-and-videos',\n priority: 'high',\n fixPosition: 'description',\n title: 'Media',\n content: {\n good: 'Media are used effectively.',\n improve: '',\n bad: 'No media found. Add visual content to enhance engagement.'\n }\n };\n\n this.identifier = MEDIA_ID;\n this._config = merge(defaultConfig, config);\n this._countVideos = countVideos;\n }\n\n /**\n * Execute the Assessment and return a result.\n *\n * @param {Paper} paper The Paper object to assess.\n * @param {Researcher} researcher The Researcher object containing all available researches.\n * @returns {AssessmentResult} The result of the assessment, containing both a score and a descriptive text.\n */\n getResult({paper, researcher}) {\n this.imageCount = researcher.getResearch('imageCount');\n this.videoCount = researcher.getResearch('videoCount');\n\n const assessmentResult = new AssessmentResult({config: this._config});\n\n const calculatedResult = this.calculateResult();\n\n assessmentResult.setScore(calculatedResult.score);\n assessmentResult.setStatus(calculatedResult.status);\n\n return assessmentResult;\n }\n\n /**\n * Checks whether the paper has text.\n *\n * @param {Paper} paper The paper to use for the assessment.\n *\n * @returns {boolean} True when there is text.\n */\n isApplicable(paper) {\n return true;\n }\n\n /**\n *\n * @returns {{score: number, status: string}}\n */\n calculateResult() {\n // If \"countVideos\" is on, we include videos in the assessment\n const mediaCount = this._countVideos ? this.imageCount + this.videoCount : this.imageCount;\n\n let status = '';\n // No images.\n if (mediaCount === 0) {\n status = 'bad';\n } else {\n status = 'good';\n }\n\n const score = this.getScore(FAQS_POINTS, status);\n\n return {\n score,\n status\n };\n }\n}\n"],"mappings":"AAAA,SAAQA,KAAK,QAAO,QAAQ;AAC5B,OAAOC,UAAU;AACjB,OAAOC,gBAAgB;AACvB,SAAQC,WAAW,EAAEC,QAAQ;;AAE7B;AACA;AACA;AACA,eAAe,MAAMC,oBAAoB,SAASJ,UAAU,CAAC;EAC3D;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEK,WAAWA,CAACC,MAAM,GAAG,CAAC,CAAC,EAAEC,WAAW,GAAG,IAAI,EAAE;IAC3C,KAAK,CAAC,CAAC;IAEP,MAAMC,aAAa,GAAG;MACpBC,EAAE,EAAEN,QAAQ;MACZO,MAAM,EACJ,+FAA+F;MACjGC,QAAQ,EAAE,MAAM;MAChBC,WAAW,EAAE,aAAa;MAC1BC,KAAK,EAAE,OAAO;MACdC,OAAO,EAAE;QACPC,IAAI,EAAE,6BAA6B;QACnCC,OAAO,EAAE,EAAE;QACXC,GAAG,EAAE;MACP;IACF,CAAC;IAED,IAAI,CAACC,UAAU,GAAGf,QAAQ;IAC1B,IAAI,CAACgB,OAAO,GAAGpB,KAAK,CAACS,aAAa,EAAEF,MAAM,CAAC;IAC3C,IAAI,CAACc,YAAY,GAAGb,WAAW;EACjC;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEc,SAASA,CAAC;IAACC,KAAK;IAAEC;EAAU,CAAC,EAAE;IAC7B,IAAI,CAACC,UAAU,GAAGD,UAAU,CAACE,WAAW,CAAC,YAAY,CAAC;IACtD,IAAI,CAACC,UAAU,GAAGH,UAAU,CAACE,WAAW,CAAC,YAAY,CAAC;IAEtD,MAAME,gBAAgB,GAAG,IAAI1B,gBAAgB,CAAC;MAACK,MAAM,EAAE,IAAI,CAACa;IAAO,CAAC,CAAC;IAErE,MAAMS,gBAAgB,GAAG,IAAI,CAACC,eAAe,CAAC,CAAC;IAE/CF,gBAAgB,CAACG,QAAQ,CAACF,gBAAgB,CAACG,KAAK,CAAC;IACjDJ,gBAAgB,CAACK,SAAS,CAACJ,gBAAgB,CAACK,MAAM,CAAC;IAEnD,OAAON,gBAAgB;EACzB;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEO,YAAYA,CAACZ,KAAK,EAAE;IAClB,OAAO,IAAI;EACb;;EAEA;AACF;AACA;AACA;EACEO,eAAeA,CAAA,EAAG;IAChB;IACA,MAAMM,UAAU,GAAG,IAAI,CAACf,YAAY,GAAG,IAAI,CAACI,UAAU,GAAG,IAAI,CAACE,UAAU,GAAG,IAAI,CAACF,UAAU;IAE1F,IAAIS,MAAM,GAAG,EAAE;IACf;IACA,IAAIE,UAAU,KAAK,CAAC,EAAE;MACpBF,MAAM,GAAG,KAAK;IAChB,CAAC,MAAM;MACLA,MAAM,GAAG,MAAM;IACjB;IAEA,MAAMF,KAAK,GAAG,IAAI,CAACK,QAAQ,CAAClC,WAAW,EAAE+B,MAAM,CAAC;IAEhD,OAAO;MACLF,KAAK;MACLE;IACF,CAAC;EACH;AACF","ignoreList":[]}
@@ -1,7 +1,8 @@
1
1
  import { merge } from 'lodash';
2
2
  import Assessment from "../assessment";
3
3
  import AssessmentResult from "../../../values/AssessmentResult";
4
- import { INTERNAL_LINKS_ID } from "../../../const/analysis";
4
+ import { LinkIcon } from '@shopify/polaris-icons';
5
+ import { INTERNAL_LINKS_ID, LINK_RECOMMEND_POINTS } from "../../../const/analysis";
5
6
 
6
7
  /**
7
8
  * Assessment to check whether the text has internal links and whether they are followed or no-followed.
@@ -26,6 +27,7 @@ class InternalLinksAssessment extends Assessment {
26
27
  id: INTERNAL_LINKS_ID,
27
28
  fixPosition: '',
28
29
  docUrl: 'https://docs.avada.io/seo-suite-help-center/seo-audit/on-page-seo/checklist#internal-links-outbound-links',
30
+ icon: LinkIcon,
29
31
  priority: 'high',
30
32
  title: 'Internal links',
31
33
  content: {
@@ -67,7 +69,7 @@ class InternalLinksAssessment extends Assessment {
67
69
  * @returns {boolean} Whether the paper has text.
68
70
  */
69
71
  isApplicable(paper) {
70
- return paper.hasText();
72
+ return true;
71
73
  }
72
74
 
73
75
  /**
@@ -75,13 +77,11 @@ class InternalLinksAssessment extends Assessment {
75
77
  * @returns {{score: number, status: string}}
76
78
  */
77
79
  calculateResult() {
78
- let status = '';
80
+ let status = 'good';
79
81
  if (this.linkStatistics.internalTotal === 0) {
80
82
  status = 'bad';
81
- } else {
82
- status = 'good';
83
83
  }
84
- const score = this.getScore(this._config.priority, status);
84
+ const score = this.getScore(LINK_RECOMMEND_POINTS, status);
85
85
  return {
86
86
  score,
87
87
  status