@danielhaim/titlecaser 1.7.0 → 1.7.2
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.
- package/README.md +231 -87
- package/dist/titlecaser.amd.js +5 -0
- package/dist/titlecaser.module.js +5 -0
- package/index.d.ts +23 -0
- package/package.json +16 -14
- package/src/TitleCaser.js +120 -53
- package/src/TitleCaserConsts.js +188 -33
- package/src/TitleCaserUtils.js +166 -202
- package/src/data/brandList.json +532 -89
- package/src/data/businessFinanceLegalTerms.json +108 -14
- package/src/data/eCommerceDigitalTerms.json +13 -3
- package/src/data/globalGeography.json +197 -41
- package/src/data/marketingMediaTerms.json +37 -6
- package/src/data/militaryTerms.json +153 -0
- package/src/data/miscSpecializedTerms.json +12 -3
- package/src/data/techComputingConcepts.json +184 -26
- package/src/data/timeAcademicTerms.json +32 -5
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @danielhaim/titlecaser - v1.7.2 - 2025-04-09
|
|
3
|
+
* https://github.com/danielhaim1/titlecaser.git
|
|
4
|
+
* Copyright (c) 2025 Daniel Haim, Licensed Apache-2.0
|
|
5
|
+
*/(()=>{"use strict";var e={16:e=>{e.exports=JSON.parse('{"ranks":["Pvt.","Cpl.","Sgt.","SSgt.","GySgt.","MSgt.","1stSgt.","SgtMaj.","WO1","CW2","CW3","CW4","CW5","2ndLt.","1stLt.","Capt.","Maj.","LtCol.","Col.","BrigGen.","MajGen.","LtGen.","Gen.","Adm.","Cpt.","Cmdr.","Lt.","Ens."],"branches":["Army","Navy","Air Force","Marines","Coast Guard","Space Force","National Guard","People\'s Liberation Army","Russian Ground Forces","JASDF","ROKA"],"units":["Platoon","Company","Battalion","Regiment","Brigade","Division","Corps","Squad","Fleet","Wing","Squadron","Task Force","Eurocorps","Battlegroup","Rapid Reaction Force","Joint Expeditionary Force"],"acronyms":["DoD","NATO","EUFOR","EUTM","OSCE","UNSC","JAG","ROTC","AFB","MOS","AWOL","MRE","IED","FOB","TOC","CONUS","OCONUS","UCMJ","USMC","USAF","USN","USA","SOCOM","CENTCOM","NORAD","PACOM","JTF","RPG","SAM","ASEAN","AUKUS","QUAD","CSTO","SCO","CFSP","EEAS","EUMS","Frontex","GRU","FSB","PLAN","PLAAF"],"equipment":["Humvee","MRAP","Apache","Black Hawk","Bradley","Abrams","F-16","F-22","F-35","B-2","B-52","C-130","LCAC","MRE"],"operations":["Operation Desert Storm","Operation Enduring Freedom","Operation Iraqi Freedom","Operation Inherent Resolve"],"treaties":["Lisbon Treaty","Maastricht Treaty","Treaty of Rome","Nice Treaty","Schengen Agreement"],"regions":["South China Sea","Taiwan Strait","Korean DMZ","Kashmir","Kuril Islands","Senkaku Islands"],"alliances":["NATO","AUKUS","QUAD","ASEAN","SCO","CSTO","Five Eyes"]}')},157:e=>{e.exports=JSON.parse('{"countries":["Afghanistan","Albania","Algeria","Andorra","Angola","Antigua and Barbuda","Argentina","Armenia","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bhutan","Bolivia","Bosnia and Herzegovina","Botswana","Brazil","Brunei","Bulgaria","Burkina Faso","Burundi","Cabo Verde","Cambodia","Cameroon","Canada","Central African Republic","Chad","Chile","China","Colombia","Comoros","Congo","Costa Rica","Cote d\'Ivoire","Croatia","Cuba","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Eswatini","Ethiopia","Fiji","Finland","France","Gabon","Gambia","Georgia","Germany","Ghana","Greece","Grenada","Guatemala","Guinea","Guinea-Bissau","Guyana","Haiti","Honduras","Hungary","Iceland","India","Indonesia","Iran","Iraq","Ireland","Israel","Italy","Jamaica","Japan","Jordan","Kazakhstan","Kenya","Kiribati","Korea","Kosovo","Kuwait","Kyrgyzstan","Laos","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Mauritania","Mauritius","Mexico","Micronesia","Moldova","Monaco","Mongolia","Montenegro","Morocco","Mozambique","Myanmar","Namibia","Nauru","Nepal","Netherlands","New Zealand","Nicaragua","Niger","Nigeria","North Macedonia","Norway","Oman","Pakistan","Palau","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal","Qatar","Romania","Russia","Rwanda","Saint Kitts and Nevis","Saint Lucia","Saint Vincent and the Grenadines","Samoa","San Marino","Sao Tome and Principe","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Korea","South Sudan","Spain","Sri Lanka","Sudan","Suriname","Sweden","Switzerland","Syria","Taiwan","Tajikistan","Tanzania","Thailand","Timor-Leste","Togo","Tonga","Trinidad and Tobago","Tunisia","Turkey","Turkmenistan","Tuvalu","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States","Uruguay","Uzbekistan","Vanuatu","Vatican City","Venezuela","Vietnam","Yemen","Zambia","Zimbabwe"],"alpha2":["UK"],"alpha3":["USA"]}')},223:e=>{e.exports=JSON.parse('{"sports":["FIFA","UEFA","NBA","NFL","MLB","NHL","NASCAR","IOC","FIBA","ATP","WTA","PGA","LPGA","FIA","WADA","ITF","AFL","NRL","ICC","IRB","IHF","FIVB","FINA","UCI","IAAF","ISU","WSF","BWF","WBC","WBO","IBF","IBO","UEFA","CONMEBOL","CONCACAF","CAF","AFC","OFC","CPL","MLS","LaLiga","Bundesliga","Ligue1","Eredivisie","JLeague","KLeague","Ryder Cup","Davis Cup","FedCup","XGames","Olympics","Paralympics","Dakar"],"apple":["Apple","AirDrop","AirPlay","AirPods","AirTags","FinalCut","GarageBand","iBooks","iCloud","iLife","iMac","iMessage","iMovie","iPhoto","iWatch","iWork","LogicPro","macOS","ProTools","QuickTime","iPhone","iPad","iPod","iOS","macOS","tvOS","watchOS"],"corporate":["Deloitte","Devoteam","ExxonMobil","GE","Boeing","Shell","Chevron"],"tech":["Bing","Salesforce","Asus","Acer","Lenovo","Huawei","Xiaomi","Epson","Nvidia","AMD","Qualcomm","Logitech","Panasonic","Sharp","Toshiba","Philips","Fujitsu","Netgear","Lexmark","Razer","SAP","Symantec","Kaspersky","Avast","McAfee","Siemens","Canon","Nikon","Garmin","GoPro","Oculus","Zoom","Slack","Trello","WeChat","Alibaba","Tencent","Baidu","Roku","Fitbit","Dropbox","Reddit","TikTok","Slack","Trello","Uber","Zoom","Reddit","Quora","JIRA","ZoomInfo","HubSpot","Mailchimp","WeChat","Dropbox","Uber","Telegram","Discord","StackOverflow","Quora","Reddit","ZoomInfo","Airbnb","LinkedIn","Snapchat","GitHub","GitLab","Nginx","OpenSSL","Webpack","Unity3D","Figma","JIRA","Kubernetes","TensorFlow","NPM","WooCommerce","WordPress","Slack","Trello","Uber","Zoom","Reddit","Quora","WeChat","Dropbox","Telegram","Discord","StackOverflow","Airbnb","LinkedIn","Snapchat","JIRA","MobX","VMware","Google"],"business":["Visa","Mastercard","Citibank","JPMorgan","Barclay","AMEX","Citigroup","PayPal","BNP","HSBC","Santander","UBS","Allianz","Prudential","Vanguard","BlackRock","CapitalOne","TD","Robinhood","MoneyGram","SoFi","Experian","Equifax","TransUnion","MasterCard","Blockchain","Coinbase","Binance","Kraken","Ethereum","Bitcoin"],"automotive":["BMW","Ford","Mercedes","Nissan","Tesla","Toyota","Audi","Chevrolet","Chrysler","Dodge","Ferrari","Fiat","Honda","Hyundai","Infiniti","Jaguar","Jeep","Kia","Lamborghini","LandRover","Lexus","Maserati","Mazda","McLaren","Mitsubishi","Peugeot","Porsche","Renault","RollsRoyce","Saab","Subaru","Suzuki","Volkswagen","Volvo","Alfa Romeo","Bentley","Bugatti","Cadillac","Citroen","Daewoo","Daihatsu","Datsun","DeLorean","Fiat Chrysler","GMC","Holden","Hummer","Isuzu","Koenigsegg","Lancia","Lincoln","Lotus","Mahindra","Suzuki","Opel","Pagani","Perodua","Proton","Rover","Scania","Skoda","SsangYong","Tata","Vauxhall","VinFast","Yugo","Zenvo"],"media":["Disney","Netflix","YouTube","Instagram","Twitter","Facebook","Spotify","Hulu","TikTok","Snapchat","Vimeo","Twitch","Reddit","HBO","Showtime","Starz","Crunchyroll","Audible","Pixar","DreamWorks","MGM","Lionsgate","Miramax","EpicGames","Ubisoft","Blizzard","Capcom","Bethesda","Sega","Roku","Fandango","IMDb","Shazam","SoundCloud","Vevo","Vine","Zynga","Tidal","Quibi","Crave","Gaia","PlutoTV","Vudu","Kanopy","Mubi","BritBox"],"telecom":["Verizon","Sprint","Nokia","Ericsson","Vodafone","AT&T","Huawei","Xiaomi","Orange","NTT","T-Mobile","Telefonica","Airtel","Telstra","Rogers","Bell","MTN","ZTE","Qualcomm","Motorola","Telus","BT","Swisscom","SoftBank","KDDI"],"entertainment":["Disney","Netflix","YouTube","Instagram","Twitter","Facebook","Spotify","Hulu","TikTok","Snapchat","Vimeo","Twitch","Reddit","Pandora","HBO","Showtime","Starz","Paramount","Peacock","Crunchyroll","Audible","Pixar","DreamWorks","MGM","Lionsgate","Miramax","EpicGames","Ubisoft","Blizzard","Capcom","Bethesda","Sega","Roku","Fandango","IMDb","Shazam","SoundCloud","Vevo","Zynga","Tidal","Oscars"],"retail":["Amazon","eBay","IKEA","Walmart","Zara","Target","Costco","Sephora","Nordstrom","Tesco","Asda","Aldi","Lidl","Carrefour","Uniqlo","H&M","Gap","Cabela’s","BassPro","REI","Ulta","Saks","JCPenney","Belk","Argos","Safeway","Kroger","Publix","HomeDepot","Woolworths","Staples","OfficeMax","B&H","Newegg","MicroCenter","Frys","Monoprix","Waitrose","Morrisons","Ocado","Flipkart","Rakuten","Alibaba","JD","Taobao","Tmall","Guomei","Suning"],"food":["Nestle","Pepsi","Coca-Cola","PepsiCo","Starbucks","KFC","BurgerKing","PizzaHut","TacoBell","Kroger","Costco","Woolworths","Carrefour","Tesco","Aldi","Lidl","Walmart","Safeway","Publix","WholeFoods","RedBull","Monster","Nespresso","Heineken","Budweiser","Corona","Guinness","GeneralMills","Unilever","Kraft","Heinz","Danone","Campbell","Tyson","Conagra","Mondelez","Suntory","Diageo","Pernod"],"pharmaceutical":["Pfizer","Moderna","Gilead","Merck","Novartis","Sanofi","Roche","AbbVie","Amgen","Bayer","Biogen","BristolMyers","Celgene","GSK","Janssen","Lilly","Medtronic","Mylan","NovoNordisk","Regeneron","Teva","AstraZeneca","Boehringer","Daiichi","Eisai","Genentech","Grifols","Ipsen","Mundipharma","Otsuka","Purdue","Sandoz","Servier","SunPharma","Takeda","UCB","Viatris","Wockhardt","Zydus","Alkem"],"nonprofit":["NGO","NPO","NGOs","NPOs","UN","UNESCO","UNICEF","UNHCR","UNODC","UNDP","UNFPA","UNEP","UNRWA"]}')},279:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.TitleCaserUtils=void 0;var i=r(416);function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,i)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var i=r.call(e,t||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}class n{static validateOption(e,t){if(!Array.isArray(t))throw new TypeError(`Invalid option: ${e} must be an array`);if(!t.every((e=>"string"==typeof e)))throw new TypeError(`Invalid option: ${e} must be an array of strings`)}static validateOptions(e){for(const t of Object.keys(e))if("style"!==t)if("wordReplacementsList"!==t){if(!i.titleCaseDefaultOptionsList.hasOwnProperty(t))throw new TypeError(`Invalid option: ${t}`);this.TitleCaseValidator.validateOption(t,e[t])}else{if(!Array.isArray(e.wordReplacementsList))throw new TypeError(`Invalid option: ${t} must be an array`);for(const r of e.wordReplacementsList)if("string"!=typeof r)throw new TypeError(`Invalid option: ${t} must contain only strings`)}else{if("string"!=typeof e.style)throw new TypeError(`Invalid option: ${t} must be a string`);if(!i.allowedTitleCaseStylesList.includes(e.style))throw new TypeError(`Invalid option: ${t} must be a string`)}}static getTitleCaseOptions(e={},t=[]){const r=JSON.stringify({options:e,lowercaseWords:t});if(n.titleCaseOptionsCache.has(r))return n.titleCaseOptionsCache.get(r);const a=s(s(s({},i.titleCaseDefaultOptionsList[e.style||"ap"]),e),{},{smartQuotes:!!e.hasOwnProperty("smartQuotes")&&e.smartQuotes}),o=a.articlesList.concat(t).filter(((e,t,r)=>r.indexOf(e)===t)),l=a.shortConjunctionsList.concat(t).filter(((e,t,r)=>r.indexOf(e)===t)),c=a.shortPrepositionsList.concat(t).filter(((e,t,r)=>r.indexOf(e)===t)),u=[...(a.replaceTerms||[]).map((([e,t])=>[e.toLowerCase(),t])),...i.wordReplacementsList],p={articlesList:o,shortConjunctionsList:l,shortPrepositionsList:c,neverCapitalizedList:[...a.neverCapitalizedList],replaceTerms:u,smartQuotes:a.smartQuotes};return n.titleCaseOptionsCache.set(r,p),p}static capitalizeFirstLetter(e){return e.charAt(0).toUpperCase()+e.slice(1)}static isShortConjunction(e,t){const r=[...n.getTitleCaseOptions({style:t}).shortConjunctionsList],i=e.toLowerCase();return r.includes(i)}static isArticle(e,t){return n.getTitleCaseOptions({style:t}).articlesList.includes(e.toLowerCase())}static isShortPreposition(e,t){const{shortPrepositionsList:r}=n.getTitleCaseOptions({style:t});return r.includes(e.toLowerCase())}static isNeverCapitalized(e,t){const r=`${t}_${e.toLowerCase()}`;if(n.isNeverCapitalizedCache.has(r))return n.isNeverCapitalizedCache.get(r);const{neverCapitalizedList:i}=n.getTitleCaseOptions({style:t}),a=i.includes(e.toLowerCase());return n.isNeverCapitalizedCache.set(r,a),a}static isShortWord(e,t){if("string"!=typeof e)throw new TypeError(`Invalid input: word must be a string. Received ${typeof e}.`);if(!i.allowedTitleCaseStylesList.includes(t))throw new Error(`Invalid option: style must be one of ${i.allowedTitleCaseStylesList.join(", ")}.`);return n.isShortConjunction(e,t)||n.isArticle(e,t)||n.isShortPreposition(e,t)||n.isNeverCapitalized(e,t)}static hasNumbers(e){return/\d/.test(e)}static hasUppercaseMultiple(e){let t=0;for(let r=0;r<e.length&&t<2;r++)/[A-Z]/.test(e[r])&&t++;return t>=2}static hasUppercaseIntentional(e){if(e.length<=4)return/[A-Z]/.test(e.slice(1));const t=/[A-Z]/.test(e.slice(1)),r=/[a-z]/.test(e.slice(1));return t&&r}static isEntirelyUppercase(e){return e===e.toUpperCase()&&e!==e.toLowerCase()&&e.length>1}static isRegionalAcronym(e){if("string"!=typeof e)throw new TypeError("Invalid input: word must be a string.");if(e.length<2)return!1;const t=e.toLowerCase();return i.regionalAcronymList.includes(t)}static isRegionalAcronymNoDot(e,t,r=null){if("string"!=typeof e||"string"!=typeof t)return!1;const a=e.toLowerCase().replace(/[^\w\s]/g,""),s=t.toLowerCase().replace(/[^\w\s]/g,"");return!!(r&&i.regionalAcronymList.includes(a)&&["the"].includes(r.toLowerCase()))||i.regionalAcronymList.includes(a)&&i.directFollowingIndicatorsRegionalAcronym.includes(s)}static isFinalWordRegionalAcronym(e,t,r=null){if("string"!=typeof e||"string"!=typeof t)return!1;const a=e.toLowerCase().replace(/[^\w]/g,""),s=t.toLowerCase().replace(/[^\w]/g,""),o="string"==typeof r?r.toLowerCase().replace(/[^\w]/g,""):null;return!!i.regionalAcronymList.includes(a)&&(!!i.regionalAcronymPrecedingWords.includes(s)||!("the"!==s||!o||!i.regionalAcronymPrecedingWords.includes(o)))}static normalizeRegionalAcronym(e){if("string"!=typeof e)throw new TypeError("Invalid input: word must be a string.");return e.toUpperCase()}static normalizeAcronymKey(e){return e.toLowerCase().replace(/\./g,"")}static normalizeCasingForWordByStyle(e,t){if(!e||!t||!i.titleCaseDefaultOptionsList[t])return!1;const r=e.toLowerCase(),{shortConjunctionsList:a,articlesList:s,shortPrepositionsList:o,neverCapitalizedList:n}=i.titleCaseDefaultOptionsList[t];return!![...a,...s,...o,...n].includes(r)&&e}static hasSuffix(e){return e.length>2&&e.endsWith("'s")}static hasApostrophe(e){return-1!==e.indexOf("'")}static hasHyphen(e){return-1!==e.indexOf("-")||-1!==e.indexOf("–")||-1!==e.indexOf("—")}static hasRomanNumeral(e){if("string"!=typeof e||""===e)throw new TypeError("Invalid input: word must be a non-empty string.");const t=e.includes("'")?e.split("'"):[e],r=/^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/i;return t.every((e=>r.test(e)))}static hasHyphenRomanNumeral(e){if("string"!=typeof e||""===e)throw new TypeError("Invalid input: word must be a non-empty string.");const t=e.split("-");for(let e=0;e<t.length;e++)if(!n.hasRomanNumeral(t[e]))return!1;return!0}static hasHtmlBreak(e){return"nl2br"===e}static hasUnicodeSymbols(e){return/[^\x00-\x7F\u00A0-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u02B0-\u02FF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0800-\u083F\u0840-\u085F\u0860-\u087F\u0880-\u08AF\u08B0-\u08FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF]/.test(e)}static hasCurrencySymbols(e){return/[^\x00-\x7F\u00A0-\u00FF\u20AC\u20A0-\u20B9\u20BD\u20A1-\u20A2\u00A3-\u00A5\u058F\u060B\u09F2-\u09F3\u0AF1\u0BF9\u0E3F\u17DB\u20A6\u20A8\u20B1\u2113\u20AA-\u20AB\u20AA\u20AC-\u20AD\u20B9]/.test(e)}static isWordAmpersand(e){return/&|&/.test(e)}static startsWithSymbol(e){if("string"!=typeof e)throw new Error(`Parameter 'word' must be a string. Received '${typeof e}' instead.`);if(0===e.length)return!1;const t=e.charAt(0);return"#"===t||"@"===t||"."===t}static escapeSpecialCharacters(e){return e.replace(/[&<>"']/g,(function(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case'"':return""";case"'":return"'";default:return e}}))}static unescapeSpecialCharacters(e){return e.replace(/&|<|>|"|'/g,(function(e){switch(e){case"&":return"&";case"<":return"<";case">":return">";case""":return'"';case"'":return"'";default:return e}}))}static endsWithSymbol(e,t=[".",",",";",":","?","!"]){if("string"!=typeof e||!Array.isArray(t))throw new Error("Invalid arguments");return t.some((t=>e.endsWith(t)))||t.includes(e.slice(-2))}static isWordIgnored(e,t=i.ignoredWordList){if(!Array.isArray(t))throw new TypeError("Invalid input: ignoredWords must be an array.");if("string"!=typeof e||""===e.trim())throw new TypeError("Invalid input: word must be a non-empty string.");let r;return r=e.toLowerCase().trim(),t.includes(r)}static isWordInArray(e,t){return!!Array.isArray(t)&&t.some((t=>t.toLowerCase()===e.toLowerCase()))}static convertQuotesToCurly(e){const t={"'":["‘","’"],'"':["“","”"]};let r="";for(let i=0;i<e.length;i++){const a=e[i],s=t[a];if(s){const t=e[i-1],a=e[i+1],o=!t||" "===t||"\n"===t?s[0]:s[1];r+=o,o===s[1]&&/[.,;!?()\[\]{}:]/.test(a)&&(r+=a,i++)}else r+=a}return r}static replaceTerm(e,t){if("string"!=typeof e||""===e)throw new TypeError("Invalid input: word must be a non-empty string.");if(!t||"object"!=typeof t)throw new TypeError("Invalid input: replaceTermObj must be a non-null object.");let r;if(r=e.toLowerCase(),t.hasOwnProperty(r))return t[r];if(t.hasOwnProperty(e))return t[e];const i=e.toUpperCase();return t.hasOwnProperty(i)?t[i]:e}static isElidedWord(e){if("string"!=typeof e||""===e.trim())throw new TypeError("Invalid input: word must be a non-empty string.");const t=new Set(["o’","fo’","ne’er","e’er","’tis","’twas","’n’"]),r=e.trim().toLowerCase().replace(/'/g,"’");for(const e of t)if(r.startsWith(e))return!0;return!1}static normalizeElidedWord(e){if("string"!=typeof e||""===e.trim())throw new TypeError("Invalid input: word must be a non-empty string.");const t=new Set(["o’","fo’","ne’er","e’er","’tis","’twas","’n’"]),r=e.trim(),i=r.replace(/'/g,"’").toLowerCase();for(const e of t)if(i.startsWith(e)){const t=e.length,i=r.slice(t);return e.charAt(0).toUpperCase()+e.slice(1)+(i.length>0?i.charAt(0).toUpperCase()+i.slice(1):"")}return!1}static correctSuffix(e,t){if("string"!=typeof e||""===e)throw new TypeError("Invalid input: word must be a non-empty string.");if(!t||!Array.isArray(t)||t.some((e=>"string"!=typeof e)))throw new TypeError("Invalid input: correctTerms must be an array of strings.");if(/'s$/i.test(e)){const r=e.slice(0,-2),i=t.findIndex((e=>e.toLowerCase()===r.toLowerCase()));if(i>=0){return`${t[i]}'s`}return`${r.charAt(0).toUpperCase()+r.slice(1)}'s`}return e}static correctTerm(e,t,r=/[-']/){if("string"!=typeof e||""===e)throw new TypeError("Invalid input: word must be a non-empty string.");if(!t||!Array.isArray(t))throw new TypeError("Invalid input: correctTerms must be an array.");if(!("string"==typeof r||Array.isArray(r)||r instanceof RegExp))throw new TypeError("Invalid input: delimiters must be a string, an array of strings, or a regular expression.");"string"==typeof r?r=new RegExp(`[${r}]`):Array.isArray(r)&&(r=new RegExp(`[${r.join("")}]`));const i=e.split(r),a=i.length;for(let e=0;e<a;e++){const r=i[e].toLowerCase(),a=t.findIndex((e=>e.toLowerCase()===r));i[e]=a>=0?t[a]:i[e].charAt(0).toUpperCase()+i[e].slice(1).toLowerCase()}let s=r.source.charAt(0);return e.includes("-")?s="-":e.includes("'")&&(s="'"),i.join(s)}static correctTermHyphenated(e,t){const r=e.split("-"),a=e=>e.charAt(0).toUpperCase()+e.slice(1),s=e=>e.charAt(0)+e.slice(1).toLowerCase(),o={ap:(e,t)=>0===t?a(e):s(e),chicago:a,apa:(e,r,i)=>n.isShortWord(e,t)&&r>0&&r<i-1?e.toLowerCase():a(e),nyt:(e,t)=>0===t?a(e):s(e),wikipedia:(e,t)=>0===t?a(e):s(e)},l=o[t]||s,c=r.map(((e,t)=>{let a=e;if(/^(M{0,3})(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})'s$/i.test(e)){return a.toUpperCase().replace(/'S$/,"'s")}const s=/^(M{0,3})(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/i;if(s.test(e))return e.toUpperCase();if(e.includes("'")){const i=e.split("'");return i.every((e=>s.test(e)))?(a=i.map((e=>e.toUpperCase())).join("'"),a):l(a,t,r.length)}const o=e.toLowerCase(),n=i.correctTitleCasingList.findIndex((e=>e.toLowerCase()===o));if(n>=0)a=i.correctTitleCasingList[n];else if(o.endsWith("'s")){const e=o.substring(0,o.length-2),t=i.correctTitleCasingList.findIndex((t=>t.toLowerCase()===e));t>=0&&(a=`${i.correctTitleCasingList[t]}'s`)}return l(a,t,r.length)}));return c.join("-")}}t.TitleCaserUtils=n,o(n,"TitleCaseValidator",void 0),o(n,"titleCaseOptionsCache",new Map),o(n,"isNeverCapitalizedCache",new Map)},321:e=>{e.exports=JSON.parse('{"advertising":["AdWords","AdSense","AdMob","DoubleClick","SpotX"],"digitalMarketing":["DSP","SSP","CTR","CPA","CPC","CPL","CPM","CRM","SEO","SEM","SMM","A/B","CTOR","KPI","SERP","FAQ","PR"],"general":["B2B","B2C","CMO","USP","PWA","SMO","T&C","TOS","PP","UI","UX","UI/UX"],"blockchain":["PoE","PoW","PoC"],"accessibility":["A11Y"]}')},388:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.TitleCaser=void 0;var i=r(416),a=r(279);t.TitleCaser=class{constructor(e={}){this.options=e,this.debug=e.debug||!1,this.wordReplacementsList=i.wordReplacementsList,this.correctPhraseCasingList=i.correctPhraseCasingList}logWarning(e){this.debug&&console.warn(`Warning: ${e}`)}toTitleCase(e){try{if(0===e.trim().length)throw new TypeError("Invalid input: input must not be empty.");if("string"!=typeof e)throw new TypeError("Invalid input: input must be a string.");if(void 0!==this.options&&"object"!=typeof this.options)throw new TypeError("Invalid options: options must be an object.");const{style:t="ap",neverCapitalize:r=[],replaceTermList:s=this.wordReplacementsList,smartQuotes:o=!1}=this.options,n=["nl2br",...r],{articlesList:l,shortConjunctionsList:c,shortPrepositionsList:u,neverCapitalizedList:p,replaceTerms:d,smartQuotes:m}=a.TitleCaserUtils.getTitleCaseOptions(this.options,i.commonShortWords,i.wordReplacementsList),g=s.map((e=>Object.keys(e)[0].toLowerCase())),C=Object.fromEntries(s.map((e=>[Object.keys(e)[0].toLowerCase(),Object.values(e)[0]])));this.logWarning(`replaceTermsArray: ${g}`),this.logWarning(`this.wordReplacementsList: ${this.wordReplacementsList}`);let h=e.trim();h=h.replace(/<\s*br\s*\/?\s*>/gi," nl2br "),h=h.replace(/ {2,}/g,(e=>e.slice(0,1)));a.TitleCaserUtils.isEntirelyUppercase(h.replace(/[^a-zA-Z]/g,""))&&(this.logWarning("Input string is entirely uppercase, normalizing to lowercase first"),h=h.toLowerCase());const y=h.split(" ");h=y.map(((e,r)=>{switch(!0){case a.TitleCaserUtils.isWordAmpersand(e):case a.TitleCaserUtils.hasHtmlBreak(e):case a.TitleCaserUtils.isWordIgnored(e,n):return e;case g.includes(e.toLowerCase()):return C[e.toLowerCase()];case a.TitleCaserUtils.isWordInArray(e,i.correctTitleCasingList):return a.TitleCaserUtils.correctTerm(e,i.correctTitleCasingList);case a.TitleCaserUtils.isElidedWord(e):return a.TitleCaserUtils.normalizeElidedWord(e);case a.TitleCaserUtils.hasHyphen(e):const s=e.replace(/[\W_]+$/,""),o=e.slice(s.length),l=s.split("-"),c=l.map((e=>{const t=e.toLowerCase();return g.includes(t)?C[t]:e})),u=!c.every(((e,t)=>e===l[t]))?c.join("-"):a.TitleCaserUtils.correctTermHyphenated(e,t);return u.endsWith(o)?u:u+o;case a.TitleCaserUtils.hasSuffix(e,t):return a.TitleCaserUtils.correctSuffix(e,i.correctTitleCasingList);case a.TitleCaserUtils.hasUppercaseIntentional(e):return e;case a.TitleCaserUtils.isShortWord(e,t)&&0!==r:if(r>0&&a.TitleCaserUtils.endsWithSymbol(y[r-1],[":","?","!","."]))return e.charAt(0).toUpperCase()+e.slice(1);return a.TitleCaserUtils.normalizeCasingForWordByStyle(e,t);case a.TitleCaserUtils.endsWithSymbol(e):this.logWarning(`Check if the word ends with a symbol: ${e}`);const p=e.split(/([.,\/#!$%\^&\*;:{}=\-_`~()?])/g);this.logWarning(`Splitting word at symbols, result: ${p}`);return p.map((e=>{if(this.logWarning(`Processing part: ${e}`),a.TitleCaserUtils.endsWithSymbol(e))return this.logWarning(`Part is a symbol: ${e}`),e;if(this.logWarning(`Part is a word: ${e}`),a.TitleCaserUtils.isWordInArray(e,i.correctTitleCasingList)){const t=a.TitleCaserUtils.correctTerm(e,i.correctTitleCasingList);return this.logWarning(`Word is in correctTitleCasingList, corrected term: ${t}`),t}if(g.includes(e)){const t=C[e];return this.logWarning(`Word is in replaceTermsArray, replacement: ${t}`),t}{const t=e.charAt(0).toUpperCase()+e.slice(1).toLowerCase();return this.logWarning(`Applying title casing to word: ${t}`),t}})).join("");case a.TitleCaserUtils.startsWithSymbol(e):return a.TitleCaserUtils.isWordInArray(e,i.correctTitleCasingList)?a.TitleCaserUtils.correctTerm(e):e;case a.TitleCaserUtils.hasRomanNumeral(e):return e.toUpperCase();case a.TitleCaserUtils.hasNumbers(e):return e;default:return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}})).join(" "),h=h.replace(/nl2br/gi,"<br>"),o&&(h=a.TitleCaserUtils.convertQuotesToCurly(h));const f=h.split(" ");let S=f[0],w=f[1]||null;f[f.length-1];for(let e=0;e<f.length;e++){e>0&&f[e-1];let t=f[e];const r=e<f.length-1?f[e+1]:null,i=t.match(/[.,!?;:]+$/);let s="";i&&(s=i[0],t=t.replace(/[.,!?;:]+$/,"")),a.TitleCaserUtils.isRegionalAcronym(t)&&(t=a.TitleCaserUtils.normalizeRegionalAcronym(t)),a.TitleCaserUtils.isRegionalAcronymNoDot(t,r)&&(t=a.TitleCaserUtils.normalizeRegionalAcronym(t)),""!==s&&(t+=s)}h=f.join(" ");const A=h.split(" ");for(let e=1;e<A.length-1;e++){const t=A[e];A[e-1],A[e+1];t===t.toUpperCase()||a.TitleCaserUtils.hasUppercaseIntentional(t)||a.TitleCaserUtils.isWordInArray(t,i.commonShortWords)&&(A[e]=t.length<=3?t.toLowerCase():t)}h=A.join(" ");const L=h.split(" ");for(let e=0;e<L.length;e++){let t=L[e],r=L[e+1],i=L[e-1];null!==r&&a.TitleCaserUtils.isRegionalAcronymNoDot(t,r,i)&&(L[e]=t.toUpperCase())}let b=L[L.length-1],T=L[L.length-2],O=L[L.length-3];a.TitleCaserUtils.isRegionalAcronym(S)&&(console.log("firstWord is a regional acronym, proof: ",S),L[0]=S.toUpperCase()),a.TitleCaserUtils.isRegionalAcronymNoDot(S,w)&&(L[0]=S.toUpperCase()),a.TitleCaserUtils.isFinalWordRegionalAcronym(b,T,O)&&(L[L.length-1]=b.toUpperCase()),h=L.join(" ");for(const[e,t]of Object.entries(this.correctPhraseCasingList)){const r=new RegExp(e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");h=h.replace(r,t)}return h}catch(e){throw new Error(e)}}setReplaceTerms(e){if(!Array.isArray(e))throw new TypeError("Invalid argument: setReplaceTerms must be an array of objects.");e.forEach((e=>{if(e&&"object"==typeof e){const[t,r]=Object.entries(e)[0],i=this.wordReplacementsList.findIndex((e=>e.hasOwnProperty(t)));-1!==i?this.wordReplacementsList[i][t]=r:this.wordReplacementsList.push({[t]:r})}else console.warn("Invalid entry in terms array:",e)})),this.options.wordReplacementsList=this.wordReplacementsList,this.logWarning(`Log the updated this.wordReplacementsList: ${this.wordReplacementsList}`)}addReplaceTerm(e,t){if("string"!=typeof e||"string"!=typeof t)throw new TypeError("Invalid argument: term and replacement must be strings.");const r=this.wordReplacementsList.findIndex((t=>Object.keys(t)[0]===e));-1!==r?this.wordReplacementsList[r][e]=t:this.wordReplacementsList.push({[e]:t}),this.options.wordReplacementsList=this.wordReplacementsList}removeReplaceTerm(e){if("string"!=typeof e)throw new TypeError("Invalid argument: term must be a string.");const t=this.wordReplacementsList.findIndex((t=>Object.keys(t)[0]===e));if(-1===t)throw new Error(`Term '${e}' not found in word replacements list.`);this.wordReplacementsList.splice(t,1),this.options.wordReplacementsList=this.wordReplacementsList,this.logWarning(`Log the updated this.wordReplacementsList: ${this.wordReplacementsList}`)}addExactPhraseReplacements(e){if(!Array.isArray(e))throw new TypeError("Invalid argument: newPhrases must be an array.");e.forEach((e=>{if("object"!=typeof e||Array.isArray(e)||1!==Object.keys(e).length){if("object"!=typeof e||Array.isArray(e))throw new TypeError("Invalid argument: Each item must be an object with a single key-value pair.");Object.entries(e).forEach((([e,t])=>{if("string"!=typeof e||"string"!=typeof t)throw new TypeError("Invalid argument: Each key-value pair must contain strings.");this.correctPhraseCasingList[e]=t}))}else{const t=Object.keys(e)[0],r=e[t];if("string"!=typeof t||"string"!=typeof r)throw new TypeError("Invalid argument: Each key-value pair must contain strings.");this.correctPhraseCasingList[t]=r}})),this.logWarning(`Log the this.correctPhraseCasingList: ${this.correctPhraseCasingList}`)}setStyle(e){if("string"!=typeof e)throw new TypeError("Invalid argument: style must be a string.");this.options.style=e}}},416:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.wordReplacementsList=t.titleCaseStylesList=t.titleCaseDefaultOptionsList=t.regionalAcronymPrecedingWords=t.regionalAcronymList=t.ignoredWordList=t.directFollowingIndicatorsRegionalAcronym=t.correctTitleCasingList=t.correctPhraseCasingList=t.commonShortWords=t.allowedTitleCaseStylesList=void 0;var i=d(r(223)),a=d(r(814)),s=d(r(661)),o=d(r(157)),n=d(r(321)),l=d(r(742)),c=d(r(501)),u=d(r(491)),p=d(r(16));function d(e){return e&&e.__esModule?e:{default:e}}const m=function(...e){const t=[];return e.forEach((e=>{Array.isArray(e)?e.forEach((e=>{Object.values(e).forEach((e=>{t.push(...e)}))})):"object"==typeof e&&Object.values(e).forEach((e=>{t.push(...e)}))})),[...new Set(t)]}(i.default,a.default,s.default,o.default,n.default,l.default,c.default,u.default,p.default),g=(t.correctTitleCasingList=m,t.commonShortWords=["the","in","to","within","towards","into","at","of","for","by","on","from","with","through","about","across","over","under","between"],t.wordReplacementsList=[{"a.k.a":"AKA"},{"a.s.a.p":"ASAP"},{"f.a.q":"FAQ"},{"f.a.q.s":"FAQs"},{FAQS:"FAQs"},{"f.y.i":"FYI"},{"d.i.y":"DIY"},{"t.b.d":"TBD"},{"back-end":"Backend"},{"front-end":"Frontend"},{"full-stack":"Fullstack"},{nodejs:"Node.js"},{nextjs:"Next.js"},{nuxtjs:"Nuxt.js"},{reactjs:"React"},{"react.js":"React"},{"cyber-security":"Cybersecurity"}],t.titleCaseStylesList=Object.freeze({AP:"ap",APA:"apa",BRITISH:"british",CHICAGO:"chicago",NYT:"nyt",WIKIPEDIA:"wikipedia"}));t.allowedTitleCaseStylesList=Object.values(g),t.titleCaseDefaultOptionsList=Object.freeze({ap:{shortConjunctionsList:["and","but","or","for","nor","yet","so"],articlesList:["a","an","the"],shortPrepositionsList:["as","at","by","in","into","of","off","on","onto","out","over","to","up","via","with","from","under","upon","among"],neverCapitalizedList:[]},apa:{shortConjunctionsList:["and","but","by","for","in","nor","of","on","or","so","to","yet"],articlesList:["a","an","the"],shortPrepositionsList:["about","above","across","after","against","along","among","around","as","at","before","behind","below","beneath","beside","between","beyond","by","despite","down","during","except","for","from","in","inside","into","like","near","of","off","on","onto","out","outside","over","past","since","through","throughout","till","to","toward","under","underneath","until","up","upon","via","with","within","without"],neverCapitalizedList:[]},british:{shortConjunctionsList:["and","but","or","for","nor","yet","so"],articlesList:["a","an","the"],shortPrepositionsList:["as","at","by","in","into","of","off","on","onto","out","over","to","up","via","with","from","under","upon"],neverCapitalizedList:[]},chicago:{shortConjunctionsList:["and","but","or","for","nor","yet","so"],articlesList:["a","an","the"],shortPrepositionsList:["as","at","by","in","into","of","off","on","onto","out","over","to","up","via","with","from","under","upon"],neverCapitalizedList:["etc."]},nyt:{shortConjunctionsList:["and","but","or","for","nor","yet","so"],articlesList:["a","an","the"],shortPrepositionsList:["as","at","by","in","into","of","off","on","onto","out","over","to","up","via","with","from","under","upon"],neverCapitalizedList:[]},wikipedia:{shortConjunctionsList:["and","as","but","for","nor","or","so","yet"],articlesList:["a","an","the"],shortPrepositionsList:["as","at","by","in","into","of","off","on","onto","out","over","to","up","via","with","from","under","upon"],neverCapitalizedList:[]}}),t.ignoredWordList=[],t.correctPhraseCasingList={"the cybersmile foundation":"The Cybersmile Foundation","co. by colgate":"CO. by Colgate","on & off":"On & Off","on and off":"On and Off"},t.regionalAcronymList=["usa","us","u.s.a","u.s.","u.s","u.s.a.","eu","e.u.","e.u","uk","u.k.","u.k"],t.regionalAcronymPrecedingWords=["the","via","among","across","beyond","outside","alongside","throughout","despite","unlike","upon"],t.directFollowingIndicatorsRegionalAcronym=["act","acts","administration","administrations","agency","agencies","agreement","agreements","airforce","airforces","aid","alliance","alliances","ambassador","ambassadors","authority","authorities","bill","bills","bloc","blocs","budget","budgets","bureau","bureaus","cabinet","cabinets","charter","charters","command","commands","commission","commissions","conference","conferences","congress","congresses","convention","conventions","council","councils","court","courts","defense","defences","defence","defenses","delegation","delegations","democracy","democracies","department","departments","development","developments","directive","directives","diplomacy","division","divisions","economy","economies","embassy","embassies","engagement","engagements","envoy","envoys","exports","federation","federations","finance","finances","forces","framework","frameworks","funding","government","governments","hearing","hearings","imports","initiative","initiatives","intel","intelligence","intervention","interventions","jurisdiction","jurisdictions","law","laws","leadership","leaders","legislation","liaison","liaisons","mandate","mandates","markets","marines","military","militaries","ministry","ministries","mission","missions","navy","navies","negotiations","office","offices","operations","oversight","parliament","parliaments","plan","plans","policies","policy","policy-makers","precedent","precedents","presence","program","programme","programmes","programs","project","projects","protocol","protocols","province","provinces","reform","reforms","regulation","regulations","regulator","regulators","relations","representation","representations","republic","republics","resolution","resolutions","ruling","rulings","sanctions","security","securities","senate","senates","service","services","state","states","statute","statutes","strategy","strategies","summit","summits","summitry","surveillance","talks","tariffs","territory","territories","trade","trades","treasury","treasuries","treaty","treaties","tribunal","tribunals","troops","union","unions","veterans","warships","zone","zones"]},491:e=>{e.exports=JSON.parse('{"timeRelated":["a.m.","p.m.","ca.","cc.","fig.","pl.","pt.","rev.","sr.","v.","vol.","et al.","pp.","p."],"academic":["adj.","adv.","cf.","cm.","co.","corp.","dept.","dist.","ed.","edn.","esp.","etc.","ex.","i.e.","e.g.","op. cit.","vs."]}')},501:e=>{e.exports=JSON.parse('{"terms":["API","APIs","ASCII","CI","CLI","DLL","DNS","EC2","FTP","HTTP","HTTPS","ICMP","IDE","IP","ISP","LPWAN","M2M","MQTT","OOP","REST","SSH","SSL","TCP","UDP","URL","WLAN","WYSIWYG","IMAP","RSS","IaaS","PaaS","SaaS","CaaS","FaaS","XaaS","RaaS","IoE","IoT","LoRa","NB-IoT","RFID","RF","RFI","RFQ","ECMAScript","IO","I/O","DevOps","SecOps","DDoS","VoIP","AI","AR","ML","VR","CI/CD","DevSecOps","UI/UX","UX/UI","UI","UX","MVC","ORM","3G","4G","5G","NumPy","VPN","PKI","WAN","NAT","GPU","SSD","HDD","RAM","Frontend","Backend","Fullstack"],"legal":["DMCA","GDPR","HIPAA","NDA","SOW","TOS"],"languages":["JavaScript","TypeScript","Java","PHP","SQL","CSS",".NET","ES5","ES6","NoSQL","DynamoDB","Terraform","CloudFormation","RDS","Python","Ruby","Go","Swift","Kotlin","Perl"],"formats":["JSON","XML","YAML","GraphQL","WebSocket","RESTful"],"secops":["RaaS","DevSecOps","SecOps","Cybersecurity","DDoS"],"technologies":["AWS","Azure","GCP","VMware","Docker","Ansible","Chef","Puppet","Git","Subversion","Jenkins","CircleCI","Hadoop","Spark","BigQuery","PowerBI","Tableau"],"os":["Android","macOS","Windows","Linux","iOS","Ubuntu","CentOS","Fedora","Debian","SUSE","HarmonyOS","FreeRTOS","BeOS","BSD","Cordova","Flutter"],"programming":["Angular","Bootstrap","CodeIgniter","jQuery","Laravel","Redux","Vue.js","VueX","SCSS","AJAX","GraphQL","HTML","HTML5","MySQL","MongoDB","PostgresQL","SQLite","ASP","ASPX","Elasticsearch","Nginx","OpenSSL","Webpack","Unity3D","Kubernetes","TensorFlow","NPM","cURL"]}')},661:e=>{e.exports=JSON.parse('{"eterms":["eBook","eBooks","eMarket","eMarketplace","eMarketplaces","eMarkets","eReader","eShop","eShops","eStore","eStores","E-commerce","E-com"]}')},742:e=>{e.exports=JSON.parse('{"miscellaneous":["w/","w/o","Open Source","Cybersecurity","Ecosystem","Biodiversity","LGBT","LGBTQ+","LGBTQIA+","2SLGBTQ+","BIPOC"]}')},814:e=>{e.exports=JSON.parse('{"commercial":["Ltd.","LLC","PLC","Co.","Inc.","St.","Ave.","Bldg.","No.","GmbH"],"titles":["CEO","CEOs","CFO","CFOs","CIO","CIOs","CMO","CMOs","COO","COOs","CPO","CPOs","CRO","CROs","CSO","CSOs","CTO","CTOs","EVP","EVPs","HR","HRs","SVP","SVPs","VP","VPs","CMTO","CDO"],"accounting":["AP","COGS","EBIT","EPS","FIFO","GAAP","LIFO","P&L","ROI","SOX","TCO","VAT","EBITDA","NPV","WACC","AR"],"finance":["CAGR","DCF","ETF","IPO","IRR","M&A","NAV","PE","PEG","PPE","ROE","S&P","TVM","VC","FOMC","FX","ETF"],"legal":["AFA","ADR","CCPA","CFAA","CISG","DMCA","EULA","GDPR","HIPAA","NDA","SOW","TOS","LLM","JD","Esq.","AG","SARL","KYC","AML","ph.d.","m.d.","d.d.s.","d.m.d.","d.o.","d.c.","d.v.m.","d.n.p.","d.p.m.","d.s.w.","d.s.n.","d.n.sc.","d.n.a.","d.n.t.","d.n.p.t.","d.n.o.","d.n.m.","d.n.e.","d.n.s.","d.n.p.s."]}')},987:(e,t,r)=>{var i=r(388);void 0===String.prototype.toTitleCase&&(String.prototype.toTitleCase=function(e){return new i.TitleCaser(e).toTitleCase(this)}),e.exports&&(e.exports={TitleCaser:i.TitleCaser}),"undefined"!=typeof window&&window.document&&(window.TitleCaser=i.TitleCaser)}},t={};var r=function r(i){var a=t[i];if(void 0!==a)return a.exports;var s=t[i]={exports:{}};return e[i](s,s.exports,r),s.exports}(987);module.exports=r})();
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare module '@danielhaim/titlecaser' {
|
|
2
|
+
export interface TitleCaserOptions {
|
|
3
|
+
style?: 'ap' | 'apa' | 'chicago' | 'wikipedia' | 'nyt';
|
|
4
|
+
smartQuotes?: boolean;
|
|
5
|
+
ignoreWords?: string[];
|
|
6
|
+
acronyms?: string[];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class TitleCaser {
|
|
10
|
+
constructor(options?: TitleCaserOptions);
|
|
11
|
+
toTitleCase(text: string): string;
|
|
12
|
+
setReplaceTerms(terms: Array<{ [key: string]: string }>): void;
|
|
13
|
+
addReplaceTerm(term: string, replacement: string): void;
|
|
14
|
+
removeReplaceTerm(term: string): void;
|
|
15
|
+
addExactPhraseReplacements(phrases: Array<{ [key: string]: string }>): void;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare global {
|
|
20
|
+
interface String {
|
|
21
|
+
toTitleCase(options?: import('@danielhaim/titlecaser').TitleCaserOptions): string;
|
|
22
|
+
}
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielhaim/titlecaser",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "Converts a string to title case with multiple style options, ability to ignore certain words, and handle acronyms",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"title case",
|
|
@@ -37,9 +37,11 @@
|
|
|
37
37
|
"main": "./index.js",
|
|
38
38
|
"files": [
|
|
39
39
|
"LICENSE",
|
|
40
|
+
"index.d.ts",
|
|
40
41
|
"README.md",
|
|
41
42
|
"index.js",
|
|
42
43
|
"src/",
|
|
44
|
+
"dist",
|
|
43
45
|
"package.json"
|
|
44
46
|
],
|
|
45
47
|
"scripts": {
|
|
@@ -52,27 +54,27 @@
|
|
|
52
54
|
"tree": "tree -a -I 'node_modules|.git|.DS_Store'"
|
|
53
55
|
},
|
|
54
56
|
"devDependencies": {
|
|
55
|
-
"@babel/cli": "^7.
|
|
56
|
-
"@babel/core": "^7.
|
|
57
|
+
"@babel/cli": "^7.27.0",
|
|
58
|
+
"@babel/core": "^7.26.10",
|
|
57
59
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
58
60
|
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
|
|
59
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
60
|
-
"@babel/preset-env": "^7.
|
|
61
|
-
"@babel/runtime-corejs3": "^7.
|
|
61
|
+
"@babel/plugin-transform-modules-commonjs": "^7.26.3",
|
|
62
|
+
"@babel/preset-env": "^7.26.9",
|
|
63
|
+
"@babel/runtime-corejs3": "^7.27.0",
|
|
62
64
|
"@jest/expect": "^29.5.0",
|
|
63
65
|
"babel-jest": "^29.7.0",
|
|
64
|
-
"babel-loader": "^
|
|
66
|
+
"babel-loader": "^10.0.0",
|
|
65
67
|
"esbuild-jest": "^0.5.0",
|
|
66
68
|
"exports-loader": "^5.0.0",
|
|
67
69
|
"jest": "^29.7.0",
|
|
68
70
|
"jest-environment-jsdom": "^29.5.0",
|
|
69
|
-
"jest-environment-puppeteer": "^
|
|
70
|
-
"jest-puppeteer": "^
|
|
71
|
-
"puppeteer": "^
|
|
72
|
-
"puppeteer-core": "^
|
|
73
|
-
"terser-webpack-plugin": "^5.3.
|
|
74
|
-
"webpack": "^5.
|
|
75
|
-
"webpack-cli": "
|
|
71
|
+
"jest-environment-puppeteer": "^11.0.0",
|
|
72
|
+
"jest-puppeteer": "^11.0.0",
|
|
73
|
+
"puppeteer": "^24.6.0",
|
|
74
|
+
"puppeteer-core": "^24.6.0",
|
|
75
|
+
"terser-webpack-plugin": "^5.3.14",
|
|
76
|
+
"webpack": "^5.99.5",
|
|
77
|
+
"webpack-cli": "6.0.1",
|
|
76
78
|
"webpack-node-externals": "^3.0.0"
|
|
77
79
|
},
|
|
78
80
|
"publishConfig": {
|
package/src/TitleCaser.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
commonShortWords,
|
|
3
3
|
correctTitleCasingList,
|
|
4
4
|
correctPhraseCasingList,
|
|
5
|
-
wordReplacementsList
|
|
5
|
+
wordReplacementsList
|
|
6
6
|
} from "./TitleCaserConsts.js";
|
|
7
7
|
|
|
8
8
|
import { TitleCaserUtils } from "./TitleCaserUtils.js";
|
|
9
9
|
|
|
10
10
|
export class TitleCaser {
|
|
11
|
-
constructor(options = {}) {
|
|
11
|
+
constructor (options = {}) {
|
|
12
12
|
this.options = options;
|
|
13
13
|
this.debug = options.debug || false;
|
|
14
14
|
this.wordReplacementsList = wordReplacementsList;
|
|
@@ -23,13 +23,13 @@ export class TitleCaser {
|
|
|
23
23
|
|
|
24
24
|
toTitleCase(str) {
|
|
25
25
|
try {
|
|
26
|
-
// If input is empty, throw an error.
|
|
26
|
+
// ! If input is empty, throw an error.
|
|
27
27
|
if (str.trim().length === 0) throw new TypeError("Invalid input: input must not be empty.");
|
|
28
28
|
|
|
29
|
-
// If input is not a string, throw an error.
|
|
29
|
+
// ! If input is not a string, throw an error.
|
|
30
30
|
if (typeof str !== "string") throw new TypeError("Invalid input: input must be a string.");
|
|
31
31
|
|
|
32
|
-
// If options is not an object, throw an error.
|
|
32
|
+
// ! If options is not an object, throw an error.
|
|
33
33
|
if (typeof this.options !== "undefined" && typeof this.options !== "object")
|
|
34
34
|
throw new TypeError("Invalid options: options must be an object.");
|
|
35
35
|
|
|
@@ -47,8 +47,8 @@ export class TitleCaser {
|
|
|
47
47
|
shortPrepositionsList,
|
|
48
48
|
neverCapitalizedList,
|
|
49
49
|
replaceTerms,
|
|
50
|
-
smartQuotes: mergedSmartQuotes,
|
|
51
|
-
} = TitleCaserUtils.getTitleCaseOptions(this.options,
|
|
50
|
+
smartQuotes: mergedSmartQuotes,
|
|
51
|
+
} = TitleCaserUtils.getTitleCaseOptions(this.options, commonShortWords, wordReplacementsList);
|
|
52
52
|
|
|
53
53
|
// Prerocess the replaceTerms array to make it easier to search for.
|
|
54
54
|
const replaceTermsArray = replaceTermList.map((term) => Object.keys(term)[0].toLowerCase());
|
|
@@ -79,26 +79,37 @@ export class TitleCaser {
|
|
|
79
79
|
// Remove extra spaces and replace <br> tags with a placeholder.
|
|
80
80
|
inputString = inputString.replace(/ {2,}/g, (match) => match.slice(0, 1));
|
|
81
81
|
|
|
82
|
+
// Check if the entire input string is uppercase and normalize it to lowercase
|
|
83
|
+
// before processing if it is. This ensures consistent handling for all-caps text.
|
|
84
|
+
const isEntireStringUppercase = TitleCaserUtils.isEntirelyUppercase(inputString.replace(/[^a-zA-Z]/g, ''));
|
|
85
|
+
if (isEntireStringUppercase) {
|
|
86
|
+
this.logWarning("Input string is entirely uppercase, normalizing to lowercase first");
|
|
87
|
+
inputString = inputString.toLowerCase();
|
|
88
|
+
}
|
|
89
|
+
|
|
82
90
|
// Split the string into an array of words.
|
|
83
91
|
const words = inputString.split(" ");
|
|
84
92
|
|
|
85
93
|
const wordsInTitleCase = words.map((word, i) => {
|
|
86
94
|
switch (true) {
|
|
87
95
|
case TitleCaserUtils.isWordAmpersand(word):
|
|
88
|
-
// if the word is an ampersand, return it as is.
|
|
96
|
+
// ! if the word is an ampersand, return it as is.
|
|
89
97
|
return word;
|
|
90
98
|
case TitleCaserUtils.hasHtmlBreak(word):
|
|
91
|
-
// If the word is a <br> tag, return it as is.
|
|
99
|
+
// ! If the word is a <br> tag, return it as is.
|
|
92
100
|
return word;
|
|
93
101
|
case TitleCaserUtils.isWordIgnored(word, ignoreList):
|
|
94
|
-
// If the word is in the ignore list, return it as is.
|
|
102
|
+
// ! If the word is in the ignore list, return it as is.
|
|
95
103
|
return word;
|
|
96
104
|
case replaceTermsArray.includes(word.toLowerCase()):
|
|
97
|
-
// If the word is in the replaceTerms array, return the replacement.
|
|
105
|
+
// ! If the word is in the replaceTerms array, return the replacement.
|
|
98
106
|
return replaceTermObj[word.toLowerCase()];
|
|
99
107
|
case TitleCaserUtils.isWordInArray(word, correctTitleCasingList):
|
|
100
|
-
// If the word is in the correctTitleCasingList array, return the correct casing.
|
|
108
|
+
// ! If the word is in the correctTitleCasingList array, return the correct casing.
|
|
101
109
|
return TitleCaserUtils.correctTerm(word, correctTitleCasingList);
|
|
110
|
+
case TitleCaserUtils.isElidedWord(word):
|
|
111
|
+
// ! If the word is an elided word, return the correct casing.
|
|
112
|
+
return TitleCaserUtils.normalizeElidedWord(word);
|
|
102
113
|
case TitleCaserUtils.hasHyphen(word):
|
|
103
114
|
// Separate the base word from any trailing punctuation
|
|
104
115
|
const baseWord = word.replace(/[\W_]+$/, "");
|
|
@@ -121,19 +132,23 @@ export class TitleCaser {
|
|
|
121
132
|
const processedWord = isReplaced ? replacedParts.join("-") : TitleCaserUtils.correctTermHyphenated(word, style);
|
|
122
133
|
return processedWord.endsWith(trailingPunctuation) ? processedWord : processedWord + trailingPunctuation;
|
|
123
134
|
case TitleCaserUtils.hasSuffix(word, style):
|
|
124
|
-
// If the word has a suffix, return the correct casing.
|
|
135
|
+
// ! If the word has a suffix, return the correct casing.
|
|
125
136
|
return TitleCaserUtils.correctSuffix(word, correctTitleCasingList);
|
|
126
137
|
case TitleCaserUtils.hasUppercaseIntentional(word):
|
|
127
|
-
// If the word has an intentional uppercase letter, return the correct casing.
|
|
138
|
+
// ! If the word has an intentional uppercase letter, return the correct casing.
|
|
128
139
|
return word;
|
|
129
140
|
case TitleCaserUtils.isShortWord(word, style) && i !== 0:
|
|
130
|
-
// If the word is a short word, return the correct casing.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
141
|
+
// ! If the word is a short word, return the correct casing.
|
|
142
|
+
const isAtEndOfSentence = i > 0 && TitleCaserUtils.endsWithSymbol(words[i - 1], [":", "?", "!", "."]);
|
|
143
|
+
if (isAtEndOfSentence) {
|
|
144
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const wordCasing = TitleCaserUtils.normalizeCasingForWordByStyle(word, style);
|
|
148
|
+
return wordCasing;
|
|
134
149
|
case TitleCaserUtils.endsWithSymbol(word):
|
|
135
150
|
this.logWarning(`Check if the word ends with a symbol: ${word}`);
|
|
136
|
-
// If the word ends with a symbol, return the correct casing.
|
|
151
|
+
// ! If the word ends with a symbol, return the correct casing.
|
|
137
152
|
const splitWord = word.split(/([.,\/#!$%\^&\*;:{}=\-_`~()?])/g);
|
|
138
153
|
this.logWarning(`Splitting word at symbols, result: ${splitWord}`);
|
|
139
154
|
// Process each part for correct casing
|
|
@@ -145,7 +160,7 @@ export class TitleCaser {
|
|
|
145
160
|
return part;
|
|
146
161
|
} else {
|
|
147
162
|
this.logWarning(`Part is a word: ${part}`);
|
|
148
|
-
// If it's a word, process it for correct casing
|
|
163
|
+
// ! If it's a word, process it for correct casing
|
|
149
164
|
if (TitleCaserUtils.isWordInArray(part, correctTitleCasingList)) {
|
|
150
165
|
const correctedTerm = TitleCaserUtils.correctTerm(part, correctTitleCasingList);
|
|
151
166
|
this.logWarning(`Word is in correctTitleCasingList, corrected term: ${correctedTerm}`);
|
|
@@ -165,15 +180,15 @@ export class TitleCaser {
|
|
|
165
180
|
// Join the processed words and return them.
|
|
166
181
|
return processedWords.join("");
|
|
167
182
|
case TitleCaserUtils.startsWithSymbol(word):
|
|
168
|
-
// If the word starts with a symbol, return the correct casing.
|
|
183
|
+
// ! If the word starts with a symbol, return the correct casing.
|
|
169
184
|
return !TitleCaserUtils.isWordInArray(word, correctTitleCasingList)
|
|
170
185
|
? word
|
|
171
186
|
: TitleCaserUtils.correctTerm(word);
|
|
172
187
|
case TitleCaserUtils.hasRomanNumeral(word):
|
|
173
|
-
// If the word has a roman numeral, return the correct casing.
|
|
188
|
+
// ! If the word has a roman numeral, return the correct casing.
|
|
174
189
|
return word.toUpperCase();
|
|
175
190
|
case TitleCaserUtils.hasNumbers(word):
|
|
176
|
-
// If the word has numbers, return the correct casing.
|
|
191
|
+
// ! If the word has numbers, return the correct casing.
|
|
177
192
|
return word;
|
|
178
193
|
default:
|
|
179
194
|
// Default to returning the word with the correct casing.
|
|
@@ -184,14 +199,6 @@ export class TitleCaser {
|
|
|
184
199
|
// Join the words in the array into a string.
|
|
185
200
|
inputString = wordsInTitleCase.join(" ");
|
|
186
201
|
|
|
187
|
-
for (const [phrase, replacement] of Object.entries(this.correctPhraseCasingList)) {
|
|
188
|
-
// Create a regular expression for case-insensitive matching of the phrase
|
|
189
|
-
const regex = new RegExp(phrase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
|
|
190
|
-
|
|
191
|
-
// Replace the phrase in the input string with its corresponding replacement
|
|
192
|
-
inputString = inputString.replace(regex, replacement);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
202
|
// Replace the nl2br placeholder with <br> tags.
|
|
196
203
|
inputString = inputString.replace(/nl2br/gi, "<br>");
|
|
197
204
|
|
|
@@ -202,6 +209,9 @@ export class TitleCaser {
|
|
|
202
209
|
}
|
|
203
210
|
|
|
204
211
|
const newWords = inputString.split(" ");
|
|
212
|
+
let firstWord = newWords[0];
|
|
213
|
+
let secondWord = newWords[1] || null;
|
|
214
|
+
let lastWord = newWords[newWords.length - 1];
|
|
205
215
|
|
|
206
216
|
for (let i = 0; i < newWords.length; i++) {
|
|
207
217
|
const prevWord = i > 0 ? newWords[i - 1] : null;
|
|
@@ -217,29 +227,86 @@ export class TitleCaser {
|
|
|
217
227
|
currentWord = currentWord.replace(/[.,!?;:]+$/, ""); // Remove punctuation at the end
|
|
218
228
|
}
|
|
219
229
|
|
|
220
|
-
|
|
221
|
-
|
|
230
|
+
if (TitleCaserUtils.isRegionalAcronym(currentWord)) {
|
|
231
|
+
currentWord = TitleCaserUtils.normalizeRegionalAcronym(currentWord);
|
|
232
|
+
}
|
|
222
233
|
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
} else {
|
|
231
|
-
if (punctuation === "") {
|
|
232
|
-
newWords[i] = "Us";
|
|
233
|
-
} else {
|
|
234
|
-
newWords[i] = "Us" + punctuation;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
234
|
+
if (TitleCaserUtils.isRegionalAcronymNoDot(currentWord, nextWord)) {
|
|
235
|
+
currentWord = TitleCaserUtils.normalizeRegionalAcronym(currentWord);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// if punctuation is not empty, add it to the end of the word
|
|
239
|
+
if (punctuation !== "") {
|
|
240
|
+
currentWord = currentWord + punctuation;
|
|
237
241
|
}
|
|
238
242
|
}
|
|
239
243
|
|
|
240
244
|
inputString = newWords.join(" ");
|
|
241
245
|
|
|
246
|
+
const newSplit = inputString.split(" ");
|
|
247
|
+
for (let i = 1; i < newSplit.length - 1; i++) {
|
|
248
|
+
const currentWord = newSplit[i];
|
|
249
|
+
const prevWord = newSplit[i - 1];
|
|
250
|
+
const nextWord = newSplit[i + 1];
|
|
251
|
+
|
|
252
|
+
if (
|
|
253
|
+
currentWord === currentWord.toUpperCase() ||
|
|
254
|
+
TitleCaserUtils.hasUppercaseIntentional(currentWord)
|
|
255
|
+
) {
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (TitleCaserUtils.isWordInArray(currentWord, commonShortWords)) {
|
|
260
|
+
newSplit[i] =
|
|
261
|
+
currentWord.length <= 3
|
|
262
|
+
? currentWord.toLowerCase()
|
|
263
|
+
: currentWord;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
inputString = newSplit.join(" ");
|
|
268
|
+
|
|
269
|
+
const newSplit2 = inputString.split(" ");
|
|
270
|
+
for (let i = 0; i < newSplit2.length; i++) {
|
|
271
|
+
let currentWord = newSplit2[i];
|
|
272
|
+
let nextWord = newSplit2[i + 1];
|
|
273
|
+
let prevWord = newSplit2[i - 1];
|
|
274
|
+
if (nextWord !== null && TitleCaserUtils.isRegionalAcronymNoDot(currentWord, nextWord, prevWord)) {
|
|
275
|
+
newSplit2[i] = currentWord.toUpperCase();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
let finalWord = newSplit2[newSplit2.length - 1];
|
|
282
|
+
let wordBeforeFinal = newSplit2[newSplit2.length - 2];
|
|
283
|
+
let twoWordsBeforeFinal = newSplit2[newSplit2.length - 3];
|
|
284
|
+
|
|
285
|
+
if (TitleCaserUtils.isRegionalAcronym(firstWord)) {
|
|
286
|
+
console.log("firstWord is a regional acronym, proof: ", firstWord);
|
|
287
|
+
newSplit2[0] = firstWord.toUpperCase();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (TitleCaserUtils.isRegionalAcronymNoDot(firstWord, secondWord)) {
|
|
291
|
+
newSplit2[0] = firstWord.toUpperCase();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (TitleCaserUtils.isFinalWordRegionalAcronym(finalWord, wordBeforeFinal, twoWordsBeforeFinal)) {
|
|
295
|
+
newSplit2[newSplit2.length - 1] = finalWord.toUpperCase();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
inputString = newSplit2.join(" ");
|
|
299
|
+
|
|
300
|
+
for (const [phrase, replacement] of Object.entries(this.correctPhraseCasingList)) {
|
|
301
|
+
// Create a regular expression for case-insensitive matching of the phrase
|
|
302
|
+
const regex = new RegExp(phrase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
|
|
303
|
+
|
|
304
|
+
// Replace the phrase in the input string with its corresponding replacement
|
|
305
|
+
inputString = inputString.replace(regex, replacement);
|
|
306
|
+
}
|
|
307
|
+
|
|
242
308
|
return inputString;
|
|
309
|
+
|
|
243
310
|
} catch (error) {
|
|
244
311
|
throw new Error(error);
|
|
245
312
|
}
|
|
@@ -249,7 +316,7 @@ export class TitleCaser {
|
|
|
249
316
|
if (!Array.isArray(terms)) {
|
|
250
317
|
throw new TypeError("Invalid argument: setReplaceTerms must be an array of objects.");
|
|
251
318
|
}
|
|
252
|
-
// Iterate over each term-replacement object in the array
|
|
319
|
+
// ! Iterate over each term-replacement object in the array
|
|
253
320
|
terms.forEach((termObject) => {
|
|
254
321
|
if (termObject && typeof termObject === "object") {
|
|
255
322
|
const [term, replacement] = Object.entries(termObject)[0];
|
|
@@ -296,7 +363,7 @@ export class TitleCaser {
|
|
|
296
363
|
// Find the index of the term in the wordReplacementsList array
|
|
297
364
|
const index = this.wordReplacementsList.findIndex((obj) => Object.keys(obj)[0] === term);
|
|
298
365
|
|
|
299
|
-
// If the term is not found in the array, throw an error
|
|
366
|
+
// ! If the term is not found in the array, throw an error
|
|
300
367
|
if (index === -1) {
|
|
301
368
|
throw new Error(`Term '${term}' not found in word replacements list.`);
|
|
302
369
|
}
|
|
@@ -316,7 +383,7 @@ export class TitleCaser {
|
|
|
316
383
|
}
|
|
317
384
|
|
|
318
385
|
newPhrases.forEach((item) => {
|
|
319
|
-
// If the item is an object with a single key-value pair
|
|
386
|
+
// ! If the item is an object with a single key-value pair
|
|
320
387
|
if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 1) {
|
|
321
388
|
const key = Object.keys(item)[0];
|
|
322
389
|
const value = item[key];
|
|
@@ -326,7 +393,7 @@ export class TitleCaser {
|
|
|
326
393
|
throw new TypeError("Invalid argument: Each key-value pair must contain strings.");
|
|
327
394
|
}
|
|
328
395
|
}
|
|
329
|
-
// If the item is already a key-value pair
|
|
396
|
+
// ! If the item is already a key-value pair
|
|
330
397
|
else if (typeof item === "object" && !Array.isArray(item)) {
|
|
331
398
|
Object.entries(item).forEach(([key, value]) => {
|
|
332
399
|
if (typeof key === "string" && typeof value === "string") {
|
|
@@ -336,7 +403,7 @@ export class TitleCaser {
|
|
|
336
403
|
}
|
|
337
404
|
});
|
|
338
405
|
}
|
|
339
|
-
// Invalid format
|
|
406
|
+
// ! Invalid format
|
|
340
407
|
else {
|
|
341
408
|
throw new TypeError("Invalid argument: Each item must be an object with a single key-value pair.");
|
|
342
409
|
}
|