├── .npmignore ├── LICENSE.txt ├── README.md ├── package.json └── src ├── index.js └── tlds.js /.npmignore: -------------------------------------------------------------------------------- 1 | /* 2 | !/src 3 | !/LICENSE.txt 4 | !/README.md 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Casey Foster 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2 | 3 | A React component for formatting line breaks and links. 4 | 5 | ```jsx 6 | 7 | Email me (foo@example.com) or visit one of: 8 | 9 | foo.example.com 10 | bar.example.com 11 | baz.example.com 12 | 13 | ``` 14 | 15 | ```html 16 | Email me (foo@example.com) or visit one of:
17 |
18 | foo.example.com
19 | bar.example.com
20 | baz.example.com 21 | ``` 22 | 23 | ### Props 24 | 25 | #### LinkComponent 26 | 27 | A component that receives `children` and `href` props. Defaults to `'a'`. 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "formatted-text", 3 | "version": "0.6.16", 4 | "type": "module", 5 | "main": "src/index.js", 6 | "module": "src/index.js", 7 | "sideEffects": false, 8 | "license": "MIT", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/caseywebdev/formatted-text" 12 | }, 13 | "peerDependencies": { 14 | "react": "17 || 18" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { Fragment, createElement } from 'react'; 2 | 3 | import tlds from './tlds.js'; 4 | 5 | const local = "[\\w!#$%&'*+/=?^{|}~-]+"; 6 | const domain = '(?:[a-z0-9]([a-z0-9-]*[a-z0-9])?)'; 7 | 8 | const linkRegexp = new RegExp( 9 | // local email part or scheme 10 | `(${local}(?:\\.${local})*@|https?://)?` + 11 | // domain 12 | `(?:${domain}\\.)+(?:${tlds.join('|')})` + 13 | // path 14 | `(?:/[!-~]*)?`, 15 | 'gi' 16 | ); 17 | 18 | const headerRegexp = /^(#+)[^#\r\n].*$/gm; 19 | 20 | const atMentionRegexp = /@[^@\r\n]+/g; 21 | 22 | const comparator = (a, b) => 23 | a.from < b.from ? -1 : a.from > b.from ? 1 : a.to >= b.to ? -1 : 1; 24 | 25 | const getBlocks = ({ context, text, offset = 0, previousBlocks = [] }) => { 26 | const { getAtMentionable, indexMarkers } = context ?? {}; 27 | const offsetText = text.slice(offset); 28 | const blocks = [ 29 | ...previousBlocks, 30 | 31 | ...(offset === 0 32 | ? (indexMarkers ?? []).map(({ index, ref }) => ({ 33 | type: 'indexMarker', 34 | from: index, 35 | to: index, 36 | props: { ref } 37 | })) 38 | : []), 39 | 40 | ...[...offsetText.matchAll(headerRegexp)].map( 41 | ({ 0: { length }, 1: { length: level }, index }) => ({ 42 | type: 'header', 43 | from: offset + index, 44 | to: offset + index + length, 45 | props: { level } 46 | }) 47 | ), 48 | 49 | ...[...offsetText.matchAll(linkRegexp)].flatMap( 50 | ({ 0: all, 1: prefix, index }) => ({ 51 | type: 'link', 52 | from: offset + index, 53 | to: offset + index + all.length, 54 | props: { 55 | href: !prefix 56 | ? `https://${all}` 57 | : prefix.endsWith('@') 58 | ? `mailto:${all}` 59 | : all 60 | } 61 | }) 62 | ), 63 | 64 | ...(getAtMentionable 65 | ? [...offsetText.matchAll(atMentionRegexp)].flatMap( 66 | ({ 0: all, index }) => { 67 | const mentionable = getAtMentionable(all.slice(1)); 68 | return mentionable 69 | ? { 70 | type: 'atMention', 71 | from: offset + index, 72 | to: offset + index + 1 + mentionable.length, 73 | props: { mentionable } 74 | } 75 | : []; 76 | } 77 | ) 78 | : []) 79 | ].sort(comparator); 80 | 81 | for (let i = 0; i < blocks.length - 1; ++i) { 82 | const blockA = blocks[i]; 83 | for (let j = i + 1; j < blocks.length; ++j) { 84 | const blockB = blocks[j]; 85 | if (blockB.from >= blockA.to) break; 86 | 87 | if (blockB.to > blockA.to) { 88 | return getBlocks({ 89 | context, 90 | offset: blockA.to, 91 | previousBlocks: blocks.slice(0, i + 1), 92 | text 93 | }); 94 | } 95 | } 96 | } 97 | 98 | return blocks; 99 | }; 100 | 101 | // eslint-disable-next-line no-unused-vars 102 | const fallbackRender = ({ children, context, type, ...props }) => { 103 | if (type === 'link') return createElement('a', props, children); 104 | 105 | if (type === 'header') { 106 | if (typeof children[0] !== 'string') return children; 107 | 108 | children = [children[0].replace(/^#*\s*/, ''), ...children.slice(1)]; 109 | return createElement(`h${Math.min(props.level, 6)}`, null, children); 110 | } 111 | 112 | if (type === 'indexMarker') return createElement('span', props); 113 | 114 | return children; 115 | }; 116 | 117 | const renderBlocks = ({ blocks, context, render, text }) => { 118 | if (!blocks.length) return [text]; 119 | 120 | const components = []; 121 | const before = text.slice(0, blocks[0].from); 122 | if (before) components.push(before); 123 | for (let i = 0; i < blocks.length; ++i) { 124 | const { from, to, type, props } = blocks[i]; 125 | const subtext = text.slice(from, to); 126 | const subBlocks = []; 127 | for (let j = i + 1; j < blocks.length; ++j) { 128 | const subBlock = blocks[j]; 129 | if (subBlock.to > to) break; 130 | 131 | subBlocks.push({ 132 | ...subBlock, 133 | from: subBlock.from - from, 134 | to: subBlock.to - from 135 | }); 136 | ++i; 137 | } 138 | const children = renderBlocks({ 139 | blocks: subBlocks, 140 | context, 141 | render, 142 | text: subtext 143 | }); 144 | const renderArgs = { children, context, type, ...props }; 145 | let rendered = render?.(renderArgs); 146 | if (rendered === undefined) rendered = fallbackRender(renderArgs); 147 | components.push(createElement(Fragment, { key: i }, rendered)); 148 | 149 | const after = text.slice(to, blocks[i + 1]?.from); 150 | if (after) components.push(after); 151 | } 152 | 153 | return components; 154 | }; 155 | 156 | export default ({ children: text, context, render }) => 157 | typeof text === 'string' 158 | ? renderBlocks({ 159 | blocks: getBlocks({ context, text }), 160 | context, 161 | render, 162 | text 163 | }) 164 | : null; 165 | -------------------------------------------------------------------------------- /src/tlds.js: -------------------------------------------------------------------------------- 1 | // https://data.iana.org/TLD/tlds-alpha-by-domain.txt 2 | export default [ 3 | 'aaa', 4 | 'aarp', 5 | 'abb', 6 | 'abbott', 7 | 'abbvie', 8 | 'abc', 9 | 'able', 10 | 'abogado', 11 | 'abudhabi', 12 | 'ac', 13 | 'academy', 14 | 'accenture', 15 | 'accountant', 16 | 'accountants', 17 | 'aco', 18 | 'actor', 19 | 'ad', 20 | 'ads', 21 | 'adult', 22 | 'ae', 23 | 'aeg', 24 | 'aero', 25 | 'aetna', 26 | 'af', 27 | 'afl', 28 | 'africa', 29 | 'ag', 30 | 'agakhan', 31 | 'agency', 32 | 'ai', 33 | 'aig', 34 | 'airbus', 35 | 'airforce', 36 | 'airtel', 37 | 'akdn', 38 | 'al', 39 | 'alibaba', 40 | 'alipay', 41 | 'allfinanz', 42 | 'allstate', 43 | 'ally', 44 | 'alsace', 45 | 'alstom', 46 | 'am', 47 | 'amazon', 48 | 'americanexpress', 49 | 'americanfamily', 50 | 'amex', 51 | 'amfam', 52 | 'amica', 53 | 'amsterdam', 54 | 'analytics', 55 | 'android', 56 | 'anquan', 57 | 'anz', 58 | 'ao', 59 | 'aol', 60 | 'apartments', 61 | 'app', 62 | 'apple', 63 | 'aq', 64 | 'aquarelle', 65 | 'ar', 66 | 'arab', 67 | 'aramco', 68 | 'archi', 69 | 'army', 70 | 'arpa', 71 | 'art', 72 | 'arte', 73 | 'as', 74 | 'asda', 75 | 'asia', 76 | 'associates', 77 | 'at', 78 | 'athleta', 79 | 'attorney', 80 | 'au', 81 | 'auction', 82 | 'audi', 83 | 'audible', 84 | 'audio', 85 | 'auspost', 86 | 'author', 87 | 'auto', 88 | 'autos', 89 | 'avianca', 90 | 'aw', 91 | 'aws', 92 | 'ax', 93 | 'axa', 94 | 'az', 95 | 'azure', 96 | 'ba', 97 | 'baby', 98 | 'baidu', 99 | 'banamex', 100 | 'band', 101 | 'bank', 102 | 'bar', 103 | 'barcelona', 104 | 'barclaycard', 105 | 'barclays', 106 | 'barefoot', 107 | 'bargains', 108 | 'baseball', 109 | 'basketball', 110 | 'bauhaus', 111 | 'bayern', 112 | 'bb', 113 | 'bbc', 114 | 'bbt', 115 | 'bbva', 116 | 'bcg', 117 | 'bcn', 118 | 'bd', 119 | 'be', 120 | 'beats', 121 | 'beauty', 122 | 'beer', 123 | 'bentley', 124 | 'berlin', 125 | 'best', 126 | 'bestbuy', 127 | 'bet', 128 | 'bf', 129 | 'bg', 130 | 'bh', 131 | 'bharti', 132 | 'bi', 133 | 'bible', 134 | 'bid', 135 | 'bike', 136 | 'bing', 137 | 'bingo', 138 | 'bio', 139 | 'biz', 140 | 'bj', 141 | 'black', 142 | 'blackfriday', 143 | 'blockbuster', 144 | 'blog', 145 | 'bloomberg', 146 | 'blue', 147 | 'bm', 148 | 'bms', 149 | 'bmw', 150 | 'bn', 151 | 'bnpparibas', 152 | 'bo', 153 | 'boats', 154 | 'boehringer', 155 | 'bofa', 156 | 'bom', 157 | 'bond', 158 | 'boo', 159 | 'book', 160 | 'booking', 161 | 'bosch', 162 | 'bostik', 163 | 'boston', 164 | 'bot', 165 | 'boutique', 166 | 'box', 167 | 'br', 168 | 'bradesco', 169 | 'bridgestone', 170 | 'broadway', 171 | 'broker', 172 | 'brother', 173 | 'brussels', 174 | 'bs', 175 | 'bt', 176 | 'build', 177 | 'builders', 178 | 'business', 179 | 'buy', 180 | 'buzz', 181 | 'bv', 182 | 'bw', 183 | 'by', 184 | 'bz', 185 | 'bzh', 186 | 'ca', 187 | 'cab', 188 | 'cafe', 189 | 'cal', 190 | 'call', 191 | 'calvinklein', 192 | 'cam', 193 | 'camera', 194 | 'camp', 195 | 'canon', 196 | 'capetown', 197 | 'capital', 198 | 'capitalone', 199 | 'car', 200 | 'caravan', 201 | 'cards', 202 | 'care', 203 | 'career', 204 | 'careers', 205 | 'cars', 206 | 'casa', 207 | 'case', 208 | 'cash', 209 | 'casino', 210 | 'cat', 211 | 'catering', 212 | 'catholic', 213 | 'cba', 214 | 'cbn', 215 | 'cbre', 216 | 'cc', 217 | 'cd', 218 | 'center', 219 | 'ceo', 220 | 'cern', 221 | 'cf', 222 | 'cfa', 223 | 'cfd', 224 | 'cg', 225 | 'ch', 226 | 'chanel', 227 | 'channel', 228 | 'charity', 229 | 'chase', 230 | 'chat', 231 | 'cheap', 232 | 'chintai', 233 | 'christmas', 234 | 'chrome', 235 | 'church', 236 | 'ci', 237 | 'cipriani', 238 | 'circle', 239 | 'cisco', 240 | 'citadel', 241 | 'citi', 242 | 'citic', 243 | 'city', 244 | 'ck', 245 | 'cl', 246 | 'claims', 247 | 'cleaning', 248 | 'click', 249 | 'clinic', 250 | 'clinique', 251 | 'clothing', 252 | 'cloud', 253 | 'club', 254 | 'clubmed', 255 | 'cm', 256 | 'cn', 257 | 'co', 258 | 'coach', 259 | 'codes', 260 | 'coffee', 261 | 'college', 262 | 'cologne', 263 | 'com', 264 | 'commbank', 265 | 'community', 266 | 'company', 267 | 'compare', 268 | 'computer', 269 | 'comsec', 270 | 'condos', 271 | 'construction', 272 | 'consulting', 273 | 'contact', 274 | 'contractors', 275 | 'cooking', 276 | 'cool', 277 | 'coop', 278 | 'corsica', 279 | 'country', 280 | 'coupon', 281 | 'coupons', 282 | 'courses', 283 | 'cpa', 284 | 'cr', 285 | 'credit', 286 | 'creditcard', 287 | 'creditunion', 288 | 'cricket', 289 | 'crown', 290 | 'crs', 291 | 'cruise', 292 | 'cruises', 293 | 'cu', 294 | 'cuisinella', 295 | 'cv', 296 | 'cw', 297 | 'cx', 298 | 'cy', 299 | 'cymru', 300 | 'cyou', 301 | 'cz', 302 | 'dabur', 303 | 'dad', 304 | 'dance', 305 | 'data', 306 | 'date', 307 | 'dating', 308 | 'datsun', 309 | 'day', 310 | 'dclk', 311 | 'dds', 312 | 'de', 313 | 'deal', 314 | 'dealer', 315 | 'deals', 316 | 'degree', 317 | 'delivery', 318 | 'dell', 319 | 'deloitte', 320 | 'delta', 321 | 'democrat', 322 | 'dental', 323 | 'dentist', 324 | 'desi', 325 | 'design', 326 | 'dev', 327 | 'dhl', 328 | 'diamonds', 329 | 'diet', 330 | 'digital', 331 | 'direct', 332 | 'directory', 333 | 'discount', 334 | 'discover', 335 | 'dish', 336 | 'diy', 337 | 'dj', 338 | 'dk', 339 | 'dm', 340 | 'dnp', 341 | 'do', 342 | 'docs', 343 | 'doctor', 344 | 'dog', 345 | 'domains', 346 | 'dot', 347 | 'download', 348 | 'drive', 349 | 'dtv', 350 | 'dubai', 351 | 'dunlop', 352 | 'dupont', 353 | 'durban', 354 | 'dvag', 355 | 'dvr', 356 | 'dz', 357 | 'earth', 358 | 'eat', 359 | 'ec', 360 | 'eco', 361 | 'edeka', 362 | 'edu', 363 | 'education', 364 | 'ee', 365 | 'eg', 366 | 'email', 367 | 'emerck', 368 | 'energy', 369 | 'engineer', 370 | 'engineering', 371 | 'enterprises', 372 | 'epson', 373 | 'equipment', 374 | 'er', 375 | 'ericsson', 376 | 'erni', 377 | 'es', 378 | 'esq', 379 | 'estate', 380 | 'et', 381 | 'eu', 382 | 'eurovision', 383 | 'eus', 384 | 'events', 385 | 'exchange', 386 | 'expert', 387 | 'exposed', 388 | 'express', 389 | 'extraspace', 390 | 'fage', 391 | 'fail', 392 | 'fairwinds', 393 | 'faith', 394 | 'family', 395 | 'fan', 396 | 'fans', 397 | 'farm', 398 | 'farmers', 399 | 'fashion', 400 | 'fast', 401 | 'fedex', 402 | 'feedback', 403 | 'ferrari', 404 | 'ferrero', 405 | 'fi', 406 | 'fidelity', 407 | 'fido', 408 | 'film', 409 | 'final', 410 | 'finance', 411 | 'financial', 412 | 'fire', 413 | 'firestone', 414 | 'firmdale', 415 | 'fish', 416 | 'fishing', 417 | 'fit', 418 | 'fitness', 419 | 'fj', 420 | 'fk', 421 | 'flickr', 422 | 'flights', 423 | 'flir', 424 | 'florist', 425 | 'flowers', 426 | 'fly', 427 | 'fm', 428 | 'fo', 429 | 'foo', 430 | 'food', 431 | 'football', 432 | 'ford', 433 | 'forex', 434 | 'forsale', 435 | 'forum', 436 | 'foundation', 437 | 'fox', 438 | 'fr', 439 | 'free', 440 | 'fresenius', 441 | 'frl', 442 | 'frogans', 443 | 'frontier', 444 | 'ftr', 445 | 'fujitsu', 446 | 'fun', 447 | 'fund', 448 | 'furniture', 449 | 'futbol', 450 | 'fyi', 451 | 'ga', 452 | 'gal', 453 | 'gallery', 454 | 'gallo', 455 | 'gallup', 456 | 'game', 457 | 'games', 458 | 'gap', 459 | 'garden', 460 | 'gay', 461 | 'gb', 462 | 'gbiz', 463 | 'gd', 464 | 'gdn', 465 | 'ge', 466 | 'gea', 467 | 'gent', 468 | 'genting', 469 | 'george', 470 | 'gf', 471 | 'gg', 472 | 'ggee', 473 | 'gh', 474 | 'gi', 475 | 'gift', 476 | 'gifts', 477 | 'gives', 478 | 'giving', 479 | 'gl', 480 | 'glass', 481 | 'gle', 482 | 'global', 483 | 'globo', 484 | 'gm', 485 | 'gmail', 486 | 'gmbh', 487 | 'gmo', 488 | 'gmx', 489 | 'gn', 490 | 'godaddy', 491 | 'gold', 492 | 'goldpoint', 493 | 'golf', 494 | 'goo', 495 | 'goodyear', 496 | 'goog', 497 | 'google', 498 | 'gop', 499 | 'got', 500 | 'gov', 501 | 'gp', 502 | 'gq', 503 | 'gr', 504 | 'grainger', 505 | 'graphics', 506 | 'gratis', 507 | 'green', 508 | 'gripe', 509 | 'grocery', 510 | 'group', 511 | 'gs', 512 | 'gt', 513 | 'gu', 514 | 'gucci', 515 | 'guge', 516 | 'guide', 517 | 'guitars', 518 | 'guru', 519 | 'gw', 520 | 'gy', 521 | 'hair', 522 | 'hamburg', 523 | 'hangout', 524 | 'haus', 525 | 'hbo', 526 | 'hdfc', 527 | 'hdfcbank', 528 | 'health', 529 | 'healthcare', 530 | 'help', 531 | 'helsinki', 532 | 'here', 533 | 'hermes', 534 | 'hiphop', 535 | 'hisamitsu', 536 | 'hitachi', 537 | 'hiv', 538 | 'hk', 539 | 'hkt', 540 | 'hm', 541 | 'hn', 542 | 'hockey', 543 | 'holdings', 544 | 'holiday', 545 | 'homedepot', 546 | 'homegoods', 547 | 'homes', 548 | 'homesense', 549 | 'honda', 550 | 'horse', 551 | 'hospital', 552 | 'host', 553 | 'hosting', 554 | 'hot', 555 | 'hotels', 556 | 'hotmail', 557 | 'house', 558 | 'how', 559 | 'hr', 560 | 'hsbc', 561 | 'ht', 562 | 'hu', 563 | 'hughes', 564 | 'hyatt', 565 | 'hyundai', 566 | 'ibm', 567 | 'icbc', 568 | 'ice', 569 | 'icu', 570 | 'id', 571 | 'ie', 572 | 'ieee', 573 | 'ifm', 574 | 'ikano', 575 | 'il', 576 | 'im', 577 | 'imamat', 578 | 'imdb', 579 | 'immo', 580 | 'immobilien', 581 | 'in', 582 | 'inc', 583 | 'industries', 584 | 'infiniti', 585 | 'info', 586 | 'ing', 587 | 'ink', 588 | 'institute', 589 | 'insurance', 590 | 'insure', 591 | 'int', 592 | 'international', 593 | 'intuit', 594 | 'investments', 595 | 'io', 596 | 'ipiranga', 597 | 'iq', 598 | 'ir', 599 | 'irish', 600 | 'is', 601 | 'ismaili', 602 | 'ist', 603 | 'istanbul', 604 | 'it', 605 | 'itau', 606 | 'itv', 607 | 'jaguar', 608 | 'java', 609 | 'jcb', 610 | 'je', 611 | 'jeep', 612 | 'jetzt', 613 | 'jewelry', 614 | 'jio', 615 | 'jll', 616 | 'jm', 617 | 'jmp', 618 | 'jnj', 619 | 'jo', 620 | 'jobs', 621 | 'joburg', 622 | 'jot', 623 | 'joy', 624 | 'jp', 625 | 'jpmorgan', 626 | 'jprs', 627 | 'juegos', 628 | 'juniper', 629 | 'kaufen', 630 | 'kddi', 631 | 'ke', 632 | 'kerryhotels', 633 | 'kerrylogistics', 634 | 'kerryproperties', 635 | 'kfh', 636 | 'kg', 637 | 'kh', 638 | 'ki', 639 | 'kia', 640 | 'kids', 641 | 'kim', 642 | 'kindle', 643 | 'kitchen', 644 | 'kiwi', 645 | 'km', 646 | 'kn', 647 | 'koeln', 648 | 'komatsu', 649 | 'kosher', 650 | 'kp', 651 | 'kpmg', 652 | 'kpn', 653 | 'kr', 654 | 'krd', 655 | 'kred', 656 | 'kuokgroup', 657 | 'kw', 658 | 'ky', 659 | 'kyoto', 660 | 'kz', 661 | 'la', 662 | 'lacaixa', 663 | 'lamborghini', 664 | 'lamer', 665 | 'lancaster', 666 | 'land', 667 | 'landrover', 668 | 'lanxess', 669 | 'lasalle', 670 | 'lat', 671 | 'latino', 672 | 'latrobe', 673 | 'law', 674 | 'lawyer', 675 | 'lb', 676 | 'lc', 677 | 'lds', 678 | 'lease', 679 | 'leclerc', 680 | 'lefrak', 681 | 'legal', 682 | 'lego', 683 | 'lexus', 684 | 'lgbt', 685 | 'li', 686 | 'lidl', 687 | 'life', 688 | 'lifeinsurance', 689 | 'lifestyle', 690 | 'lighting', 691 | 'like', 692 | 'lilly', 693 | 'limited', 694 | 'limo', 695 | 'lincoln', 696 | 'link', 697 | 'lipsy', 698 | 'live', 699 | 'living', 700 | 'lk', 701 | 'llc', 702 | 'llp', 703 | 'loan', 704 | 'loans', 705 | 'locker', 706 | 'locus', 707 | 'lol', 708 | 'london', 709 | 'lotte', 710 | 'lotto', 711 | 'love', 712 | 'lpl', 713 | 'lplfinancial', 714 | 'lr', 715 | 'ls', 716 | 'lt', 717 | 'ltd', 718 | 'ltda', 719 | 'lu', 720 | 'lundbeck', 721 | 'luxe', 722 | 'luxury', 723 | 'lv', 724 | 'ly', 725 | 'ma', 726 | 'madrid', 727 | 'maif', 728 | 'maison', 729 | 'makeup', 730 | 'man', 731 | 'management', 732 | 'mango', 733 | 'map', 734 | 'market', 735 | 'marketing', 736 | 'markets', 737 | 'marriott', 738 | 'marshalls', 739 | 'mattel', 740 | 'mba', 741 | 'mc', 742 | 'mckinsey', 743 | 'md', 744 | 'me', 745 | 'med', 746 | 'media', 747 | 'meet', 748 | 'melbourne', 749 | 'meme', 750 | 'memorial', 751 | 'men', 752 | 'menu', 753 | 'merckmsd', 754 | 'mg', 755 | 'mh', 756 | 'miami', 757 | 'microsoft', 758 | 'mil', 759 | 'mini', 760 | 'mint', 761 | 'mit', 762 | 'mitsubishi', 763 | 'mk', 764 | 'ml', 765 | 'mlb', 766 | 'mls', 767 | 'mm', 768 | 'mma', 769 | 'mn', 770 | 'mo', 771 | 'mobi', 772 | 'mobile', 773 | 'moda', 774 | 'moe', 775 | 'moi', 776 | 'mom', 777 | 'monash', 778 | 'money', 779 | 'monster', 780 | 'mormon', 781 | 'mortgage', 782 | 'moscow', 783 | 'moto', 784 | 'motorcycles', 785 | 'mov', 786 | 'movie', 787 | 'mp', 788 | 'mq', 789 | 'mr', 790 | 'ms', 791 | 'msd', 792 | 'mt', 793 | 'mtn', 794 | 'mtr', 795 | 'mu', 796 | 'museum', 797 | 'music', 798 | 'mv', 799 | 'mw', 800 | 'mx', 801 | 'my', 802 | 'mz', 803 | 'na', 804 | 'nab', 805 | 'nagoya', 806 | 'name', 807 | 'natura', 808 | 'navy', 809 | 'nba', 810 | 'nc', 811 | 'ne', 812 | 'nec', 813 | 'net', 814 | 'netbank', 815 | 'netflix', 816 | 'network', 817 | 'neustar', 818 | 'new', 819 | 'news', 820 | 'next', 821 | 'nextdirect', 822 | 'nexus', 823 | 'nf', 824 | 'nfl', 825 | 'ng', 826 | 'ngo', 827 | 'nhk', 828 | 'ni', 829 | 'nico', 830 | 'nike', 831 | 'nikon', 832 | 'ninja', 833 | 'nissan', 834 | 'nissay', 835 | 'nl', 836 | 'no', 837 | 'nokia', 838 | 'norton', 839 | 'now', 840 | 'nowruz', 841 | 'nowtv', 842 | 'np', 843 | 'nr', 844 | 'nra', 845 | 'nrw', 846 | 'ntt', 847 | 'nu', 848 | 'nyc', 849 | 'nz', 850 | 'obi', 851 | 'observer', 852 | 'office', 853 | 'okinawa', 854 | 'olayan', 855 | 'olayangroup', 856 | 'ollo', 857 | 'om', 858 | 'omega', 859 | 'one', 860 | 'ong', 861 | 'onl', 862 | 'online', 863 | 'ooo', 864 | 'open', 865 | 'oracle', 866 | 'orange', 867 | 'org', 868 | 'organic', 869 | 'origins', 870 | 'osaka', 871 | 'otsuka', 872 | 'ott', 873 | 'ovh', 874 | 'pa', 875 | 'page', 876 | 'panasonic', 877 | 'paris', 878 | 'pars', 879 | 'partners', 880 | 'parts', 881 | 'party', 882 | 'pay', 883 | 'pccw', 884 | 'pe', 885 | 'pet', 886 | 'pf', 887 | 'pfizer', 888 | 'pg', 889 | 'ph', 890 | 'pharmacy', 891 | 'phd', 892 | 'philips', 893 | 'phone', 894 | 'photo', 895 | 'photography', 896 | 'photos', 897 | 'physio', 898 | 'pics', 899 | 'pictet', 900 | 'pictures', 901 | 'pid', 902 | 'pin', 903 | 'ping', 904 | 'pink', 905 | 'pioneer', 906 | 'pizza', 907 | 'pk', 908 | 'pl', 909 | 'place', 910 | 'play', 911 | 'playstation', 912 | 'plumbing', 913 | 'plus', 914 | 'pm', 915 | 'pn', 916 | 'pnc', 917 | 'pohl', 918 | 'poker', 919 | 'politie', 920 | 'porn', 921 | 'post', 922 | 'pr', 923 | 'pramerica', 924 | 'praxi', 925 | 'press', 926 | 'prime', 927 | 'pro', 928 | 'prod', 929 | 'productions', 930 | 'prof', 931 | 'progressive', 932 | 'promo', 933 | 'properties', 934 | 'property', 935 | 'protection', 936 | 'pru', 937 | 'prudential', 938 | 'ps', 939 | 'pt', 940 | 'pub', 941 | 'pw', 942 | 'pwc', 943 | 'py', 944 | 'qa', 945 | 'qpon', 946 | 'quebec', 947 | 'quest', 948 | 'racing', 949 | 'radio', 950 | 're', 951 | 'read', 952 | 'realestate', 953 | 'realtor', 954 | 'realty', 955 | 'recipes', 956 | 'red', 957 | 'redstone', 958 | 'redumbrella', 959 | 'rehab', 960 | 'reise', 961 | 'reisen', 962 | 'reit', 963 | 'reliance', 964 | 'ren', 965 | 'rent', 966 | 'rentals', 967 | 'repair', 968 | 'report', 969 | 'republican', 970 | 'rest', 971 | 'restaurant', 972 | 'review', 973 | 'reviews', 974 | 'rexroth', 975 | 'rich', 976 | 'richardli', 977 | 'ricoh', 978 | 'ril', 979 | 'rio', 980 | 'rip', 981 | 'ro', 982 | 'rocks', 983 | 'rodeo', 984 | 'rogers', 985 | 'room', 986 | 'rs', 987 | 'rsvp', 988 | 'ru', 989 | 'rugby', 990 | 'ruhr', 991 | 'run', 992 | 'rw', 993 | 'rwe', 994 | 'ryukyu', 995 | 'sa', 996 | 'saarland', 997 | 'safe', 998 | 'safety', 999 | 'sakura', 1000 | 'sale', 1001 | 'salon', 1002 | 'samsclub', 1003 | 'samsung', 1004 | 'sandvik', 1005 | 'sandvikcoromant', 1006 | 'sanofi', 1007 | 'sap', 1008 | 'sarl', 1009 | 'sas', 1010 | 'save', 1011 | 'saxo', 1012 | 'sb', 1013 | 'sbi', 1014 | 'sbs', 1015 | 'sc', 1016 | 'scb', 1017 | 'schaeffler', 1018 | 'schmidt', 1019 | 'scholarships', 1020 | 'school', 1021 | 'schule', 1022 | 'schwarz', 1023 | 'science', 1024 | 'scot', 1025 | 'sd', 1026 | 'se', 1027 | 'search', 1028 | 'seat', 1029 | 'secure', 1030 | 'security', 1031 | 'seek', 1032 | 'select', 1033 | 'sener', 1034 | 'services', 1035 | 'seven', 1036 | 'sew', 1037 | 'sex', 1038 | 'sexy', 1039 | 'sfr', 1040 | 'sg', 1041 | 'sh', 1042 | 'shangrila', 1043 | 'sharp', 1044 | 'shaw', 1045 | 'shell', 1046 | 'shia', 1047 | 'shiksha', 1048 | 'shoes', 1049 | 'shop', 1050 | 'shopping', 1051 | 'shouji', 1052 | 'show', 1053 | 'si', 1054 | 'silk', 1055 | 'sina', 1056 | 'singles', 1057 | 'site', 1058 | 'sj', 1059 | 'sk', 1060 | 'ski', 1061 | 'skin', 1062 | 'sky', 1063 | 'skype', 1064 | 'sl', 1065 | 'sling', 1066 | 'sm', 1067 | 'smart', 1068 | 'smile', 1069 | 'sn', 1070 | 'sncf', 1071 | 'so', 1072 | 'soccer', 1073 | 'social', 1074 | 'softbank', 1075 | 'software', 1076 | 'sohu', 1077 | 'solar', 1078 | 'solutions', 1079 | 'song', 1080 | 'sony', 1081 | 'soy', 1082 | 'spa', 1083 | 'space', 1084 | 'sport', 1085 | 'spot', 1086 | 'sr', 1087 | 'srl', 1088 | 'ss', 1089 | 'st', 1090 | 'stada', 1091 | 'staples', 1092 | 'star', 1093 | 'statebank', 1094 | 'statefarm', 1095 | 'stc', 1096 | 'stcgroup', 1097 | 'stockholm', 1098 | 'storage', 1099 | 'store', 1100 | 'stream', 1101 | 'studio', 1102 | 'study', 1103 | 'style', 1104 | 'su', 1105 | 'sucks', 1106 | 'supplies', 1107 | 'supply', 1108 | 'support', 1109 | 'surf', 1110 | 'surgery', 1111 | 'suzuki', 1112 | 'sv', 1113 | 'swatch', 1114 | 'swiss', 1115 | 'sx', 1116 | 'sy', 1117 | 'sydney', 1118 | 'systems', 1119 | 'sz', 1120 | 'tab', 1121 | 'taipei', 1122 | 'talk', 1123 | 'taobao', 1124 | 'target', 1125 | 'tatamotors', 1126 | 'tatar', 1127 | 'tattoo', 1128 | 'tax', 1129 | 'taxi', 1130 | 'tc', 1131 | 'tci', 1132 | 'td', 1133 | 'tdk', 1134 | 'team', 1135 | 'tech', 1136 | 'technology', 1137 | 'tel', 1138 | 'temasek', 1139 | 'tennis', 1140 | 'teva', 1141 | 'tf', 1142 | 'tg', 1143 | 'th', 1144 | 'thd', 1145 | 'theater', 1146 | 'theatre', 1147 | 'tiaa', 1148 | 'tickets', 1149 | 'tienda', 1150 | 'tips', 1151 | 'tires', 1152 | 'tirol', 1153 | 'tj', 1154 | 'tjmaxx', 1155 | 'tjx', 1156 | 'tk', 1157 | 'tkmaxx', 1158 | 'tl', 1159 | 'tm', 1160 | 'tmall', 1161 | 'tn', 1162 | 'to', 1163 | 'today', 1164 | 'tokyo', 1165 | 'tools', 1166 | 'top', 1167 | 'toray', 1168 | 'toshiba', 1169 | 'total', 1170 | 'tours', 1171 | 'town', 1172 | 'toyota', 1173 | 'toys', 1174 | 'tr', 1175 | 'trade', 1176 | 'trading', 1177 | 'training', 1178 | 'travel', 1179 | 'travelers', 1180 | 'travelersinsurance', 1181 | 'trust', 1182 | 'trv', 1183 | 'tt', 1184 | 'tube', 1185 | 'tui', 1186 | 'tunes', 1187 | 'tushu', 1188 | 'tv', 1189 | 'tvs', 1190 | 'tw', 1191 | 'tz', 1192 | 'ua', 1193 | 'ubank', 1194 | 'ubs', 1195 | 'ug', 1196 | 'uk', 1197 | 'unicom', 1198 | 'university', 1199 | 'uno', 1200 | 'uol', 1201 | 'ups', 1202 | 'us', 1203 | 'uy', 1204 | 'uz', 1205 | 'va', 1206 | 'vacations', 1207 | 'vana', 1208 | 'vanguard', 1209 | 'vc', 1210 | 've', 1211 | 'vegas', 1212 | 'ventures', 1213 | 'verisign', 1214 | 'versicherung', 1215 | 'vet', 1216 | 'vg', 1217 | 'vi', 1218 | 'viajes', 1219 | 'video', 1220 | 'vig', 1221 | 'viking', 1222 | 'villas', 1223 | 'vin', 1224 | 'vip', 1225 | 'virgin', 1226 | 'visa', 1227 | 'vision', 1228 | 'viva', 1229 | 'vivo', 1230 | 'vlaanderen', 1231 | 'vn', 1232 | 'vodka', 1233 | 'volvo', 1234 | 'vote', 1235 | 'voting', 1236 | 'voto', 1237 | 'voyage', 1238 | 'vu', 1239 | 'wales', 1240 | 'walmart', 1241 | 'walter', 1242 | 'wang', 1243 | 'wanggou', 1244 | 'watch', 1245 | 'watches', 1246 | 'weather', 1247 | 'weatherchannel', 1248 | 'webcam', 1249 | 'weber', 1250 | 'website', 1251 | 'wed', 1252 | 'wedding', 1253 | 'weibo', 1254 | 'weir', 1255 | 'wf', 1256 | 'whoswho', 1257 | 'wien', 1258 | 'wiki', 1259 | 'williamhill', 1260 | 'win', 1261 | 'windows', 1262 | 'wine', 1263 | 'winners', 1264 | 'wme', 1265 | 'wolterskluwer', 1266 | 'woodside', 1267 | 'work', 1268 | 'works', 1269 | 'world', 1270 | 'wow', 1271 | 'ws', 1272 | 'wtc', 1273 | 'wtf', 1274 | 'xbox', 1275 | 'xerox', 1276 | 'xihuan', 1277 | 'xin', 1278 | 'xn--11b4c3d', 1279 | 'xn--1ck2e1b', 1280 | 'xn--1qqw23a', 1281 | 'xn--2scrj9c', 1282 | 'xn--30rr7y', 1283 | 'xn--3bst00m', 1284 | 'xn--3ds443g', 1285 | 'xn--3e0b707e', 1286 | 'xn--3hcrj9c', 1287 | 'xn--3pxu8k', 1288 | 'xn--42c2d9a', 1289 | 'xn--45br5cyl', 1290 | 'xn--45brj9c', 1291 | 'xn--45q11c', 1292 | 'xn--4dbrk0ce', 1293 | 'xn--4gbrim', 1294 | 'xn--54b7fta0cc', 1295 | 'xn--55qw42g', 1296 | 'xn--55qx5d', 1297 | 'xn--5su34j936bgsg', 1298 | 'xn--5tzm5g', 1299 | 'xn--6frz82g', 1300 | 'xn--6qq986b3xl', 1301 | 'xn--80adxhks', 1302 | 'xn--80ao21a', 1303 | 'xn--80aqecdr1a', 1304 | 'xn--80asehdb', 1305 | 'xn--80aswg', 1306 | 'xn--8y0a063a', 1307 | 'xn--90a3ac', 1308 | 'xn--90ae', 1309 | 'xn--90ais', 1310 | 'xn--9dbq2a', 1311 | 'xn--9et52u', 1312 | 'xn--9krt00a', 1313 | 'xn--b4w605ferd', 1314 | 'xn--bck1b9a5dre4c', 1315 | 'xn--c1avg', 1316 | 'xn--c2br7g', 1317 | 'xn--cck2b3b', 1318 | 'xn--cckwcxetd', 1319 | 'xn--cg4bki', 1320 | 'xn--clchc0ea0b2g2a9gcd', 1321 | 'xn--czr694b', 1322 | 'xn--czrs0t', 1323 | 'xn--czru2d', 1324 | 'xn--d1acj3b', 1325 | 'xn--d1alf', 1326 | 'xn--e1a4c', 1327 | 'xn--eckvdtc9d', 1328 | 'xn--efvy88h', 1329 | 'xn--fct429k', 1330 | 'xn--fhbei', 1331 | 'xn--fiq228c5hs', 1332 | 'xn--fiq64b', 1333 | 'xn--fiqs8s', 1334 | 'xn--fiqz9s', 1335 | 'xn--fjq720a', 1336 | 'xn--flw351e', 1337 | 'xn--fpcrj9c3d', 1338 | 'xn--fzc2c9e2c', 1339 | 'xn--fzys8d69uvgm', 1340 | 'xn--g2xx48c', 1341 | 'xn--gckr3f0f', 1342 | 'xn--gecrj9c', 1343 | 'xn--gk3at1e', 1344 | 'xn--h2breg3eve', 1345 | 'xn--h2brj9c', 1346 | 'xn--h2brj9c8c', 1347 | 'xn--hxt814e', 1348 | 'xn--i1b6b1a6a2e', 1349 | 'xn--imr513n', 1350 | 'xn--io0a7i', 1351 | 'xn--j1aef', 1352 | 'xn--j1amh', 1353 | 'xn--j6w193g', 1354 | 'xn--jlq480n2rg', 1355 | 'xn--jvr189m', 1356 | 'xn--kcrx77d1x4a', 1357 | 'xn--kprw13d', 1358 | 'xn--kpry57d', 1359 | 'xn--kput3i', 1360 | 'xn--l1acc', 1361 | 'xn--lgbbat1ad8j', 1362 | 'xn--mgb9awbf', 1363 | 'xn--mgba3a3ejt', 1364 | 'xn--mgba3a4f16a', 1365 | 'xn--mgba7c0bbn0a', 1366 | 'xn--mgbaam7a8h', 1367 | 'xn--mgbab2bd', 1368 | 'xn--mgbah1a3hjkrd', 1369 | 'xn--mgbai9azgqp6j', 1370 | 'xn--mgbayh7gpa', 1371 | 'xn--mgbbh1a', 1372 | 'xn--mgbbh1a71e', 1373 | 'xn--mgbc0a9azcg', 1374 | 'xn--mgbca7dzdo', 1375 | 'xn--mgbcpq6gpa1a', 1376 | 'xn--mgberp4a5d4ar', 1377 | 'xn--mgbgu82a', 1378 | 'xn--mgbi4ecexp', 1379 | 'xn--mgbpl2fh', 1380 | 'xn--mgbt3dhd', 1381 | 'xn--mgbtx2b', 1382 | 'xn--mgbx4cd0ab', 1383 | 'xn--mix891f', 1384 | 'xn--mk1bu44c', 1385 | 'xn--mxtq1m', 1386 | 'xn--ngbc5azd', 1387 | 'xn--ngbe9e0a', 1388 | 'xn--ngbrx', 1389 | 'xn--node', 1390 | 'xn--nqv7f', 1391 | 'xn--nqv7fs00ema', 1392 | 'xn--nyqy26a', 1393 | 'xn--o3cw4h', 1394 | 'xn--ogbpf8fl', 1395 | 'xn--otu796d', 1396 | 'xn--p1acf', 1397 | 'xn--p1ai', 1398 | 'xn--pgbs0dh', 1399 | 'xn--pssy2u', 1400 | 'xn--q7ce6a', 1401 | 'xn--q9jyb4c', 1402 | 'xn--qcka1pmc', 1403 | 'xn--qxa6a', 1404 | 'xn--qxam', 1405 | 'xn--rhqv96g', 1406 | 'xn--rovu88b', 1407 | 'xn--rvc1e0am3e', 1408 | 'xn--s9brj9c', 1409 | 'xn--ses554g', 1410 | 'xn--t60b56a', 1411 | 'xn--tckwe', 1412 | 'xn--tiq49xqyj', 1413 | 'xn--unup4y', 1414 | 'xn--vermgensberater-ctb', 1415 | 'xn--vermgensberatung-pwb', 1416 | 'xn--vhquv', 1417 | 'xn--vuq861b', 1418 | 'xn--w4r85el8fhu5dnra', 1419 | 'xn--w4rs40l', 1420 | 'xn--wgbh1c', 1421 | 'xn--wgbl6a', 1422 | 'xn--xhq521b', 1423 | 'xn--xkc2al3hye2a', 1424 | 'xn--xkc2dl3a5ee0h', 1425 | 'xn--y9a3aq', 1426 | 'xn--yfro4i67o', 1427 | 'xn--ygbi2ammx', 1428 | 'xn--zfr164b', 1429 | 'xxx', 1430 | 'xyz', 1431 | 'yachts', 1432 | 'yahoo', 1433 | 'yamaxun', 1434 | 'yandex', 1435 | 'ye', 1436 | 'yodobashi', 1437 | 'yoga', 1438 | 'yokohama', 1439 | 'you', 1440 | 'youtube', 1441 | 'yt', 1442 | 'yun', 1443 | 'za', 1444 | 'zappos', 1445 | 'zara', 1446 | 'zero', 1447 | 'zip', 1448 | 'zm', 1449 | 'zone', 1450 | 'zuerich', 1451 | 'zw' 1452 | ].sort((a, b) => b.length - a.length); 1453 | --------------------------------------------------------------------------------