diff --git a/README.md b/README.md
index 0893be2..66a0871 100644
--- a/README.md
+++ b/README.md
@@ -3,9 +3,7 @@ Extension chrome pour Equideow qui permet d'obtenir plus facilement les
différentes informations du jeux comme le blup, le PG, les compétences mais
aussi d'afficher un coefficient de victoire pour mieux gérer ses blups notamment
-Il s'agit la des nouvelles et anciennes version de l'extension trouvable en stores.
-Ainsi que de la version vX.Y.Z qui est ma version personnel (incluant des features de l'abonnement VIP).
-La version vX.Y.Z n'arrivera jamais dans les store et est buggué et non fiable.
+Il s'agit la des nouvelles et anciennes version de l'extension trouvable en stores.
---
## Better Howrse
@@ -13,11 +11,9 @@ Small chrome extension for Howrse that allow you to get more informations about
your horses and competition difficulties.
Here are available all recents and pasts updates of the browser extension that you can find on the stores.
-There is also the vX.Y.Z which is my personnal version of the extension (that adds some VIP sub features).
-The vX.Y.Z will never made it to the stores and is buggy and unreliable
---
-[![Last Version](https://img.shields.io/badge/last%20version-v1.4.0-informational)](#)
+[![Last Version](https://img.shields.io/badge/last%20version-v2.0.0-informational)](#)
[![DeepScan grade](https://deepscan.io/api/teams/17688/projects/21040/branches/592899/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=17688&pid=21040&bid=592899)
[![Chrome Web Store](https://img.shields.io/chrome-web-store/v/gkopbgamdhaolbjalfcbmbjkjcmgffjp)](https://chrome.google.com/webstore/detail/better-equideow/gkopbgamdhaolbjalfcbmbjkjcmgffjp)
diff --git a/_locales/no/messages.json b/_locales/no/messages.json
new file mode 100644
index 0000000..7dc5700
--- /dev/null
+++ b/_locales/no/messages.json
@@ -0,0 +1,10 @@
+{
+ "appName": {
+ "message": "Better Howrse",
+ "description": "Navnet på utvidelsen."
+ },
+ "appDesc": {
+ "message": "Denne utvidelsen viser mer informasjon i spillet om hester og konkurranser for å få deg til å føle deg mer komfortabel når du spiller.",
+ "description": "Beskrivelse av utvidelsen.Beskrivelse av utvidelsen."
+ }
+}
\ No newline at end of file
diff --git a/competitionsDiffDisplay.js b/competitionsDiffDisplay.js
deleted file mode 100644
index 3666c33..0000000
--- a/competitionsDiffDisplay.js
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2022. Gwen Tripet-Costet
- * This file is part of Better Equideow (Better Howrse).
- * Better Equideow (Better Howrse) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- * Better Equideow (Better Howrse) is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License along with this program. If not, see .
- */
-
-let isFrenchApp;
-
-if (window.location.host.match(/.+equideow.+/)) {
- isFrenchApp = true;
-}
-
-const reducer = (a, b) => a + b;
-
-let age;
-let staminaTotalBonusValue;
-let speedTotalBonusValue;
-let dressageTotalBonusValue;
-let gallopTotalBonusValue;
-let trotTotalBonusValue;
-let jumpingTotalBonusValue;
-
-function convert(x) {
- return x.join(',').replace(/[^0-9\.,]/g, '').split(',').map((i) => Number(i));
-}
-
-function calcPoints(primarySkill, secondarySkill, lastSkill) {
- return (primarySkill * 0.45 + secondarySkill * 0.3 + lastSkill * 0.2 + age * 0.05);
-}
-
-function competitionsDiffDisplay() {
- const characteristics = document.getElementById('characteristics-body-content');
- const ageStr = characteristics.getElementsByClassName('align-right')[0].textContent;
- const ageStrArr = ageStr.match(/[1-9]\d*/g);
- let ageIntArr;
-
- if (ageStrArr) {
- ageIntArr = ageStrArr.map((i) => Number(i));
- } else return;
-
- if (ageIntArr.length > 1) {
- age = ageIntArr[0] * 12 + ageIntArr[1];
- } else if (ageIntArr.length === 1) {
- age = ageIntArr[0] * 12;
- } else {
- return;
- }
-
- const stamina = parseFloat(document.getElementById('enduranceValeur').innerText);
- const speed = parseFloat(document.getElementById('vitesseValeur').innerText);
- const dressage = parseFloat(document.getElementById('dressageValeur').innerText);
- const gallop = parseFloat(document.getElementById('galopValeur').innerText);
- const trot = parseFloat(document.getElementById('trotValeur').innerText);
- const jumping = parseFloat(document.getElementById('sautValeur').innerText);
-
- const bonusHtml = document.getElementById('bonuses-body-content');
-
-
- if (!bonusHtml.outerHTML.match(/(Ce cheval n'a aucun bonus.|This horse doesn't have any bonuses.|Cette jument n'a aucun bonus.|This mare doesn't have any bonuses.)/)) {
- const staminaBonuses = bonusHtml.outerHTML.match(/(endurance|stamina).+?[1-9]\d*/g);
- const staminaBonusesValues = convert(staminaBonuses);
-
-
- const speedBonuses = bonusHtml.outerHTML.match(/(vitesse|speed).+?[1-9]\d*/g);
- const speedBonusesValues = convert(speedBonuses);
-
-
- const dressageBonuses = bonusHtml.outerHTML.match(/dressage.+?[1-9]\d*/g);
- const dressageBonusesValues = convert(dressageBonuses);
-
-
- const gallopBonuses = bonusHtml.outerHTML.match(/(galop|gallop).+?[1-9]\d*/g);
- const gallopBonusesValues = convert(gallopBonuses);
-
- const trotBonuses = bonusHtml.outerHTML.match(/trot.+?[1-9]\d*/g);
- const trotBonusesValues = convert(trotBonuses);
-
-
- const jumpingBonuses = bonusHtml.outerHTML.match(/(saut|jumping).+?[1-9]\d*/g);
- const jumpingBonusesValues = convert(jumpingBonuses);
-
- // all bonuses
-
- staminaTotalBonusValue = staminaBonusesValues.reduce(reducer);
- speedTotalBonusValue = speedBonusesValues.reduce(reducer);
- dressageTotalBonusValue = dressageBonusesValues.reduce(reducer);
- gallopTotalBonusValue = gallopBonusesValues.reduce(reducer);
- trotTotalBonusValue = trotBonusesValues.reduce(reducer);
- jumpingTotalBonusValue = jumpingBonusesValues.reduce(reducer);
- }
-
- const totalStamina = stamina + staminaTotalBonusValue;
- const totalSpeed = speed + speedTotalBonusValue;
- const totalDressage = dressage + dressageTotalBonusValue;
- const totalGallop = gallop + gallopTotalBonusValue;
- const totalTrot = trot + trotTotalBonusValue;
- const totalJumping = jumping + jumpingTotalBonusValue;
-
- const competitionsHTML = document.getElementById('competition-body-content');
- const competitionTitle = document.getElementById('competition-head-title');
- const competitions = competitionsHTML.querySelectorAll('a');
-
- competitionTitle.style.display = 'flex';
- competitionTitle.style.flexFlow = 'column nowrap';
- const hintHTML = `${isFrenchApp ? 'Plus le coeff est élevé plus il y a de chances de gagner' : 'The higher the coefficient, the greater the chance of winning'}`;
- const parsedHintHtml = parser.parseFromString(hintHTML, `text/html`);
- const hintTags = parsedHintHtml.getElementsByTagName(`span`);
-
- for (const tag of hintTags) {
- competitionTitle.appendChild(tag);
- }
-
- competitions.forEach((competition) => {
- const diffDiv = document.createElement('div');
- diffDiv.style.margin = '0 0 0.2em 0';
- diffDiv.style.color = '#993322';
-
- let coeff;
-
- switch (competition.innerText) {
- case 'Trot':
- coeff = calcPoints(totalTrot, totalSpeed, totalDressage) / trot;
- break;
- case 'Galop':
- case 'Gallop':
- coeff = calcPoints(totalGallop, totalSpeed, totalDressage) / gallop;
- break;
- case 'Dressage':
- coeff = calcPoints(totalDressage, totalTrot, totalGallop) / dressage;
- break;
- case 'Cross':
- case 'Cross-country':
- coeff = calcPoints(totalStamina, totalDressage, totalJumping) / stamina;
- break;
- case 'Cso':
- case 'Show jumping':
- coeff = calcPoints(totalJumping, totalDressage, totalSpeed) / jumping;
- break;
- case 'Barrel racing':
- coeff = calcPoints(totalSpeed, totalStamina, totalGallop) / speed;
- break;
- case 'Cutting':
- coeff = calcPoints(totalStamina, totalDressage, totalSpeed) / stamina;
- break;
- case 'Trail class':
- coeff = calcPoints(totalDressage, totalTrot, totalJumping) / dressage;
- break;
- case 'Reining':
- coeff = calcPoints(totalGallop, totalDressage, totalStamina) / gallop;
- break;
- case 'Western pleasure':
- coeff = calcPoints(totalTrot, totalStamina, totalDressage) / trot;
- break;
- }
-
- if (coeff) {
- const diffDivHTML = `Coeff: ${coeff.toFixed(2)}`;
-
- const parsedDiffDivHTML = parser.parseFromString(diffDivHTML, `text/html`);
- const diffDivTags = parsedDiffDivHTML.getElementsByTagName(`span`);
-
- for (const tag of diffDivTags) {
- diffDiv.appendChild(tag);
- }
- competition.parentNode.insertBefore(diffDiv, competition.nextSibling);
- }
- });
-}
-
-if (window.location.href.indexOf('elevage/chevaux/cheval') > -1) {
- setTimeout(() => {
- competitionsDiffDisplay();
- }, 250);
-}
diff --git a/foodSelect.js b/foodSelect.js
new file mode 100644
index 0000000..91912fc
--- /dev/null
+++ b/foodSelect.js
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2022. Gwen Tripet-Costet
+ * This file is part of Better Equideow (Better Howrse).
+ * Better Equideow (Better Howrse) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * Better Equideow (Better Howrse) is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ */
+
+class FoodSelect {
+ constructor() {
+ this.feedingBtn = this.setHTMLElement("#boutonNourrir")
+ this.haySlider = this.setHTMLElement("#haySlider") || null // entire bloc containing ol, script, li, span
+ this.haySelectors = this.haySlider?.getElementsByTagName("span") // all span selectors from 0 to 20
+ this.oatsSlider = this.setHTMLElement("#oatsSlider") || null
+ this.oatsSelectors = this.oatsSlider?.getElementsByTagName("span")
+ }
+
+ setHTMLElement(element) {
+ return document.querySelector(element)
+ };
+
+ getFoodIndex(foodNode) {
+ const foodValue = foodNode.innerHTML
+ const foodIndex = parseInt(foodValue)
+ return foodIndex
+ }
+
+
+ async run() {
+ // will get the value eg: XX/20 for hay and X/16 for oats.
+ const fourrageNode = document.getElementsByClassName(
+ "section-fourrage section-fourrage-target"
+ )
+ const avoineNode = document.getElementsByClassName(
+ "section-avoine section-avoine-target"
+ )
+
+ if (fourrageNode.length > 0) {
+ const fourrageIndex = this.getFoodIndex(fourrageNode[0])
+ this.haySelectors[fourrageIndex].click()
+ }
+
+ if (avoineNode.length > 0) {
+ const avoineIndex = this.getFoodIndex(avoineNode[0])
+ this.oatsSelectors[avoineIndex].click()
+ }
+ }
+}
+
+if (window.location.href.indexOf("elevage/chevaux/cheval?") > -1) {
+ const foodSelect = new FoodSelect()
+ if (foodSelect.feedingBtn !== null)
+ foodSelect.feedingBtn.addEventListener("click", () => {
+ foodSelect.run()
+ })
+
+ /**
+ * @description generate a new FoodSelect() because after #loading style change,
+ * it seems like the different this.elements from foodSelect are erased ..
+ * @todo fix it...
+ */
+ const startObserver = () => {
+ observer.start().then(() => {
+ let newFoodSelect = new FoodSelect()
+ newFoodSelect.run()
+ startObserver()
+ })
+ }
+
+ startObserver()
+}
\ No newline at end of file
diff --git a/horseStats.js b/horseStats.js
new file mode 100644
index 0000000..c575c06
--- /dev/null
+++ b/horseStats.js
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2022. Gwen Tripet-Costet
+ * This file is part of Better Equideow (Better Howrse).
+ * Better Equideow (Better Howrse) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * Better Equideow (Better Howrse) is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ */
+
+class HorseStats {
+ constructor() {
+ this.lang = translation.getLang(window.location.href)
+ this.characteristicsContainer = document.getElementById('characteristics-body-content')
+ this.bonusContainer = document.getElementById('bonuses-body-content')
+ this.competitionsContainer = document.getElementById('competition-body-content')
+ this.competitions = this.competitionsContainer.querySelectorAll('a')
+ this.competitionTitle = document.getElementById('competition-head-title')
+
+ this.parser = new DOMParser()
+ this.age = this.calcAge()
+
+ this.staminaBase = this.calcStatBase('enduranceValeur')
+ this.staminaBonuses = this.calcStatBonus(new RegExp(`(${translation.get(this.lang, 'stat', 'stamina')}).+?[1-9]\d*`, "g"))
+ this.staminaTotal = this.calcStatTotal(this.staminaBase, this.staminaBonuses)
+
+ this.speedBase = this.calcStatBase('vitesseValeur')
+ this.speedBonuses = this.calcStatBonus(new RegExp(`(${translation.get(this.lang, 'stat', 'speed')}).+?[1-9]\d*`, "g"))
+ this.speedTotal = this.calcStatTotal(this.speedBase, this.speedBonuses)
+
+ this.dressageBase = this.calcStatBase('dressageValeur')
+ this.dressageBonuses = this.calcStatBonus(new RegExp(`(${translation.get(this.lang, 'stat', 'dressage')}).+?[1-9]\d*`, "g"))
+ this.dressageTotal = this.calcStatTotal(this.dressageBase, this.dressageBonuses)
+
+ this.gallopBase = this.calcStatBase('galopValeur')
+ this.gallopBonuses = this.calcStatBonus(new RegExp(`(${translation.get(this.lang, 'stat', 'gallop')}).+?[1-9]\d*`, "g"))
+ this.gallopTotal = this.calcStatTotal(this.gallopBase, this.gallopBonuses)
+
+ this.trotBase = this.calcStatBase('trotValeur')
+ this.trotBonuses = this.calcStatBonus(new RegExp(`(${translation.get(this.lang, 'stat', 'trot')}).+?[1-9]\d*`, "g"))
+ this.trotTotal = this.calcStatTotal(this.trotBase, this.trotBonuses)
+
+ this.jumpingBase = this.calcStatBase('sautValeur')
+ this.jumpingBonuses = this.calcStatBonus(new RegExp(`(${translation.get(this.lang, 'stat', 'jumping')}).+?[1-9]\d*`, "g"))
+ this.jumpingTotal = this.calcStatTotal(this.jumpingBase, this.jumpingBonuses)
+ }
+
+ convert(value) {
+ if (value !== null) {
+ return value.join(',').replace(/[^0-9\.,]/g, '').split(',').map((i) => Number(i))
+ }
+ }
+
+ calcAge() {
+ const ageStr = this.characteristicsContainer.getElementsByClassName('align-right')[0].textContent
+ const ageStrArr = ageStr.match(/[1-9]\d*/g)
+
+ let ageIntArr
+ if (ageStrArr) {
+ ageIntArr = ageStrArr.map((i) => Number(i))
+ } else return
+
+ if (ageIntArr.length > 1) {
+ return this.age = ageIntArr[0] * 12 + ageIntArr[1]
+ } else if (ageIntArr.length === 1) {
+ return this.age = ageIntArr[0] * 12
+ } else {
+ return
+ }
+ }
+
+ calcStatBase(stat) {
+ return parseFloat(document.getElementById(stat).innerText)
+ }
+
+ calcStatBonus(stat) {
+ if (this.bonusContainer.childElementCount !== 4) {
+ const statBonuses = this.bonusContainer.outerHTML.match(stat)
+ return this.convert(statBonuses)
+ }
+ }
+
+ calcStatTotal(statBase, statBonuses) {
+ const totalBonusValue = statBonuses?.reduce((a, b) => a + b) || 0
+ return statBase + totalBonusValue
+ }
+
+ calcCoeff(primarySkill, secondarySkill, lastSkill) {
+ return (primarySkill * 0.45 + secondarySkill * 0.3 + lastSkill * 0.2 + this.age * 0.05)
+ }
+
+ competitionsDiffDisplay() {
+ this.competitionTitle.style.display = 'flex'
+ this.competitionTitle.style.flexFlow = 'column nowrap'
+ const hintHTML = ` ${this.isFrenchApp ? 'Plus le coeff est élevé plus il y a de chances de gagner' : 'The higher the coefficient, the greater the chance of winning'} `
+ const parsedHintHtml = this.parser.parseFromString(hintHTML, `text/html`)
+ const hintTags = parsedHintHtml.getElementsByTagName(`span`)
+
+ for (const tag of hintTags) {
+ this.competitionTitle.appendChild(tag)
+ }
+
+ this.competitions.forEach((competition) => {
+ const diffDiv = document.createElement('div')
+ diffDiv.style.margin = '0 0 0.2em 0'
+ diffDiv.style.color = '#993322'
+
+ let coeff
+
+ switch (competition.innerText) {
+ case translation.get(this.lang, 'competition', 'trot'):
+ coeff = this.calcCoeff(this.trotTotal, this.speedTotal, this.dressageTotal) / this.trotBase
+ break
+ case translation.get(this.lang, 'competition', 'gallop'):
+ coeff = this.calcCoeff(this.gallopTotal, this.speedTotal, this.dressageTotal) / this.gallopBase
+ break
+ case translation.get(this.lang, 'competition', 'dressage'):
+ coeff = this.calcCoeff(this.dressageTotal, this.trotTotal, this.gallopTotal) / this.dressageBase
+ break
+ case translation.get(this.lang, 'competition', 'crossCountry'):
+ coeff = this.calcCoeff(this.staminaTotal, this.dressageTotal, this.jumpingTotal) / this.staminaBase
+ break
+ case translation.get(this.lang, 'competition', 'showJumping'):
+ coeff = this.calcCoeff(this.jumpingTotal, this.dressageTotal, this.speedTotal) / this.jumpingBase
+ break
+ case translation.get(this.lang, 'competition', 'barrelRacing'):
+ coeff = this.calcCoeff(this.speedTotal, this.staminaTotal, this.gallopTotal) / this.speedBase
+ break
+ case translation.get(this.lang, 'competition', 'cutting'):
+ coeff = this.calcCoeff(this.staminaTotal, this.dressageTotal, this.speedTotal) / this.staminaBase
+ break
+ case translation.get(this.lang, 'competition', 'trailClass'):
+ coeff = this.calcCoeff(this.dressageTotal, this.trotTotal, this.jumpingTotal) / this.dressageBase
+ break
+ case translation.get(this.lang, 'competition', 'reining'):
+ coeff = this.calcCoeff(this.gallopTotal, this.dressageTotal, this.staminaTotal) / this.gallopBase
+ break
+ case translation.get(this.lang, 'competition', 'westernPleasure'):
+ coeff = this.calcCoeff(this.trotTotal, this.staminaTotal, this.dressageTotal) / this.trotBase
+ break
+ }
+
+ if (coeff) {
+ const diffDivHTML = `Coeff: ${coeff.toFixed(2)} `
+
+ const parsedDiffDivHTML = this.parser.parseFromString(diffDivHTML, `text/html`)
+ const diffDivTags = parsedDiffDivHTML.getElementsByTagName(`span`)
+
+ for (const tag of diffDivTags) {
+ diffDiv.appendChild(tag)
+ }
+ competition.parentNode.insertBefore(diffDiv, competition.nextSibling)
+ }
+ })
+ }
+
+ run() {
+ this.competitionsDiffDisplay()
+ }
+}
+
+if (window.location.href.indexOf('elevage/chevaux/cheval') > -1) {
+ const horseStats = new HorseStats()
+ horseStats.run()
+}
diff --git a/loadingDisplayObserver.js b/loadingDisplayObserver.js
new file mode 100644
index 0000000..f7a20eb
--- /dev/null
+++ b/loadingDisplayObserver.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2022. Gwen Tripet-Costet
+ * This file is part of Better Equideow (Better Howrse).
+ * Better Equideow (Better Howrse) is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * Better Equideow (Better Howrse) is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ */
+
+class LoadingDisplayObserver {
+ constructor() {
+ this.targetNode = document.querySelector('#loading');
+ this.config = { attributes: true, attributeFilter: ['style'] };
+ }
+ start() {
+ return new Promise((resolve) => {
+ this.observer = new MutationObserver((mutationsList) => {
+ for (let mutation of mutationsList) {
+ if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
+ let element = mutation.target;
+ let display = window.getComputedStyle(element, null).getPropertyValue("display");
+ if (display === "none") {
+ resolve();
+ }
+ }
+ }
+ });
+ this.observer.observe(this.targetNode, this.config);
+ });
+ }
+ stop() {
+ this.observer.disconnect();
+ }
+}
+
+const observer = new LoadingDisplayObserver();
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index a9bdf7f..c16f2df 100644
--- a/manifest.json
+++ b/manifest.json
@@ -2,12 +2,8 @@
"name": "__MSG_appName__",
"description": "__MSG_appDesc__",
"default_locale": "fr",
- "version": "1.4.0",
+ "version": "2.0.0",
"manifest_version": 3,
- "action": {
- "default_title": "Click to see your horse sells",
- "default_popup": "popup.html"
- },
"author": "TC-Dev",
"icons": {
"16": "/images/icon-16x16.png",
@@ -17,9 +13,19 @@
},
"content_scripts": [
{
- "matches": ["*://*.equideow.com/*", "*://*.howrse.com/*"],
+ "matches": [
+ "*://*.equideow.com/*",
+ "*://*.howrse.com/*",
+ "*://*.howrse.no/*"
+ ],
"run_at": "document_end",
- "js": ["moreInfos.js", "competitionsDiffDisplay.js", "foodSelect.js"]
+ "js": [
+ "translation.js",
+ "loadingDisplayObserver.js",
+ "moreInfos.js",
+ "horseStats.js",
+ "foodSelect.js"
+ ]
}
]
-}
+}
\ No newline at end of file
diff --git a/moreInfos.js b/moreInfos.js
index cc21fe2..b36b6ef 100644
--- a/moreInfos.js
+++ b/moreInfos.js
@@ -6,250 +6,158 @@
* You should have received a copy of the GNU General Public License along with this program. If not, see .
*/
-const regexpBlupHtml =
- /